diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index af0ee8771e7..7e4234bd106 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -1,151 +1,424 @@ -// 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.agent.api.to; - - -import java.util.List; -import com.cloud.utils.Pair; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; - - -public class LoadBalancerTO { - String srcIp; - int srcPort; - String protocol; - 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) { - this.srcIp = srcIp; - this.srcPort = srcPort; - this.protocol = protocol; - this.algorithm = algorithm; - this.revoked = revoked; - this.alreadyAdded = alreadyAdded; - this.destinations = new DestinationTO[destinations.size()]; - this.stickinessPolicies = null; - int i = 0; - for (LbDestination destination : destinations) { - 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); - this.stickinessPolicies = null; - if (stickinessPolicies != null && stickinessPolicies.size()>0) { - this.stickinessPolicies = new StickinessPolicyTO[MAX_STICKINESS_POLICIES]; - int index = 0; - for (LbStickinessPolicy stickinesspolicy : stickinessPolicies) { - if (!stickinesspolicy.isRevoked()) { - this.stickinessPolicies[index] = new StickinessPolicyTO(stickinesspolicy.getMethodName(), stickinesspolicy.getParams()); - index++; - if (index == MAX_STICKINESS_POLICIES) break; - } - } - if (index == 0) this.stickinessPolicies = null; - } - } - - - protected LoadBalancerTO() { - } - - public String getSrcIp() { - return srcIp; - } - - public int getSrcPort() { - return srcPort; - } - - public String getAlgorithm() { - return algorithm; - } - - public String getProtocol() { - return protocol; - } - - public boolean isRevoked() { - return revoked; - } - - public boolean isAlreadyAdded() { - return alreadyAdded; - } - - public StickinessPolicyTO[] getStickinessPolicies() { - return stickinessPolicies; - } - - public DestinationTO[] getDestinations() { - return destinations; - } - - public static class StickinessPolicyTO { - private String _methodName; - private List> _paramsList; - - public String getMethodName() { - return _methodName; - } - - public List> getParams() { - return _paramsList; - } - - public StickinessPolicyTO(String methodName, List> paramsList) { - this._methodName = methodName; - this._paramsList = paramsList; - } - } - - public static class DestinationTO { - String destIp; - int destPort; - boolean revoked; - boolean alreadyAdded; - public DestinationTO(String destIp, int destPort, boolean revoked, boolean alreadyAdded) { - this.destIp = destIp; - this.destPort = destPort; - this.revoked = revoked; - this.alreadyAdded = alreadyAdded; - } - - protected DestinationTO() { - } - - public String getDestIp() { - return destIp; - } - - public int getDestPort() { - return destPort; - } - - public boolean isRevoked() { - return revoked; - } - - public boolean isAlreadyAdded() { - return alreadyAdded; - } - } - -} +// 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.agent.api.to; + + +import java.util.ArrayList; +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.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; + boolean revoked; + boolean alreadyAdded; + DestinationTO[] destinations; + private StickinessPolicyTO[] stickinessPolicies; + 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) { + this.id = id; + this.srcIp = srcIp; + this.srcPort = srcPort; + this.protocol = protocol; + this.algorithm = algorithm; + this.revoked = revoked; + this.alreadyAdded = alreadyAdded; + this.destinations = new DestinationTO[destinations.size()]; + this.stickinessPolicies = null; + int i = 0; + for (LbDestination destination : destinations) { + this.destinations[i++] = new DestinationTO(destination.getIpAddress(), destination.getDestinationPortStart(), destination.isRevoked(), false); + } + } + + 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]; + int index = 0; + for (LbStickinessPolicy stickinesspolicy : stickinessPolicies) { + if (!stickinesspolicy.isRevoked()) { + this.stickinessPolicies[index] = new StickinessPolicyTO(stickinesspolicy.getMethodName(), stickinesspolicy.getParams()); + index++; + if (index == MAX_STICKINESS_POLICIES) { + break; + } + } + } + if (index == 0) { + this.stickinessPolicies = null; + } + } + } + + + protected LoadBalancerTO() { + } + + public Long getId() { + return id; + } + + public String getSrcIp() { + return srcIp; + } + + public int getSrcPort() { + return srcPort; + } + + public String getAlgorithm() { + return algorithm; + } + + public String getProtocol() { + return protocol; + } + + public boolean isRevoked() { + return revoked; + } + + 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 final String _methodName; + private final List> _paramsList; + + public String getMethodName() { + return _methodName; + } + + public List> getParams() { + return _paramsList; + } + + public StickinessPolicyTO(String methodName, List> paramsList) { + this._methodName = methodName; + this._paramsList = paramsList; + } + } + + public static class DestinationTO { + String destIp; + int destPort; + boolean revoked; + boolean alreadyAdded; + public DestinationTO(String destIp, int destPort, boolean revoked, boolean alreadyAdded) { + this.destIp = destIp; + this.destPort = destPort; + this.revoked = revoked; + this.alreadyAdded = alreadyAdded; + } + + protected DestinationTO() { + } + + public String getDestIp() { + return destIp; + } + + public int getDestPort() { + return destPort; + } + + public boolean isRevoked() { + return revoked; + } + + public boolean isAlreadyAdded() { + return alreadyAdded; + } + } + + public static class CounterTO { + 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{ + 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 { + 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 { + 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 { + 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 boolean revoked; + private String state; + + AutoScaleVmGroupTO(int minMembers, int maxMembers, int memberPort, int interval, List policies, AutoScaleVmProfileTO profile, boolean revoked) + { + this.minMembers = minMembers; + this.maxMembers = maxMembers; + this.memberPort = memberPort; + this.interval = interval; + this.policies = policies; + this.profile = profile; + this.revoked = revoked; + } + + 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 boolean isRevoked() { + return revoked; + } + } + + 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.getAutoScaleUserApiKey(), lbAutoScaleVmProfile.getAutoScaleUserSecretKey(), lbAutoScaleVmProfile.getCloudStackApiUrl(), + 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.isRevoke()); + } + +} diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 1f11d49cee7..12336cb988a 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -1,392 +1,415 @@ -// 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.api; - -public class ApiConstants { - public static final String ACCOUNT = "account"; - public static final String ACCOUNTS = "accounts"; - public static final String ACCOUNT_TYPE = "accounttype"; - public static final String ACCOUNT_ID = "accountid"; - public static final String ALGORITHM = "algorithm"; - public static final String ALLOCATED_ONLY = "allocatedonly"; - public static final String API_KEY = "userapikey"; - public static final String APPLIED = "applied"; - public static final String AVAILABLE = "available"; - public static final String BITS = "bits"; - public static final String BOOTABLE = "bootable"; - 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 CIDR = "cidr"; - public static final String CIDR_LIST = "cidrlist"; - public static final String CLEANUP = "cleanup"; - public static final String CLUSTER_ID = "clusterid"; - public static final String CLUSTER_NAME = "clustername"; - public static final String CLUSTER_TYPE = "clustertype"; - public static final String COMPONENT = "component"; - public static final String CPU_NUMBER = "cpunumber"; - public static final String CPU_SPEED = "cpuspeed"; - public static final String CREATED = "created"; - public static final String CUSTOMIZED = "customized"; - public static final String DESCRIPTION = "description"; - public static final String DESTINATION_ZONE_ID = "destzoneid"; - public static final String DETAILS = "details"; - public static final String DEVICE_ID = "deviceid"; - public static final String DISK_OFFERING_ID = "diskofferingid"; - public static final String DISK_SIZE = "disksize"; - public static final String DISPLAY_NAME = "displayname"; - public static final String DISPLAY_TEXT = "displaytext"; - public static final String DNS1 = "dns1"; - public static final String DNS2 = "dns2"; - public static final String DOMAIN = "domain"; - public static final String DOMAIN_ID = "domainid"; - public static final String DURATION = "duration"; - public static final String EMAIL = "email"; - public static final String END_DATE = "enddate"; - public static final String END_IP = "endip"; - public static final String END_PORT = "endport"; - public static final String ENTRY_TIME = "entrytime"; - public static final String FETCH_LATEST = "fetchlatest"; - public static final String FIRSTNAME = "firstname"; - public static final String FORCED = "forced"; - public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage"; - public static final String FORMAT = "format"; - public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork"; - public static final String GATEWAY = "gateway"; - public static final String GROUP = "group"; - public static final String GROUP_ID = "groupid"; - public static final String GUEST_CIDR_ADDRESS = "guestcidraddress"; - public static final String HA_ENABLE = "haenable"; - public static final String HOST_ID = "hostid"; - public static final String HOST_NAME = "hostname"; - public static final String HYPERVISOR = "hypervisor"; - public static final String INLINE = "inline"; - public static final String INSTANCE = "instance"; - public static final String ICMP_CODE = "icmpcode"; - public static final String ICMP_TYPE = "icmptype"; - public static final String ID = "id"; - public static final String IDS = "ids"; - public static final String INTERNAL_DNS1 = "internaldns1"; - public static final String INTERNAL_DNS2 = "internaldns2"; - public static final String INTERVAL_TYPE = "intervaltype"; - public static final String IP_ADDRESS = "ipaddress"; - public static final String IP_ADDRESS_ID = "ipaddressid"; - public static final String IP_AVAILABLE = "ipavailable"; - public static final String IP_LIMIT = "iplimit"; - public static final String IP_TOTAL = "iptotal"; - public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired"; - public static final String IS_EXTRACTABLE = "isextractable"; - public static final String IS_FEATURED = "isfeatured"; - public static final String IS_PUBLIC = "ispublic"; - public static final String IS_READY = "isready"; - public static final String IS_RECURSIVE = "isrecursive"; - public static final String ISO_FILTER = "isofilter"; - public static final String ISO_GUEST_OS_NONE = "None"; - public static final String JOB_ID = "jobid"; - 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 LOCK = "lock"; - public static final String LUN = "lun"; - public static final String LBID = "lbruleid"; - public static final String MAX = "max"; - public static final String MAX_SNAPS = "maxsnaps"; - public static final String MEMORY = "memory"; - public static final String MODE = "mode"; - public static final String NAME = "name"; - public static final String METHOD_NAME = "methodname"; - public static final String NETWORK_DOMAIN = "networkdomain"; - public static final String NETMASK = "netmask"; - public static final String NEW_NAME = "newname"; - public static final String NUM_RETRIES = "numretries"; - public static final String OFFER_HA = "offerha"; - public static final String IS_SYSTEM_OFFERING = "issystem"; - public static final String IS_DEFAULT_USE = "defaultuse"; - public static final String OP = "op"; - public static final String OS_CATEGORY_ID = "oscategoryid"; - public static final String OS_TYPE_ID = "ostypeid"; - public static final String PARENT_DOMAIN_ID = "parentdomainid"; - public static final String PASSWORD = "password"; - public static final String NEW_PASSWORD = "new_password"; - public static final String PASSWORD_ENABLED = "passwordenabled"; - public static final String SSHKEY_ENABLED = "sshkeyenabled"; - public static final String PATH = "path"; - public static final String POD_ID = "podid"; - public static final String POLICY_ID = "policyid"; - public static final String PORT = "port"; - 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_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"; - public static final String PUBLIC_INTERFACE = "publicinterface"; - 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_END_PORT = "publicendport"; - public static final String PUBLIC_ZONE = "publiczone"; - public static final String RECEIVED_BYTES = "receivedbytes"; - public static final String REQUIRES_HVM = "requireshvm"; - public static final String RESOURCE_TYPE = "resourcetype"; - public static final String QUERY_FILTER = "queryfilter"; - public static final String SCHEDULE = "schedule"; - public static final String SCOPE = "scope"; - public static final String SECRET_KEY = "usersecretkey"; - public static final String KEY = "key"; - public static final String SEARCH_BASE = "searchbase"; - public static final String SECURITY_GROUP_IDS = "securitygroupids"; - public static final String SECURITY_GROUP_NAMES = "securitygroupnames"; - public static final String SECURITY_GROUP_NAME = "securitygroupname"; - public static final String SECURITY_GROUP_ID = "securitygroupid"; - public static final String SENT = "sent"; - public static final String SENT_BYTES = "sentbytes"; - public static final String SERVICE_OFFERING_ID = "serviceofferingid"; - public static final String SHOW_CAPACITIES = "showcapacities"; - public static final String SIZE = "size"; - 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 START_DATE = "startdate"; - public static final String START_IP = "startip"; - public static final String START_PORT = "startport"; - public static final String STATE = "state"; - public static final String STATUS = "status"; - public static final String STORAGE_TYPE = "storagetype"; - public static final String SYSTEM_VM_TYPE = "systemvmtype"; - public static final String TAGS = "tags"; - public static final String TARGET_IQN = "targetiqn"; - public static final String TEMPLATE_FILTER = "templatefilter"; - public static final String TEMPLATE_ID = "templateid"; - public static final String TIMEOUT = "timeout"; - public static final String TIMEZONE = "timezone"; - public static final String TYPE = "type"; - public static final String TRUST_STORE = "truststore"; - public static final String TRUST_STORE_PASSWORD = "truststorepass"; - public static final String URL = "url"; - public static final String USAGE_INTERFACE = "usageinterface"; - public static final String USER_DATA = "userdata"; - public static final String USER_ID = "userid"; - public static final String USE_SSL = "ssl"; - public static final String USERNAME = "username"; - public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist"; - public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork"; - public static final String VALUE = "value"; - public static final String VIRTUAL_MACHINE_ID = "virtualmachineid"; - public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids"; - public static final String VLAN = "vlan"; - public static final String VLAN_ID = "vlanid"; - public static final String VM_AVAILABLE = "vmavailable"; - public static final String VM_LIMIT = "vmlimit"; - public static final String VM_TOTAL = "vmtotal"; - public static final String VNET = "vnet"; - public static final String VOLUME_ID = "volumeid"; - public static final String ZONE_ID = "zoneid"; - public static final String ZONE_NAME = "zonename"; - public static final String NETWORK_TYPE = "networktype"; - public static final String PAGE = "page"; - public static final String PAGE_SIZE = "pagesize"; - public static final String COUNT = "count"; - public static final String TRAFFIC_TYPE = "traffictype"; - public static final String NETWORK_OFFERING_ID = "networkofferingid"; - public static final String NETWORK_IDS = "networkids"; - public static final String NETWORK_ID = "networkid"; - public static final String SPECIFY_VLAN = "specifyvlan"; - public static final String IS_DEFAULT = "isdefault"; - public static final String IS_SYSTEM = "issystem"; - public static final String AVAILABILITY = "availability"; - public static final String NETWORKRATE = "networkrate"; - public static final String HOST_TAGS = "hosttags"; - public static final String SSH_KEYPAIR = "keypair"; - public static final String HOST_CPU_CAPACITY = "hostcpucapacity"; - public static final String HOST_CPU_NUM = "hostcpunum"; - public static final String HOST_MEM_CAPACITY = "hostmemcapacity"; - public static final String HOST_MAC = "hostmac"; - public static final String HOST_TAG = "hosttag"; - public static final String PXE_SERVER_TYPE = "pxeservertype"; - public static final String LINMIN_USERNAME = "linminusername"; - public static final String LINMIN_PASSWORD = "linminpassword"; - public static final String LINMIN_APID = "linminapid"; - public static final String DHCP_SERVER_TYPE = "dhcpservertype"; - public static final String LINK_LOCAL_IP = "linklocalip"; - public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress"; - public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask"; - public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid"; - public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress"; - public static final String PRIVATE_NETMASK = "privatenetmask"; - public static final String PRIVATE_NETWORK_ID = "privatenetworkid"; - public static final String ALLOCATION_STATE = "allocationstate"; - public static final String MANAGED_STATE = "managedstate"; - public static final String STORAGE_ID="storageid"; - public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip"; - public static final String PING_DIR = "pingdir"; - public static final String TFTP_DIR = "tftpdir"; - public static final String PING_CIFS_USERNAME = "pingcifsusername"; - public static final String PING_CIFS_PASSWORD = "pingcifspassword"; - public static final String CHECKSUM="checksum"; - public static final String NETWORK_DEVICE_TYPE = "networkdevicetype"; - public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist"; - public static final String ZONE_TOKEN = "zonetoken"; - public static final String DHCP_PROVIDER = "dhcpprovider"; - public static final String RESULT = "success"; - public static final String LUN_ID = "lunId"; - public static final String IQN = "iqn"; - public static final String AGGREGATE_NAME = "aggregatename"; - public static final String POOL_NAME = "poolname"; - public static final String VOLUME_NAME = "volumename"; - public static final String SNAPSHOT_POLICY = "snapshotpolicy"; - public static final String SNAPSHOT_RESERVATION = "snapshotreservation"; - public static final String IP_NETWORK_LIST = "iptonetworklist"; - public static final String PARAM_LIST = "param"; - public static final String FOR_LOAD_BALANCING = "forloadbalancing"; - public static final String KEYBOARD="keyboard"; - public static final String OPEN_FIREWALL="openfirewall"; - public static final String TEMPLATE_TAG = "templatetag"; - public static final String HYPERVISOR_VERSION = "hypervisorversion"; - public static final String MAX_GUESTS_LIMIT = "maxguestslimit"; - public static final String PROJECT_ID = "projectid"; - public static final String PROJECT_IDS = "projectids"; - public static final String PROJECT = "project"; - public static final String ROLE = "role"; - public static final String USER = "user"; - public static final String ACTIVE_ONLY = "activeonly"; - public static final String TOKEN = "token"; - public static final String ACCEPT = "accept"; - public static final String SORT_KEY = "sortkey"; - public static final String ACCOUNT_DETAILS = "accountdetails"; - public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist"; - public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist"; - public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability"; - public static final String PROVIDER = "provider"; - public static final String NETWORK_SPEED = "networkspeed"; - public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange"; - public static final String ISOLATION_METHODS = "isolationmethods"; - public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid"; - public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid"; - public static final String ENABLED = "enabled"; - public static final String SERVICE_NAME = "servicename"; - public static final String DHCP_RANGE = "dhcprange"; - public static final String UUID = "uuid"; - public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled"; - public static final String GUEST_IP_TYPE = "guestiptype"; - public static final String XEN_NETWORK_LABEL = "xennetworklabel"; - public static final String KVM_NETWORK_LABEL = "kvmnetworklabel"; - public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel"; - public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid"; - public static final String SERVICE_LIST = "servicelist"; - public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice"; - public static final String SUPPORTED_SERVICES = "supportedservices"; - public static final String NSP_ID= "nspid"; - public static final String ACL_TYPE= "acltype"; - public static final String SUBDOMAIN_ACCESS = "subdomainaccess"; - public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid"; - public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename"; - public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate"; - public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity"; - public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated"; - public static final String FIREWALL_DEVICE_ID = "fwdeviceid"; - public static final String FIREWALL_DEVICE_NAME = "fwdevicename"; - public static final String FIREWALL_DEVICE_STATE = "fwdevicestate"; - public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity"; - public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated"; - public static final String SERVICE = "service"; - public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid"; - public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported"; - public static final String RESOURCE_STATE = "resourcestate"; - public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired"; - public static final String RESTART_REQUIRED = "restartrequired"; - public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects"; - public static final String CONSERVE_MODE = "conservemode"; - public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor"; - public static final String KEYWORD = "keyword"; - public static final String LIST_ALL = "listall"; - public static final String SPECIFY_IP_RANGES = "specifyipranges"; - public static final String IS_SOURCE_NAT = "issourcenat"; - public static final String IS_STATIC_NAT = "isstaticnat"; - public static final String SORT_BY = "sortby"; - public static final String CHANGE_CIDR = "changecidr"; - public static final String PURPOSE = "purpose"; - public static final String IS_TAGGED = "istagged"; - public static final String INSTANCE_NAME = "instancename"; - public static final String START_VM = "startvm"; - public static final String HA_HOST = "hahost"; - public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize"; - public static final String DEFAULT_ZONE_ID = "defaultzoneid"; - public static final String GUID = "guid"; - - public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid"; - public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename"; - public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate"; - // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this later. - public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity"; - public static final String CISCO_NEXUS_VSM_NAME = "vsmname"; - public static final String VSM_USERNAME = "vsmusername"; - public static final String VSM_PASSWORD = "vsmpassword"; - public static final String VSM_IPADDRESS = "vsmipaddress"; - public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid"; - public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid"; - public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid"; - public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid"; - public static final String VSM_DOMAIN_ID = "vsmdomainid"; - public static final String VSM_CONFIG_MODE = "vsmconfigmode"; - public static final String VSM_CONFIG_STATE = "vsmconfigstate"; - public static final String VSM_DEVICE_STATE = "vsmdevicestate"; - public static final String INCL_ZONES = "includezones"; - public static final String EXCL_ZONES = "excludezones"; - public static final String RESOURCE_IDS = "resourceids"; - public static final String RESOURCE_ID = "resourceid"; - public static final String CUSTOMER = "customer"; - public static final String VPC_OFF_ID = "vpcofferingid"; - public static final String NETWORK = "network"; - public static final String VPC_ID = "vpcid"; - public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy"; - public static final String GATEWAY_ID = "gatewayid"; - public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid"; - public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid"; - public static final String IPSEC_PSK = "ipsecpsk"; - public static final String GUEST_IP = "guestip"; - public static final String REMOVED = "removed"; - public static final String IKE_POLICY = "ikepolicy"; - public static final String ESP_POLICY = "esppolicy"; - public static final String LIFETIME = "lifetime"; - public static final String FOR_VPC = "forvpc"; - - 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(); - } - } - - -} +// 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.api; + +public class ApiConstants { + public static final String ACCOUNT = "account"; + public static final String ACCOUNTS = "accounts"; + public static final String ACCOUNT_TYPE = "accounttype"; + public static final String ACCOUNT_ID = "accountid"; + public static final String ALGORITHM = "algorithm"; + public static final String ALLOCATED_ONLY = "allocatedonly"; + public static final String API_KEY = "userapikey"; + public static final String APPLIED = "applied"; + public static final String AVAILABLE = "available"; + public static final String BITS = "bits"; + public static final String BOOTABLE = "bootable"; + 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 CIDR = "cidr"; + public static final String CIDR_LIST = "cidrlist"; + public static final String CLEANUP = "cleanup"; + public static final String CLUSTER_ID = "clusterid"; + public static final String CLUSTER_NAME = "clustername"; + public static final String CLUSTER_TYPE = "clustertype"; + public static final String COMPONENT = "component"; + public static final String CPU_NUMBER = "cpunumber"; + public static final String CPU_SPEED = "cpuspeed"; + public static final String CREATED = "created"; + public static final String CUSTOMIZED = "customized"; + public static final String DESCRIPTION = "description"; + public static final String DESTINATION_ZONE_ID = "destzoneid"; + public static final String DETAILS = "details"; + public static final String DEVICE_ID = "deviceid"; + public static final String DISK_OFFERING_ID = "diskofferingid"; + public static final String DISK_SIZE = "disksize"; + public static final String DISPLAY_NAME = "displayname"; + public static final String DISPLAY_TEXT = "displaytext"; + public static final String DNS1 = "dns1"; + public static final String DNS2 = "dns2"; + public static final String DOMAIN = "domain"; + public static final String DOMAIN_ID = "domainid"; + public static final String DURATION = "duration"; + public static final String EMAIL = "email"; + public static final String END_DATE = "enddate"; + public static final String END_IP = "endip"; + public static final String END_PORT = "endport"; + public static final String ENTRY_TIME = "entrytime"; + public static final String FETCH_LATEST = "fetchlatest"; + public static final String FIRSTNAME = "firstname"; + public static final String FORCED = "forced"; + public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage"; + public static final String FORMAT = "format"; + public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork"; + public static final String GATEWAY = "gateway"; + public static final String GROUP = "group"; + public static final String GROUP_ID = "groupid"; + public static final String GUEST_CIDR_ADDRESS = "guestcidraddress"; + public static final String HA_ENABLE = "haenable"; + public static final String HOST_ID = "hostid"; + public static final String HOST_NAME = "hostname"; + public static final String HYPERVISOR = "hypervisor"; + public static final String INLINE = "inline"; + public static final String INSTANCE = "instance"; + public static final String ICMP_CODE = "icmpcode"; + public static final String ICMP_TYPE = "icmptype"; + public static final String ID = "id"; + public static final String IDS = "ids"; + public static final String INTERNAL_DNS1 = "internaldns1"; + public static final String INTERNAL_DNS2 = "internaldns2"; + public static final String INTERVAL_TYPE = "intervaltype"; + public static final String IP_ADDRESS = "ipaddress"; + public static final String IP_ADDRESS_ID = "ipaddressid"; + public static final String IP_AVAILABLE = "ipavailable"; + public static final String IP_LIMIT = "iplimit"; + public static final String IP_TOTAL = "iptotal"; + public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired"; + public static final String IS_EXTRACTABLE = "isextractable"; + public static final String IS_FEATURED = "isfeatured"; + public static final String IS_PUBLIC = "ispublic"; + public static final String IS_READY = "isready"; + public static final String IS_RECURSIVE = "isrecursive"; + public static final String ISO_FILTER = "isofilter"; + public static final String ISO_GUEST_OS_NONE = "None"; + public static final String JOB_ID = "jobid"; + 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 LOCK = "lock"; + public static final String LUN = "lun"; + public static final String LBID = "lbruleid"; + public static final String MAX = "max"; + public static final String MAX_SNAPS = "maxsnaps"; + public static final String MEMORY = "memory"; + public static final String MODE = "mode"; + public static final String NAME = "name"; + public static final String METHOD_NAME = "methodname"; + public static final String NETWORK_DOMAIN = "networkdomain"; + public static final String NETMASK = "netmask"; + public static final String NEW_NAME = "newname"; + public static final String NUM_RETRIES = "numretries"; + public static final String OFFER_HA = "offerha"; + public static final String IS_SYSTEM_OFFERING = "issystem"; + public static final String IS_DEFAULT_USE = "defaultuse"; + public static final String OP = "op"; + public static final String OS_CATEGORY_ID = "oscategoryid"; + public static final String OS_TYPE_ID = "ostypeid"; + public static final String PARENT_DOMAIN_ID = "parentdomainid"; + public static final String PASSWORD = "password"; + public static final String NEW_PASSWORD = "new_password"; + public static final String PASSWORD_ENABLED = "passwordenabled"; + public static final String SSHKEY_ENABLED = "sshkeyenabled"; + public static final String PATH = "path"; + public static final String POD_ID = "podid"; + public static final String POLICY_ID = "policyid"; + public static final String PORT = "port"; + 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_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"; + public static final String PUBLIC_INTERFACE = "publicinterface"; + 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_END_PORT = "publicendport"; + public static final String PUBLIC_ZONE = "publiczone"; + public static final String RECEIVED_BYTES = "receivedbytes"; + public static final String REQUIRES_HVM = "requireshvm"; + public static final String RESOURCE_TYPE = "resourcetype"; + public static final String QUERY_FILTER = "queryfilter"; + public static final String SCHEDULE = "schedule"; + public static final String SCOPE = "scope"; + public static final String SECRET_KEY = "usersecretkey"; + public static final String KEY = "key"; + public static final String SEARCH_BASE = "searchbase"; + public static final String SECURITY_GROUP_IDS = "securitygroupids"; + public static final String SECURITY_GROUP_NAMES = "securitygroupnames"; + public static final String SECURITY_GROUP_NAME = "securitygroupname"; + public static final String SECURITY_GROUP_ID = "securitygroupid"; + public static final String SENT = "sent"; + public static final String SENT_BYTES = "sentbytes"; + public static final String SERVICE_OFFERING_ID = "serviceofferingid"; + public static final String SHOW_CAPACITIES = "showcapacities"; + public static final String SIZE = "size"; + 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 START_DATE = "startdate"; + public static final String START_IP = "startip"; + public static final String START_PORT = "startport"; + public static final String STATE = "state"; + public static final String STATUS = "status"; + public static final String STORAGE_TYPE = "storagetype"; + public static final String SYSTEM_VM_TYPE = "systemvmtype"; + public static final String TAGS = "tags"; + public static final String TARGET_IQN = "targetiqn"; + public static final String TEMPLATE_FILTER = "templatefilter"; + public static final String TEMPLATE_ID = "templateid"; + public static final String TIMEOUT = "timeout"; + public static final String TIMEZONE = "timezone"; + public static final String TYPE = "type"; + public static final String TRUST_STORE = "truststore"; + public static final String TRUST_STORE_PASSWORD = "truststorepass"; + public static final String URL = "url"; + public static final String USAGE_INTERFACE = "usageinterface"; + public static final String USER_DATA = "userdata"; + public static final String USER_ID = "userid"; + public static final String USE_SSL = "ssl"; + public static final String USERNAME = "username"; + public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist"; + public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork"; + public static final String VALUE = "value"; + public static final String VIRTUAL_MACHINE_ID = "virtualmachineid"; + public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids"; + public static final String VLAN = "vlan"; + public static final String VLAN_ID = "vlanid"; + public static final String VM_AVAILABLE = "vmavailable"; + public static final String VM_LIMIT = "vmlimit"; + public static final String VM_TOTAL = "vmtotal"; + public static final String VNET = "vnet"; + public static final String VOLUME_ID = "volumeid"; + public static final String ZONE_ID = "zoneid"; + public static final String ZONE_NAME = "zonename"; + public static final String NETWORK_TYPE = "networktype"; + public static final String PAGE = "page"; + public static final String PAGE_SIZE = "pagesize"; + public static final String COUNT = "count"; + public static final String TRAFFIC_TYPE = "traffictype"; + public static final String NETWORK_OFFERING_ID = "networkofferingid"; + public static final String NETWORK_IDS = "networkids"; + public static final String NETWORK_ID = "networkid"; + public static final String SPECIFY_VLAN = "specifyvlan"; + public static final String IS_DEFAULT = "isdefault"; + public static final String IS_SYSTEM = "issystem"; + public static final String AVAILABILITY = "availability"; + public static final String NETWORKRATE = "networkrate"; + public static final String HOST_TAGS = "hosttags"; + public static final String SSH_KEYPAIR = "keypair"; + public static final String HOST_CPU_CAPACITY = "hostcpucapacity"; + public static final String HOST_CPU_NUM = "hostcpunum"; + public static final String HOST_MEM_CAPACITY = "hostmemcapacity"; + public static final String HOST_MAC = "hostmac"; + public static final String HOST_TAG = "hosttag"; + public static final String PXE_SERVER_TYPE = "pxeservertype"; + public static final String LINMIN_USERNAME = "linminusername"; + public static final String LINMIN_PASSWORD = "linminpassword"; + public static final String LINMIN_APID = "linminapid"; + public static final String DHCP_SERVER_TYPE = "dhcpservertype"; + public static final String LINK_LOCAL_IP = "linklocalip"; + public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress"; + public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask"; + public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid"; + public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress"; + public static final String PRIVATE_NETMASK = "privatenetmask"; + public static final String PRIVATE_NETWORK_ID = "privatenetworkid"; + public static final String ALLOCATION_STATE = "allocationstate"; + public static final String MANAGED_STATE = "managedstate"; + public static final String STORAGE_ID="storageid"; + public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip"; + public static final String PING_DIR = "pingdir"; + public static final String TFTP_DIR = "tftpdir"; + public static final String PING_CIFS_USERNAME = "pingcifsusername"; + public static final String PING_CIFS_PASSWORD = "pingcifspassword"; + public static final String CHECKSUM="checksum"; + public static final String NETWORK_DEVICE_TYPE = "networkdevicetype"; + public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist"; + public static final String ZONE_TOKEN = "zonetoken"; + public static final String DHCP_PROVIDER = "dhcpprovider"; + public static final String RESULT = "success"; + public static final String LUN_ID = "lunId"; + public static final String IQN = "iqn"; + public static final String AGGREGATE_NAME = "aggregatename"; + public static final String POOL_NAME = "poolname"; + public static final String VOLUME_NAME = "volumename"; + public static final String SNAPSHOT_POLICY = "snapshotpolicy"; + public static final String SNAPSHOT_RESERVATION = "snapshotreservation"; + public static final String IP_NETWORK_LIST = "iptonetworklist"; + public static final String PARAM_LIST = "param"; + public static final String FOR_LOAD_BALANCING = "forloadbalancing"; + public static final String KEYBOARD="keyboard"; + public static final String OPEN_FIREWALL="openfirewall"; + public static final String TEMPLATE_TAG = "templatetag"; + public static final String HYPERVISOR_VERSION = "hypervisorversion"; + public static final String MAX_GUESTS_LIMIT = "maxguestslimit"; + public static final String PROJECT_ID = "projectid"; + public static final String PROJECT_IDS = "projectids"; + public static final String PROJECT = "project"; + public static final String ROLE = "role"; + public static final String USER = "user"; + public static final String ACTIVE_ONLY = "activeonly"; + public static final String TOKEN = "token"; + public static final String ACCEPT = "accept"; + public static final String SORT_KEY = "sortkey"; + public static final String ACCOUNT_DETAILS = "accountdetails"; + public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist"; + public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist"; + public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability"; + public static final String PROVIDER = "provider"; + public static final String NETWORK_SPEED = "networkspeed"; + public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange"; + public static final String ISOLATION_METHODS = "isolationmethods"; + public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid"; + public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid"; + public static final String ENABLED = "enabled"; + public static final String SERVICE_NAME = "servicename"; + public static final String DHCP_RANGE = "dhcprange"; + public static final String UUID = "uuid"; + public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled"; + public static final String GUEST_IP_TYPE = "guestiptype"; + public static final String XEN_NETWORK_LABEL = "xennetworklabel"; + public static final String KVM_NETWORK_LABEL = "kvmnetworklabel"; + public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel"; + public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid"; + public static final String SERVICE_LIST = "servicelist"; + public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice"; + public static final String SUPPORTED_SERVICES = "supportedservices"; + public static final String NSP_ID= "nspid"; + public static final String ACL_TYPE= "acltype"; + public static final String SUBDOMAIN_ACCESS = "subdomainaccess"; + public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid"; + public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename"; + public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate"; + public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity"; + public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated"; + public static final String FIREWALL_DEVICE_ID = "fwdeviceid"; + public static final String FIREWALL_DEVICE_NAME = "fwdevicename"; + public static final String FIREWALL_DEVICE_STATE = "fwdevicestate"; + public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity"; + public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated"; + public static final String SERVICE = "service"; + public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid"; + public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported"; + public static final String RESOURCE_STATE = "resourcestate"; + public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired"; + public static final String RESTART_REQUIRED = "restartrequired"; + public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects"; + public static final String CONSERVE_MODE = "conservemode"; + public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor"; + public static final String KEYWORD = "keyword"; + public static final String LIST_ALL = "listall"; + public static final String SPECIFY_IP_RANGES = "specifyipranges"; + public static final String IS_SOURCE_NAT = "issourcenat"; + public static final String IS_STATIC_NAT = "isstaticnat"; + public static final String SORT_BY = "sortby"; + public static final String CHANGE_CIDR = "changecidr"; + public static final String PURPOSE = "purpose"; + public static final String IS_TAGGED = "istagged"; + public static final String INSTANCE_NAME = "instancename"; + public static final String START_VM = "startvm"; + public static final String HA_HOST = "hahost"; + public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize"; + public static final String DEFAULT_ZONE_ID = "defaultzoneid"; + public static final String GUID = "guid"; + + public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid"; + public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename"; + public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate"; + // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this +// later. + public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity"; + public static final String CISCO_NEXUS_VSM_NAME = "vsmname"; + public static final String VSM_USERNAME = "vsmusername"; + public static final String VSM_PASSWORD = "vsmpassword"; + public static final String VSM_IPADDRESS = "vsmipaddress"; + public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid"; + public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid"; + public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid"; + public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid"; + public static final String VSM_DOMAIN_ID = "vsmdomainid"; + public static final String VSM_CONFIG_MODE = "vsmconfigmode"; + public static final String VSM_CONFIG_STATE = "vsmconfigstate"; + public static final String VSM_DEVICE_STATE = "vsmdevicestate"; + public static final String INCL_ZONES = "includezones"; + public static final String EXCL_ZONES = "excludezones"; + public static final String RESOURCE_IDS = "resourceids"; + public static final String RESOURCE_ID = "resourceid"; + public static final String CUSTOMER = "customer"; + public static final String VPC_OFF_ID = "vpcofferingid"; + public static final String NETWORK = "network"; + public static final String VPC_ID = "vpcid"; + public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy"; + public static final String GATEWAY_ID = "gatewayid"; + public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid"; + public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid"; + public static final String IPSEC_PSK = "ipsecpsk"; + public static final String GUEST_IP = "guestip"; + public static final String REMOVED = "removed"; + public static final String IKE_POLICY = "ikepolicy"; + public static final String ESP_POLICY = "esppolicy"; + public static final String LIFETIME = "lifetime"; + public static final String FOR_VPC = "forvpc"; + 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 SCALEUP_POLICY_IDS = "scaleuppolicyids"; + public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids"; + 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 8895bf0a173..2ca70577c14 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -1,525 +1,528 @@ -// 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.api; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import org.apache.log4j.Logger; - -import com.cloud.configuration.ConfigurationService; -import com.cloud.consoleproxy.ConsoleProxyService; -import com.cloud.dao.EntityManager; -import com.cloud.domain.Domain; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.NetworkRuleConflictException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.NetworkService; -import com.cloud.network.StorageNetworkService; -import com.cloud.network.VirtualNetworkApplianceService; -import com.cloud.network.firewall.FirewallService; -import com.cloud.network.firewall.NetworkACLService; -import com.cloud.network.lb.LoadBalancingRulesService; -import com.cloud.network.rules.RulesService; -import com.cloud.network.security.SecurityGroupService; -import com.cloud.network.vpc.VpcService; -import com.cloud.network.vpn.RemoteAccessVpnService; -import com.cloud.network.vpn.Site2SiteVpnService; -import com.cloud.projects.Project; -import com.cloud.projects.ProjectService; -import com.cloud.resource.ResourceService; -import com.cloud.server.ManagementService; -import com.cloud.server.TaggedResourceService; -import com.cloud.storage.StorageService; -import com.cloud.storage.snapshot.SnapshotService; -import com.cloud.template.TemplateService; -import com.cloud.user.Account; -import com.cloud.user.AccountService; -import com.cloud.user.DomainService; -import com.cloud.user.ResourceLimitService; -import com.cloud.utils.IdentityProxy; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.vm.BareMetalVmService; -import com.cloud.vm.UserVmService; - -public abstract class BaseCmd { - private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName()); - - public static final String USER_ERROR_MESSAGE = "Internal error executing command, please contact your system administrator"; - public static final int PROGRESS_INSTANCE_CREATED = 1; - - public static final String RESPONSE_TYPE_XML = "xml"; - public static final String RESPONSE_TYPE_JSON = "json"; - - public enum CommandType { - BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE - } - - // FIXME: Extract these out into a separate file - // Client error codes - public static final int MALFORMED_PARAMETER_ERROR = 430; - public static final int PARAM_ERROR = 431; - public static final int UNSUPPORTED_ACTION_ERROR = 432; - public static final int PAGE_LIMIT_EXCEED = 433; - - // Server error codes - public static final int INTERNAL_ERROR = 530; - public static final int ACCOUNT_ERROR = 531; - public static final int ACCOUNT_RESOURCE_LIMIT_ERROR = 532; - public static final int INSUFFICIENT_CAPACITY_ERROR = 533; - public static final int RESOURCE_UNAVAILABLE_ERROR = 534; - public static final int RESOURCE_ALLOCATION_ERROR = 534; - public static final int RESOURCE_IN_USE_ERROR = 536; - public static final int NETWORK_RULE_CONFLICT_ERROR = 537; - - public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); - public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+"); - private static final DateFormat _outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - - private Object _responseObject = null; - private Map fullUrlParams; - - @Parameter(name = "response", type = CommandType.STRING) - private String responseType; - - public static ComponentLocator s_locator; - public static ConfigurationService _configService; - public static AccountService _accountService; - public static UserVmService _userVmService; - public static ManagementService _mgr; - public static StorageService _storageService; - public static ResourceService _resourceService; - public static NetworkService _networkService; - public static TemplateService _templateService; - public static SecurityGroupService _securityGroupService; - public static SnapshotService _snapshotService; - public static ConsoleProxyService _consoleProxyService; - public static VirtualNetworkApplianceService _routerService; - public static ResponseGenerator _responseGenerator; - public static EntityManager _entityMgr; - public static RulesService _rulesService; - public static LoadBalancingRulesService _lbService; - public static RemoteAccessVpnService _ravService; - public static BareMetalVmService _bareMetalVmService; - public static ProjectService _projectService; - public static FirewallService _firewallService; - public static DomainService _domainService; - public static ResourceLimitService _resourceLimitService; - public static IdentityService _identityService; - public static StorageNetworkService _storageNetworkService; - public static TaggedResourceService _taggedResourceService; - public static VpcService _vpcService; - public static NetworkACLService _networkACLService; - public static Site2SiteVpnService _s2sVpnService; - - static void setComponents(ResponseGenerator generator) { - ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); - _mgr = (ManagementService) ComponentLocator.getComponent(ManagementService.Name); - _accountService = locator.getManager(AccountService.class); - _configService = locator.getManager(ConfigurationService.class); - _userVmService = locator.getManager(UserVmService.class); - _storageService = locator.getManager(StorageService.class); - _resourceService = locator.getManager(ResourceService.class); - _networkService = locator.getManager(NetworkService.class); - _templateService = locator.getManager(TemplateService.class); - _securityGroupService = locator.getManager(SecurityGroupService.class); - _snapshotService = locator.getManager(SnapshotService.class); - _consoleProxyService = locator.getManager(ConsoleProxyService.class); - _routerService = locator.getManager(VirtualNetworkApplianceService.class); - _entityMgr = locator.getManager(EntityManager.class); - _rulesService = locator.getManager(RulesService.class); - _lbService = locator.getManager(LoadBalancingRulesService.class); - _ravService = locator.getManager(RemoteAccessVpnService.class); - _responseGenerator = generator; - _bareMetalVmService = locator.getManager(BareMetalVmService.class); - _projectService = locator.getManager(ProjectService.class); - _firewallService = locator.getManager(FirewallService.class); - _domainService = locator.getManager(DomainService.class); - _resourceLimitService = locator.getManager(ResourceLimitService.class); - _identityService = locator.getManager(IdentityService.class); - _storageNetworkService = locator.getManager(StorageNetworkService.class); - _taggedResourceService = locator.getManager(TaggedResourceService.class); - _vpcService = locator.getManager(VpcService.class); - _networkACLService = locator.getManager(NetworkACLService.class); - _s2sVpnService = locator.getManager(Site2SiteVpnService.class); - } - - public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException; - - public String getResponseType() { - if (responseType == null) { - return RESPONSE_TYPE_XML; - } - return responseType; - } - - public void setResponseType(String responseType) { - this.responseType = responseType; - } - - public abstract String getCommandName(); - - /** - * For commands the API framework needs to know the owner of the object being acted upon. This method is - * used to determine that information. - * - * @return the id of the account that owns the object being acted upon - */ - public abstract long getEntityOwnerId(); - - public Object getResponseObject() { - return _responseObject; - } - - public void setResponseObject(Object responseObject) { - _responseObject = responseObject; - } - - public ManagementService getMgmtServiceRef() { - return _mgr; - } - - public static String getDateString(Date date) { - if (date == null) { - return ""; - } - String formattedString = null; - synchronized (_outputFormat) { - formattedString = _outputFormat.format(date); - } - return formattedString; - } - - // FIXME: move this to a utils method so that maps can be unpacked and integer/long values can be appropriately cast - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Map unpackParams(Map params) { - Map lowercaseParams = new HashMap(); - for (String key : params.keySet()) { - int arrayStartIndex = key.indexOf('['); - int arrayStartLastIndex = key.lastIndexOf('['); - if (arrayStartIndex != arrayStartLastIndex) { - throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key - + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); - } - - if (arrayStartIndex > 0) { - int arrayEndIndex = key.indexOf(']'); - int arrayEndLastIndex = key.lastIndexOf(']'); - if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) { - // malformed parameter - throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key - + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); - } - - // Now that we have an array object, check for a field name in the case of a complex object - int fieldIndex = key.indexOf('.'); - String fieldName = null; - if (fieldIndex < arrayEndIndex) { - throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key - + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); - } else { - fieldName = key.substring(fieldIndex + 1); - } - - // parse the parameter name as the text before the first '[' character - String paramName = key.substring(0, arrayStartIndex); - paramName = paramName.toLowerCase(); - - Map mapArray = null; - Map mapValue = null; - String indexStr = key.substring(arrayStartIndex + 1, arrayEndIndex); - int index = 0; - boolean parsedIndex = false; - try { - if (indexStr != null) { - index = Integer.parseInt(indexStr); - parsedIndex = true; - } - } catch (NumberFormatException nfe) { - s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error."); - } - - if (!parsedIndex) { - throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key - + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); - } - - Object value = lowercaseParams.get(paramName); - if (value == null) { - // for now, assume object array with sub fields - mapArray = new HashMap(); - mapValue = new HashMap(); - mapArray.put(Integer.valueOf(index), mapValue); - } else if (value instanceof Map) { - mapArray = (HashMap) value; - mapValue = mapArray.get(Integer.valueOf(index)); - if (mapValue == null) { - mapValue = new HashMap(); - mapArray.put(Integer.valueOf(index), mapValue); - } - } - - // we are ready to store the value for a particular field into the map for this object - mapValue.put(fieldName, params.get(key)); - - lowercaseParams.put(paramName, mapArray); - } else { - lowercaseParams.put(key.toLowerCase(), params.get(key)); - } - } - return lowercaseParams; - } - - public String buildResponse(ServerApiException apiException, String responseType) { - StringBuffer sb = new StringBuffer(); - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - // JSON response - sb.append("{ \"" + getCommandName() + "\" : { " + "\"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},"); - sb.append("\"errorcode\" : \"" + apiException.getErrorCode() + "\", \"description\" : \"" + apiException.getDescription() + "\" } }"); - } else { - sb.append(""); - sb.append("<" + getCommandName() + ">"); - sb.append("" + apiException.getErrorCode() + ""); - sb.append("" + escapeXml(apiException.getDescription()) + ""); - sb.append(""); - } - return sb.toString(); - } - - public String buildResponse(List> tagList, String responseType) { - StringBuffer prefixSb = new StringBuffer(); - StringBuffer suffixSb = new StringBuffer(); - - // set up the return value with the name of the response - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - prefixSb.append("{ \"" + getCommandName() + "\" : { \"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},"); - } else { - prefixSb.append(""); - prefixSb.append("<" + getCommandName() + " cloud-stack-version=\"" + _mgr.getVersion() + "\">"); - } - - int i = 0; - for (Pair tagData : tagList) { - String tagName = tagData.first(); - Object tagValue = tagData.second(); - if (tagValue instanceof Object[]) { - Object[] subObjects = (Object[]) tagValue; - if (subObjects.length < 1) { - continue; - } - writeObjectArray(responseType, suffixSb, i++, tagName, subObjects); - } else { - writeNameValuePair(suffixSb, tagName, tagValue, responseType, i++); - } - } - - 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. - prefixSb.append(","); - } - prefixSb.append(suffixSb); - } - // close the response - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - prefixSb.append("} }"); - } else { - prefixSb.append(""); - } - return prefixSb.toString(); - } - - private void writeNameValuePair(StringBuffer sb, String tagName, Object tagValue, String responseType, int propertyCount) { - if (tagValue == null) { - return; - } - - if (tagValue instanceof Object[]) { - Object[] subObjects = (Object[]) tagValue; - if (subObjects.length < 1) { - return; - } - writeObjectArray(responseType, sb, propertyCount, tagName, subObjects); - } else { - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - String seperator = ((propertyCount > 0) ? ", " : ""); - sb.append(seperator + "\"" + tagName + "\" : \"" + escapeJSON(tagValue.toString()) + "\""); - } else { - sb.append("<" + tagName + ">" + escapeXml(tagValue.toString()) + ""); - } - } - } - - @SuppressWarnings("rawtypes") - private void writeObjectArray(String responseType, StringBuffer sb, int propertyCount, String tagName, Object[] subObjects) { - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - String separator = ((propertyCount > 0) ? ", " : ""); - sb.append(separator); - } - int j = 0; - for (Object subObject : subObjects) { - if (subObject instanceof List) { - List subObjList = (List) subObject; - writeSubObject(sb, tagName, subObjList, responseType, j++); - } - } - - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - sb.append("]"); - } - } - - @SuppressWarnings("rawtypes") - private void writeSubObject(StringBuffer sb, String tagName, List tagList, String responseType, int objectCount) { - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - sb.append(((objectCount == 0) ? "\"" + tagName + "\" : [ { " : ", { ")); - } else { - sb.append("<" + tagName + ">"); - } - - int i = 0; - for (Object tag : tagList) { - if (tag instanceof Pair) { - Pair nameValuePair = (Pair) tag; - writeNameValuePair(sb, (String) nameValuePair.first(), nameValuePair.second(), responseType, i++); - } - } - - if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - sb.append("}"); - } else { - sb.append(""); - } - } - - /** - * Escape xml response set to false by default. API commands to override this method to allow escaping - */ - public boolean requireXmlEscape() { - return true; - } - - private String escapeXml(String xml) { - if (!requireXmlEscape()) { - return xml; - } - int iLen = xml.length(); - if (iLen == 0) { - return xml; - } - StringBuffer sOUT = new StringBuffer(iLen + 256); - int i = 0; - for (; i < iLen; i++) { - char c = xml.charAt(i); - if (c == '<') { - sOUT.append("<"); - } else if (c == '>') { - sOUT.append(">"); - } else if (c == '&') { - sOUT.append("&"); - } else if (c == '"') { - sOUT.append("""); - } else if (c == '\'') { - sOUT.append("'"); - } else { - sOUT.append(c); - } - } - return sOUT.toString(); - } - - private static String escapeJSON(String str) { - if (str == null) { - return str; - } - - return str.replace("\"", "\\\""); - } - - protected long getInstanceIdFromJobSuccessResult(String result) { - s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName()); - return 0; - } - - public static boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); - } - - public static boolean isRootAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN)); - } - - public void setFullUrlParams(Map map) { - this.fullUrlParams = map; - } - - public Map getFullUrlParams() { - return this.fullUrlParams; - } - - public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { - if (accountName != null) { - if (domainId == null) { - throw new InvalidParameterValueException("Account must be specified with domainId parameter", null); - } - - Domain domain = _domainService.getDomain(domainId); - if (domain == null) { - throw new InvalidParameterValueException("Unable to find domain by id", null); - } - - Account account = _accountService.getActiveAccountByName(accountName, domainId); - if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) { - 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"); - } - } else { - List idList = new ArrayList(); - idList.add(new IdentityProxy("domain", domainId, "domainId")); - throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id", idList); - } - } - - if (projectId != null) { - Project project = _projectService.getProject(projectId); - if (project != null) { - 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"); - throw ex; - } - } else { - throw new InvalidParameterValueException("Unable to find project by id", null); - } - } - return null; - } -} +// 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.api; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; + +import com.cloud.configuration.ConfigurationService; +import com.cloud.consoleproxy.ConsoleProxyService; +import com.cloud.dao.EntityManager; +import com.cloud.domain.Domain; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NetworkService; +import com.cloud.network.StorageNetworkService; +import com.cloud.network.VirtualNetworkApplianceService; +import com.cloud.network.as.AutoScaleService; +import com.cloud.network.firewall.FirewallService; +import com.cloud.network.firewall.NetworkACLService; +import com.cloud.network.lb.LoadBalancingRulesService; +import com.cloud.network.rules.RulesService; +import com.cloud.network.security.SecurityGroupService; +import com.cloud.network.vpc.VpcService; +import com.cloud.network.vpn.RemoteAccessVpnService; +import com.cloud.network.vpn.Site2SiteVpnService; +import com.cloud.projects.Project; +import com.cloud.projects.ProjectService; +import com.cloud.resource.ResourceService; +import com.cloud.server.ManagementService; +import com.cloud.server.TaggedResourceService; +import com.cloud.storage.StorageService; +import com.cloud.storage.snapshot.SnapshotService; +import com.cloud.template.TemplateService; +import com.cloud.user.Account; +import com.cloud.user.AccountService; +import com.cloud.user.DomainService; +import com.cloud.user.ResourceLimitService; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.vm.BareMetalVmService; +import com.cloud.vm.UserVmService; + +public abstract class BaseCmd { + private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName()); + + public static final String USER_ERROR_MESSAGE = "Internal error executing command, please contact your system administrator"; + public static final int PROGRESS_INSTANCE_CREATED = 1; + + public static final String RESPONSE_TYPE_XML = "xml"; + public static final String RESPONSE_TYPE_JSON = "json"; + + public enum CommandType { + BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE + } + + // FIXME: Extract these out into a separate file + // Client error codes + public static final int MALFORMED_PARAMETER_ERROR = 430; + public static final int PARAM_ERROR = 431; + public static final int UNSUPPORTED_ACTION_ERROR = 432; + public static final int PAGE_LIMIT_EXCEED = 433; + + // Server error codes + public static final int INTERNAL_ERROR = 530; + public static final int ACCOUNT_ERROR = 531; + public static final int ACCOUNT_RESOURCE_LIMIT_ERROR = 532; + public static final int INSUFFICIENT_CAPACITY_ERROR = 533; + public static final int RESOURCE_UNAVAILABLE_ERROR = 534; + public static final int RESOURCE_ALLOCATION_ERROR = 534; + public static final int RESOURCE_IN_USE_ERROR = 536; + public static final int NETWORK_RULE_CONFLICT_ERROR = 537; + + public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+"); + private static final DateFormat _outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + + private Object _responseObject = null; + private Map fullUrlParams; + + @Parameter(name = "response", type = CommandType.STRING) + private String responseType; + + public static ComponentLocator s_locator; + public static ConfigurationService _configService; + public static AccountService _accountService; + public static UserVmService _userVmService; + public static ManagementService _mgr; + public static StorageService _storageService; + public static ResourceService _resourceService; + public static NetworkService _networkService; + public static TemplateService _templateService; + public static SecurityGroupService _securityGroupService; + public static SnapshotService _snapshotService; + public static ConsoleProxyService _consoleProxyService; + public static VirtualNetworkApplianceService _routerService; + public static ResponseGenerator _responseGenerator; + public static EntityManager _entityMgr; + public static RulesService _rulesService; + public static LoadBalancingRulesService _lbService; + public static AutoScaleService _autoScaleService; + public static RemoteAccessVpnService _ravService; + public static BareMetalVmService _bareMetalVmService; + public static ProjectService _projectService; + public static FirewallService _firewallService; + public static DomainService _domainService; + public static ResourceLimitService _resourceLimitService; + public static IdentityService _identityService; + public static StorageNetworkService _storageNetworkService; + public static TaggedResourceService _taggedResourceService; + public static VpcService _vpcService; + public static NetworkACLService _networkACLService; + public static Site2SiteVpnService _s2sVpnService; + + static void setComponents(ResponseGenerator generator) { + ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); + _mgr = (ManagementService) ComponentLocator.getComponent(ManagementService.Name); + _accountService = locator.getManager(AccountService.class); + _configService = locator.getManager(ConfigurationService.class); + _userVmService = locator.getManager(UserVmService.class); + _storageService = locator.getManager(StorageService.class); + _resourceService = locator.getManager(ResourceService.class); + _networkService = locator.getManager(NetworkService.class); + _templateService = locator.getManager(TemplateService.class); + _securityGroupService = locator.getManager(SecurityGroupService.class); + _snapshotService = locator.getManager(SnapshotService.class); + _consoleProxyService = locator.getManager(ConsoleProxyService.class); + _routerService = locator.getManager(VirtualNetworkApplianceService.class); + _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); + _projectService = locator.getManager(ProjectService.class); + _firewallService = locator.getManager(FirewallService.class); + _domainService = locator.getManager(DomainService.class); + _resourceLimitService = locator.getManager(ResourceLimitService.class); + _identityService = locator.getManager(IdentityService.class); + _storageNetworkService = locator.getManager(StorageNetworkService.class); + _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcService = locator.getManager(VpcService.class); + _networkACLService = locator.getManager(NetworkACLService.class); + _s2sVpnService = locator.getManager(Site2SiteVpnService.class); + } + + public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException; + + public String getResponseType() { + if (responseType == null) { + return RESPONSE_TYPE_XML; + } + return responseType; + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public abstract String getCommandName(); + + /** + * For commands the API framework needs to know the owner of the object being acted upon. This method is + * used to determine that information. + * + * @return the id of the account that owns the object being acted upon + */ + public abstract long getEntityOwnerId(); + + public Object getResponseObject() { + return _responseObject; + } + + public void setResponseObject(Object responseObject) { + _responseObject = responseObject; + } + + public ManagementService getMgmtServiceRef() { + return _mgr; + } + + public static String getDateString(Date date) { + if (date == null) { + return ""; + } + String formattedString = null; + synchronized (_outputFormat) { + formattedString = _outputFormat.format(date); + } + return formattedString; + } + + // FIXME: move this to a utils method so that maps can be unpacked and integer/long values can be appropriately cast + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Map unpackParams(Map params) { + Map lowercaseParams = new HashMap(); + for (String key : params.keySet()) { + int arrayStartIndex = key.indexOf('['); + int arrayStartLastIndex = key.lastIndexOf('['); + if (arrayStartIndex != arrayStartLastIndex) { + throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); + } + + if (arrayStartIndex > 0) { + int arrayEndIndex = key.indexOf(']'); + int arrayEndLastIndex = key.lastIndexOf(']'); + if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) { + // malformed parameter + throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); + } + + // Now that we have an array object, check for a field name in the case of a complex object + int fieldIndex = key.indexOf('.'); + String fieldName = null; + if (fieldIndex < arrayEndIndex) { + throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); + } else { + fieldName = key.substring(fieldIndex + 1); + } + + // parse the parameter name as the text before the first '[' character + String paramName = key.substring(0, arrayStartIndex); + paramName = paramName.toLowerCase(); + + Map mapArray = null; + Map mapValue = null; + String indexStr = key.substring(arrayStartIndex + 1, arrayEndIndex); + int index = 0; + boolean parsedIndex = false; + try { + if (indexStr != null) { + index = Integer.parseInt(indexStr); + parsedIndex = true; + } + } catch (NumberFormatException nfe) { + s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error."); + } + + if (!parsedIndex) { + throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup"); + } + + Object value = lowercaseParams.get(paramName); + if (value == null) { + // for now, assume object array with sub fields + mapArray = new HashMap(); + mapValue = new HashMap(); + mapArray.put(Integer.valueOf(index), mapValue); + } else if (value instanceof Map) { + mapArray = (HashMap) value; + mapValue = mapArray.get(Integer.valueOf(index)); + if (mapValue == null) { + mapValue = new HashMap(); + mapArray.put(Integer.valueOf(index), mapValue); + } + } + + // we are ready to store the value for a particular field into the map for this object + mapValue.put(fieldName, params.get(key)); + + lowercaseParams.put(paramName, mapArray); + } else { + lowercaseParams.put(key.toLowerCase(), params.get(key)); + } + } + return lowercaseParams; + } + + public String buildResponse(ServerApiException apiException, String responseType) { + StringBuffer sb = new StringBuffer(); + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + // JSON response + sb.append("{ \"" + getCommandName() + "\" : { " + "\"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},"); + sb.append("\"errorcode\" : \"" + apiException.getErrorCode() + "\", \"description\" : \"" + apiException.getDescription() + "\" } }"); + } else { + sb.append(""); + sb.append("<" + getCommandName() + ">"); + sb.append("" + apiException.getErrorCode() + ""); + sb.append("" + escapeXml(apiException.getDescription()) + ""); + sb.append(""); + } + return sb.toString(); + } + + public String buildResponse(List> tagList, String responseType) { + StringBuffer prefixSb = new StringBuffer(); + StringBuffer suffixSb = new StringBuffer(); + + // set up the return value with the name of the response + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + prefixSb.append("{ \"" + getCommandName() + "\" : { \"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},"); + } else { + prefixSb.append(""); + prefixSb.append("<" + getCommandName() + " cloud-stack-version=\"" + _mgr.getVersion() + "\">"); + } + + int i = 0; + for (Pair tagData : tagList) { + String tagName = tagData.first(); + Object tagValue = tagData.second(); + if (tagValue instanceof Object[]) { + Object[] subObjects = (Object[]) tagValue; + if (subObjects.length < 1) { + continue; + } + writeObjectArray(responseType, suffixSb, i++, tagName, subObjects); + } else { + writeNameValuePair(suffixSb, tagName, tagValue, responseType, i++); + } + } + + 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. + prefixSb.append(","); + } + prefixSb.append(suffixSb); + } + // close the response + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + prefixSb.append("} }"); + } else { + prefixSb.append(""); + } + return prefixSb.toString(); + } + + private void writeNameValuePair(StringBuffer sb, String tagName, Object tagValue, String responseType, int propertyCount) { + if (tagValue == null) { + return; + } + + if (tagValue instanceof Object[]) { + Object[] subObjects = (Object[]) tagValue; + if (subObjects.length < 1) { + return; + } + writeObjectArray(responseType, sb, propertyCount, tagName, subObjects); + } else { + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + String seperator = ((propertyCount > 0) ? ", " : ""); + sb.append(seperator + "\"" + tagName + "\" : \"" + escapeJSON(tagValue.toString()) + "\""); + } else { + sb.append("<" + tagName + ">" + escapeXml(tagValue.toString()) + ""); + } + } + } + + @SuppressWarnings("rawtypes") + private void writeObjectArray(String responseType, StringBuffer sb, int propertyCount, String tagName, Object[] subObjects) { + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + String separator = ((propertyCount > 0) ? ", " : ""); + sb.append(separator); + } + int j = 0; + for (Object subObject : subObjects) { + if (subObject instanceof List) { + List subObjList = (List) subObject; + writeSubObject(sb, tagName, subObjList, responseType, j++); + } + } + + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + sb.append("]"); + } + } + + @SuppressWarnings("rawtypes") + private void writeSubObject(StringBuffer sb, String tagName, List tagList, String responseType, int objectCount) { + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + sb.append(((objectCount == 0) ? "\"" + tagName + "\" : [ { " : ", { ")); + } else { + sb.append("<" + tagName + ">"); + } + + int i = 0; + for (Object tag : tagList) { + if (tag instanceof Pair) { + Pair nameValuePair = (Pair) tag; + writeNameValuePair(sb, (String) nameValuePair.first(), nameValuePair.second(), responseType, i++); + } + } + + if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + sb.append("}"); + } else { + sb.append(""); + } + } + + /** + * Escape xml response set to false by default. API commands to override this method to allow escaping + */ + public boolean requireXmlEscape() { + return true; + } + + private String escapeXml(String xml) { + if (!requireXmlEscape()) { + return xml; + } + int iLen = xml.length(); + if (iLen == 0) { + return xml; + } + StringBuffer sOUT = new StringBuffer(iLen + 256); + int i = 0; + for (; i < iLen; i++) { + char c = xml.charAt(i); + if (c == '<') { + sOUT.append("<"); + } else if (c == '>') { + sOUT.append(">"); + } else if (c == '&') { + sOUT.append("&"); + } else if (c == '"') { + sOUT.append("""); + } else if (c == '\'') { + sOUT.append("'"); + } else { + sOUT.append(c); + } + } + return sOUT.toString(); + } + + private static String escapeJSON(String str) { + if (str == null) { + return str; + } + + return str.replace("\"", "\\\""); + } + + protected long getInstanceIdFromJobSuccessResult(String result) { + s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName()); + return 0; + } + + public static boolean isAdmin(short accountType) { + return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || + (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || + (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); + } + + public static boolean isRootAdmin(short accountType) { + return ((accountType == Account.ACCOUNT_TYPE_ADMIN)); + } + + public void setFullUrlParams(Map map) { + this.fullUrlParams = map; + } + + public Map getFullUrlParams() { + return this.fullUrlParams; + } + + public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { + if (accountName != null) { + if (domainId == null) { + throw new InvalidParameterValueException("Account must be specified with domainId parameter", null); + } + + Domain domain = _domainService.getDomain(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find domain by id", null); + } + + Account account = _accountService.getActiveAccountByName(accountName, domainId); + if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) { + 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"); + } + } else { + List idList = new ArrayList(); + idList.add(new IdentityProxy("domain", domainId, "domainId")); + throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id", idList); + } + } + + if (projectId != null) { + Project project = _projectService.getProject(projectId); + if (project != null) { + 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"); + throw ex; + } + } else { + throw new InvalidParameterValueException("Unable to find project by id", null); + } + } + return null; + } +} diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index ce1245b3947..d65d155433e 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -1,339 +1,360 @@ -// 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.api; - -import java.text.DecimalFormat; -import java.util.EnumSet; -import java.util.List; - -import com.cloud.api.ApiConstants.HostDetails; -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.CapacityResponse; -import com.cloud.api.response.ClusterResponse; -import com.cloud.api.response.ConfigurationResponse; -import com.cloud.api.response.CreateCmdResponse; -import com.cloud.api.response.DiskOfferingResponse; -import com.cloud.api.response.DomainResponse; -import com.cloud.api.response.DomainRouterResponse; -import com.cloud.api.response.EventResponse; -import com.cloud.api.response.ExtractResponse; -import com.cloud.api.response.FirewallResponse; -import com.cloud.api.response.FirewallRuleResponse; -import com.cloud.api.response.HostResponse; -import com.cloud.api.response.HypervisorCapabilitiesResponse; -import com.cloud.api.response.IPAddressResponse; -import com.cloud.api.response.InstanceGroupResponse; -import com.cloud.api.response.IpForwardingRuleResponse; -import com.cloud.api.response.LBStickinessResponse; -import com.cloud.api.response.LDAPConfigResponse; -import com.cloud.api.response.ListResponse; -import com.cloud.api.response.LoadBalancerResponse; -import com.cloud.api.response.NetworkACLResponse; -import com.cloud.api.response.NetworkOfferingResponse; -import com.cloud.api.response.NetworkResponse; -import com.cloud.api.response.PhysicalNetworkResponse; -import com.cloud.api.response.PodResponse; -import com.cloud.api.response.PrivateGatewayResponse; -import com.cloud.api.response.ProjectAccountResponse; -import com.cloud.api.response.ProjectInvitationResponse; -import com.cloud.api.response.ProjectResponse; -import com.cloud.api.response.ProviderResponse; -import com.cloud.api.response.RemoteAccessVpnResponse; -import com.cloud.api.response.ResourceCountResponse; -import com.cloud.api.response.ResourceLimitResponse; -import com.cloud.api.response.ResourceTagResponse; -import com.cloud.api.response.SecurityGroupResponse; -import com.cloud.api.response.ServiceOfferingResponse; -import com.cloud.api.response.ServiceResponse; -import com.cloud.api.response.Site2SiteCustomerGatewayResponse; -import com.cloud.api.response.Site2SiteVpnConnectionResponse; -import com.cloud.api.response.Site2SiteVpnGatewayResponse; -import com.cloud.api.response.SnapshotPolicyResponse; -import com.cloud.api.response.SnapshotResponse; -import com.cloud.api.response.StaticRouteResponse; -import com.cloud.api.response.StorageNetworkIpRangeResponse; -import com.cloud.api.response.StoragePoolResponse; -import com.cloud.api.response.SwiftResponse; -import com.cloud.api.response.SystemVmInstanceResponse; -import com.cloud.api.response.SystemVmResponse; -import com.cloud.api.response.TemplatePermissionsResponse; -import com.cloud.api.response.TemplateResponse; -import com.cloud.api.response.TrafficTypeResponse; -import com.cloud.api.response.UserResponse; -import com.cloud.api.response.UserVmResponse; -import com.cloud.api.response.VirtualRouterProviderResponse; -import com.cloud.api.response.VlanIpRangeResponse; -import com.cloud.api.response.VolumeResponse; -import com.cloud.api.response.VpcOfferingResponse; -import com.cloud.api.response.VpcResponse; -import com.cloud.api.response.VpnUsersResponse; -import com.cloud.api.response.ZoneResponse; -import com.cloud.async.AsyncJob; -import com.cloud.capacity.Capacity; -import com.cloud.configuration.Configuration; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit; -import com.cloud.dc.DataCenter; -import com.cloud.dc.Pod; -import com.cloud.dc.StorageNetworkIpRange; -import com.cloud.dc.Vlan; -import com.cloud.domain.Domain; -import com.cloud.event.Event; -import com.cloud.host.Host; -import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; -import com.cloud.network.Network.Service; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StickinessPolicy; -import com.cloud.network.security.SecurityGroup; -import com.cloud.network.security.SecurityGroupRules; -import com.cloud.network.security.SecurityRule; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.StaticRoute; -import com.cloud.network.vpc.Vpc; -import com.cloud.network.vpc.VpcOffering; -import com.cloud.offering.DiskOffering; -import com.cloud.offering.NetworkOffering; -import com.cloud.offering.ServiceOffering; -import com.cloud.org.Cluster; -import com.cloud.projects.Project; -import com.cloud.projects.ProjectAccount; -import com.cloud.projects.ProjectInvitation; -import com.cloud.server.ResourceTag; -import com.cloud.storage.Snapshot; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Swift; -import com.cloud.storage.Volume; -import com.cloud.storage.snapshot.SnapshotPolicy; -import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.Account; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.uservm.UserVm; -import com.cloud.vm.InstanceGroup; -import com.cloud.vm.VirtualMachine; - -public interface ResponseGenerator { - UserResponse createUserResponse(UserAccount user); - - AccountResponse createAccountResponse(Account account); - - DomainResponse createDomainResponse(Domain domain); - - DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering); - - ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit); - - ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount); - - ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering); - - ConfigurationResponse createConfigurationResponse(Configuration cfg); - - SnapshotResponse createSnapshotResponse(Snapshot snapshot); - - SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy); - - List createUserVmResponse(String objectName, UserVm... userVms); - - List createUserVmResponse(String objectName, EnumSet details, UserVm... userVms); - - SystemVmResponse createSystemVmResponse(VirtualMachine systemVM); - - DomainRouterResponse createDomainRouterResponse(VirtualRouter router); - - HostResponse createHostResponse(Host host, EnumSet details); - - HostResponse createHostResponse(Host host); - - VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan); - - IPAddressResponse createIPAddressResponse(IpAddress ipAddress); - - LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer); - - LBStickinessResponse createLBStickinessPolicyResponse(List stickinessPolicies, LoadBalancer lb); - - LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb); - - PodResponse createPodResponse(Pod pod, Boolean showCapacities); - - ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities); - - VolumeResponse createVolumeResponse(Volume volume); - - InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group); - - StoragePoolResponse createStoragePoolResponse(StoragePool pool); - - ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities); - - FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule); - - IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule); - - User findUserById(Long userId); - - UserVm findUserVmById(Long vmId); - - Volume findVolumeById(Long volumeId); - - Account findAccountByNameDomain(String accountName, Long domainId); - - VirtualMachineTemplate findTemplateById(Long templateId); - - Host findHostById(Long hostId); - - List createTemplateResponses(long templateId, long zoneId, boolean readyOnly); - - VpnUsersResponse createVpnUserResponse(VpnUser user); - - RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn); - - List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly); - - List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly); - - ListResponse createSecurityGroupResponses(List networkGroups); - - SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List SecurityRules); - - SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group); - - ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode); - - String toSerializedString(CreateCmdResponse response, String responseType); - - AsyncJobResponse createAsyncJobResponse(AsyncJob job); - - EventResponse createEventResponse(Event event); - - TemplateResponse createIsoResponse(VirtualMachineTemplate result); - - List createCapacityResponse(List result, DecimalFormat format); - - TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin); - - AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd); - - NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering); - - NetworkResponse createNetworkResponse(Network network); - - UserResponse createUserResponse(User user); - - AccountResponse createUserAccountResponse(UserAccount user); - - Long getSecurityGroupId(String groupName, long accountId); - - List createIsoResponses(long isoId, Long zoneId, boolean readyOnly); - - ProjectResponse createProjectResponse(Project project); - - List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly); - - List createTemplateResponses(long templateId, Long vmId); - - FirewallResponse createFirewallResponse(FirewallRule fwRule); - - HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities); - - ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount); - - ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite); - - SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine systemVM); - - SwiftResponse createSwiftResponse(Swift swift); - - PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result); - - ServiceResponse createNetworkServiceResponse(Service service); - - ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result); - - TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result); - - VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result); - - LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String baseSearch, String dn); - - StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result); - - /** - * @param tableName TODO - * @param token - * @return - */ - Long getIdentiyId(String tableName, String token); - - /** - * @param resourceTag - * @param keyValueOnly TODO - * @return - */ - ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly); - - Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result); - - /** - * @param offering - * @return - */ - VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering); - - /** - * @param vpc - * @return - */ - VpcResponse createVpcResponse(Vpc vpc); - - /** - * @param networkACL - * @return - */ - NetworkACLResponse createNetworkACLResponse(FirewallRule networkACL); - - /** - * @param result - * @return - */ - PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result); - - /** - * @param result - * @return - */ - StaticRouteResponse createStaticRouteResponse(StaticRoute result); - - Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result); - - Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result); -} +// 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.api; + +import java.text.DecimalFormat; +import java.util.EnumSet; +import java.util.List; + +import com.cloud.api.ApiConstants.HostDetails; +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.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; +import com.cloud.api.response.DomainRouterResponse; +import com.cloud.api.response.EventResponse; +import com.cloud.api.response.ExtractResponse; +import com.cloud.api.response.FirewallResponse; +import com.cloud.api.response.FirewallRuleResponse; +import com.cloud.api.response.HostResponse; +import com.cloud.api.response.HypervisorCapabilitiesResponse; +import com.cloud.api.response.IPAddressResponse; +import com.cloud.api.response.InstanceGroupResponse; +import com.cloud.api.response.IpForwardingRuleResponse; +import com.cloud.api.response.LBStickinessResponse; +import com.cloud.api.response.AutoScaleVmProfileResponse; +import com.cloud.api.response.LDAPConfigResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.LoadBalancerResponse; +import com.cloud.api.response.NetworkACLResponse; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.api.response.NetworkResponse; +import com.cloud.api.response.PhysicalNetworkResponse; +import com.cloud.api.response.PodResponse; +import com.cloud.api.response.PrivateGatewayResponse; +import com.cloud.api.response.ProjectAccountResponse; +import com.cloud.api.response.ProjectInvitationResponse; +import com.cloud.api.response.ProjectResponse; +import com.cloud.api.response.ProviderResponse; +import com.cloud.api.response.RemoteAccessVpnResponse; +import com.cloud.api.response.ResourceCountResponse; +import com.cloud.api.response.ResourceLimitResponse; +import com.cloud.api.response.ResourceTagResponse; +import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.api.response.ServiceOfferingResponse; +import com.cloud.api.response.ServiceResponse; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; +import com.cloud.api.response.SnapshotPolicyResponse; +import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; +import com.cloud.api.response.StorageNetworkIpRangeResponse; +import com.cloud.api.response.StoragePoolResponse; +import com.cloud.api.response.SwiftResponse; +import com.cloud.api.response.SystemVmInstanceResponse; +import com.cloud.api.response.SystemVmResponse; +import com.cloud.api.response.TemplatePermissionsResponse; +import com.cloud.api.response.TemplateResponse; +import com.cloud.api.response.TrafficTypeResponse; +import com.cloud.api.response.UserResponse; +import com.cloud.api.response.UserVmResponse; +import com.cloud.api.response.VirtualRouterProviderResponse; +import com.cloud.api.response.VlanIpRangeResponse; +import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; +import com.cloud.api.response.VpnUsersResponse; +import com.cloud.api.response.ZoneResponse; +import com.cloud.async.AsyncJob; +import com.cloud.capacity.Capacity; +import com.cloud.configuration.Configuration; +import com.cloud.configuration.ResourceCount; +import com.cloud.configuration.ResourceLimit; +import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; +import com.cloud.dc.StorageNetworkIpRange; +import com.cloud.dc.Vlan; +import com.cloud.domain.Domain; +import com.cloud.event.Event; +import com.cloud.host.Host; +import com.cloud.hypervisor.HypervisorCapabilities; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Service; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkTrafficType; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +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.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; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.security.SecurityGroup; +import com.cloud.network.security.SecurityGroupRules; +import com.cloud.network.security.SecurityRule; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.org.Cluster; +import com.cloud.projects.Project; +import com.cloud.projects.ProjectAccount; +import com.cloud.projects.ProjectInvitation; +import com.cloud.server.ResourceTag; +import com.cloud.storage.Snapshot; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Swift; +import com.cloud.storage.Volume; +import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.uservm.UserVm; +import com.cloud.vm.InstanceGroup; +import com.cloud.vm.VirtualMachine; + +public interface ResponseGenerator { + UserResponse createUserResponse(UserAccount user); + + AccountResponse createAccountResponse(Account account); + + DomainResponse createDomainResponse(Domain domain); + + DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering); + + ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit); + + ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount); + + ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering); + + ConfigurationResponse createConfigurationResponse(Configuration cfg); + + SnapshotResponse createSnapshotResponse(Snapshot snapshot); + + SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy); + + List createUserVmResponse(String objectName, UserVm... userVms); + + List createUserVmResponse(String objectName, EnumSet details, UserVm... userVms); + + SystemVmResponse createSystemVmResponse(VirtualMachine systemVM); + + DomainRouterResponse createDomainRouterResponse(VirtualRouter router); + + HostResponse createHostResponse(Host host, EnumSet details); + + HostResponse createHostResponse(Host host); + + VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan); + + IPAddressResponse createIPAddressResponse(IpAddress ipAddress); + + LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer); + + LBStickinessResponse createLBStickinessPolicyResponse(List stickinessPolicies, LoadBalancer lb); + + LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb); + + PodResponse createPodResponse(Pod pod, Boolean showCapacities); + + ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities); + + VolumeResponse createVolumeResponse(Volume volume); + + InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group); + + StoragePoolResponse createStoragePoolResponse(StoragePool pool); + + ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities); + + FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule); + + IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule); + + User findUserById(Long userId); + + UserVm findUserVmById(Long vmId); + + Volume findVolumeById(Long volumeId); + + Account findAccountByNameDomain(String accountName, Long domainId); + + VirtualMachineTemplate findTemplateById(Long templateId); + + Host findHostById(Long hostId); + + List createTemplateResponses(long templateId, long zoneId, boolean readyOnly); + + VpnUsersResponse createVpnUserResponse(VpnUser user); + + RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn); + + List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly); + + List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly); + + ListResponse createSecurityGroupResponses(List networkGroups); + + SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List SecurityRules); + + SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group); + + ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode); + + String toSerializedString(CreateCmdResponse response, String responseType); + + AsyncJobResponse createAsyncJobResponse(AsyncJob job); + + EventResponse createEventResponse(Event event); + + TemplateResponse createIsoResponse(VirtualMachineTemplate result); + + List createCapacityResponse(List result, DecimalFormat format); + + TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin); + + AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd); + + NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering); + + NetworkResponse createNetworkResponse(Network network); + + UserResponse createUserResponse(User user); + + AccountResponse createUserAccountResponse(UserAccount user); + + Long getSecurityGroupId(String groupName, long accountId); + + List createIsoResponses(long isoId, Long zoneId, boolean readyOnly); + + ProjectResponse createProjectResponse(Project project); + + List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly); + + List createTemplateResponses(long templateId, Long vmId); + + FirewallResponse createFirewallResponse(FirewallRule fwRule); + + HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities); + + ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount); + + ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite); + + SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine systemVM); + + SwiftResponse createSwiftResponse(Swift swift); + + PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result); + + ServiceResponse createNetworkServiceResponse(Service service); + + ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result); + + TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result); + + VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result); + + LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String baseSearch, String dn); + + StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result); + + /** + * @param tableName + * TODO + * @param token + * @return + */ + Long getIdentiyId(String tableName, String token); + + /** + * @param resourceTag + * @param keyValueOnly TODO + * @return + */ + ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly); + + Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result); + + /** + * @param offering + * @return + */ + VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering); + + /** + * @param vpc + * @return + */ + VpcResponse createVpcResponse(Vpc vpc); + + /** + * @param networkACL + * @return + */ + NetworkACLResponse createNetworkACLResponse(FirewallRule networkACL); + + /** + * @param result + * @return + */ + PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result); + + /** + * @param result + * @return + */ + StaticRouteResponse createStaticRouteResponse(StaticRoute result); + + 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..ade3751eae2 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScalePolicyCmd.java @@ -0,0 +1,156 @@ +// 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. +// +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.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.Condition; + +@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.DURATION, type = CommandType.INTEGER, required = true, 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; + + @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 = "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 Integer 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); + 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() { + } + + @Override + public void create() throws ResourceAllocationException { + AutoScalePolicy result = _autoScaleService.createAutoScalePolicy(this); + if (result != null) { + this.setEntityId(result.getId()); + AutoScalePolicyResponse response = _responseGenerator.createAutoScalePolicyResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } 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..f30569589ba --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScaleVmGroupCmd.java @@ -0,0 +1,193 @@ +// 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.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 provision 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 de-provision 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_vm_groups"; + } + + 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 from lbRuleId=" + getLbRuleId()); + } + 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()); + AutoScaleVmGroupResponse response = _responseGenerator.createAutoScaleVmGroupResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } 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 = true; // Temporary, till we call configure. + // success = _lbService.configureAutoScaleVmGroup(this); + 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) { + 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..0350d017daf --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java @@ -0,0 +1,256 @@ +// 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.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.dc.DataCenter; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.offering.ServiceOffering; +import com.cloud.template.VirtualMachineTemplate; +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, required = true, 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() { + } + + @Override + public void create() throws ResourceAllocationException { + + DataCenter zone = _configService.getZone(zoneId); + if (zone == null) { + throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId); + } + + ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId); + if (serviceOffering == null) { + throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId); + } + + VirtualMachineTemplate template = _templateService.getTemplate(templateId); + // Make sure a valid template ID was specified + if (template == null) { + throw new InvalidParameterValueException("Unable to use template " + templateId); + } + + AutoScaleVmProfile result = _autoScaleService.createAutoScaleVmProfile(this); + if (result != null) { + this.setEntityId(result.getId()); + AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } 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..8ea3feaf74b --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateConditionCmd.java @@ -0,0 +1,144 @@ +// 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()); + ConditionResponse response = _responseGenerator.createConditionResponse(condition); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create condition."); + } + } + + @Override + public void execute() { + } + + // ///////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public Long getCounterId() { + return counterId; + } + + public String getRelationalOperator() { + return relationalOperator; + } + + public String getAccountName() { + return accountName; + } + + public Long 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..ec6e151347b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScalePolicyCmd.java @@ -0,0 +1,100 @@ +// 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.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()); + s_logger.info("Successfully deleted autoscale policy id : " + getId()); + 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..0d5ca9f1fda --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScaleVmGroupCmd.java @@ -0,0 +1,100 @@ +// 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.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()); + s_logger.info("Successfully deleted autoscale vm group id : " + getId()); + 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..bb0c6d82aa9 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScaleVmProfileCmd.java @@ -0,0 +1,99 @@ +// 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.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()); + s_logger.info("Successfully deleted autoscale vm profile id : " + getId()); + 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..da0c7defe0b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteConditionCmd.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.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()); + s_logger.info("Successfully deleted condition id : " + getId()); + 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..d2e95dcb252 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteCounterCmd.java @@ -0,0 +1,104 @@ +// 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()); + s_logger.info("Successfully deleted counter id : " + getId()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete counter"); + 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..02bbad3b3ee --- /dev/null +++ b/api/src/com/cloud/api/commands/DisableAutoScaleVmGroupCmd.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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +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.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; + +@Implementation(description = "Disables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class) +public class DisableAutoScaleVmGroupCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(DisableAutoScaleVmGroupCmd.class.getName()); + private static final String s_name = "disableautoscalevmGroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "account") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "Account id") + 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 + } + +} 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..6ee6bb5a96e --- /dev/null +++ b/api/src/com/cloud/api/commands/EnableAutoScaleVmGroupCmd.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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +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.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; + +@Implementation(description = "Enables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class) +public class EnableAutoScaleVmGroupCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(EnableAutoScaleVmGroupCmd.class.getName()); + private static final String s_name = "enableautoscalevmGroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "account") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "Account id") + 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 + } + +} 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..69a9a026087 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScalePoliciesCmd.java @@ -0,0 +1,85 @@ +// 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.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; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getConditionId() { + return conditionId; + } + + // /////////////////////////////////////////////////// + // ///////////// 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..8103dedabab --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScaleVmGroupsCmd.java @@ -0,0 +1,111 @@ +// 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.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..0d8940f28ce --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScaleVmProfilesCmd.java @@ -0,0 +1,91 @@ +// 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.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..57a21b4774b --- /dev/null +++ b/api/src/com/cloud/api/commands/ListConditionsCmd.java @@ -0,0 +1,88 @@ +// 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; + + @Parameter(name = ApiConstants.COUNTER_ID, type = CommandType.LONG, required = false, description = "Counter-id of the condition.") + private Long counterId; + + // /////////////////////////////////////////////////// + // ///////////// 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; + } + + @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..eacd9a9624c --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScalePolicyCmd.java @@ -0,0 +1,98 @@ +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.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 = "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() throws ServerApiException { + 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; + } + + @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."; + } + + @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..4747959f89a --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScaleVmGroupCmd.java @@ -0,0 +1,137 @@ +// 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, 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; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEUP_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, description = "list of provision autoscale policies") + private List scaleUpPolicyIds; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEDOWN_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, description = "list of de-provision 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() throws ServerApiException { + 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 int getMinMembers() { + return minMembers; + } + + public int getMaxMembers() { + return maxMembers; + } + + public List getScaleUpPolicyIds() { + return scaleUpPolicyIds; + } + + public List getScaleDownPolicyIds() { + return scaleDownPolicyIds; + } + + @Override + public String getEventType() { + return "Update AutoScale Vm Group"; + } + + @Override + public String getEventDescription() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE; + } + + @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..3947fbb8e31 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java @@ -0,0 +1,119 @@ +// 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_vmgroups") + @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, 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; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() throws ServerApiException { + 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 String getOtherDeployParams() { + return otherDeployParams; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating AutoScale Vm Profile"; + } + + @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..b96383b52d7 --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScalePolicyResponse.java @@ -0,0 +1,123 @@ +// 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.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.ZONE_ID) + @Param(description = "the availability zone of the autoscale policy") + private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @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.INTERVAL) + @Param(description = "the frequency at which the conditions have to be evaluated") + private Integer interval; + + @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 setZoneId(IdentityProxy zoneId) { + this.zoneId = zoneId; + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + + public void setInterval(Integer interval) { + this.interval = interval; + } + + public void setQuietTime(Integer quietTime) { + this.quietTime = quietTime; + } + + public void setAction(String action) { + this.action = action; + } + + public void setConditions(List conditions) { + this.conditions = conditions; + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + @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..32fc5801f18 --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScaleVmGroupResponse.java @@ -0,0 +1,132 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.network.as.AutoScalePolicy; +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_groups"); + + @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.DURATION) + @Param(description = "the duration for which the conditions have to be true before action is taken") + private Integer minMembers; + + @SerializedName(ApiConstants.INTERVAL) + @Param(description = "the frequency at which the conditions have to be evaluated") + private Integer maxMembers; + + @SerializedName(ApiConstants.INTERVAL) + @Param(description = "the frequency at which the conditions have to be evaluated") + private Integer interval; + + @SerializedName(ApiConstants.SCALEUP_POLICY_IDS) + @Param(description = "list of provision autoscale policies") + private List scaleUpPolicies; + + @SerializedName(ApiConstants.SCALEDOWN_POLICY_IDS) + @Param(description = "list of de-provision 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(Integer minMembers) { + this.minMembers = minMembers; + } + + public void setMaxMembers(Integer maxMembers) { + this.maxMembers = maxMembers; + } + + public void setInterval(Integer 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..c749d28782b --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java @@ -0,0 +1,145 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +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; + + @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; + + /* 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"); + + 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; + } +} 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..0007a65e01f --- /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(value = ApiConstants.COUNTER_ID) + @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 32fa9ac38b2..45074daf546 100644 --- a/api/src/com/cloud/async/AsyncJob.java +++ b/api/src/com/cloud/async/AsyncJob.java @@ -1,91 +1,96 @@ -// 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.async; - -import java.util.Date; - -import com.cloud.api.Identity; - -public interface AsyncJob extends Identity { - public enum Type { - None, - VirtualMachine, - DomainRouter, - Volume, - ConsoleProxy, - Snapshot, - Template, - Iso, - SystemVm, - Host, - StoragePool, - IpAddress, - SecurityGroup, - PhysicalNetwork, - TrafficType, - PhysicalNetworkServiceProvider, - FirewallRule, - Account, - User, - PrivateGateway, - StaticRoute - } - - Long getId(); - - long getUserId(); - - long getAccountId(); - - String getCmd(); - - int getCmdVersion(); - - String getCmdInfo(); - - int getCallbackType(); - - String getCallbackAddress(); - - int getStatus(); - - int getProcessStatus(); - - int getResultCode(); - - String getResult(); - - Long getInitMsid(); - - Long getCompleteMsid(); - - Date getCreated(); - - Date getLastUpdated(); - - Date getLastPolled(); - - Date getRemoved(); - - Type getInstanceType(); - - Long getInstanceId(); - - String getSessionKey(); - - String getCmdOriginator(); - - boolean isFromPreviousSession(); - - SyncQueueItem getSyncSource(); -} +// 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.async; + +import java.util.Date; + +import com.cloud.api.Identity; + +public interface AsyncJob extends Identity { + public enum Type { + None, + VirtualMachine, + DomainRouter, + Volume, + ConsoleProxy, + Snapshot, + Template, + Iso, + SystemVm, + Host, + StoragePool, + IpAddress, + SecurityGroup, + PhysicalNetwork, + TrafficType, + PhysicalNetworkServiceProvider, + FirewallRule, + Account, + User, + PrivateGateway, + StaticRoute, + Counter, + Condition, + AutoScalePolicy, + AutoScaleVmProfile, + AutoScaleVmGroup + } + + Long getId(); + + long getUserId(); + + long getAccountId(); + + String getCmd(); + + int getCmdVersion(); + + String getCmdInfo(); + + int getCallbackType(); + + String getCallbackAddress(); + + int getStatus(); + + int getProcessStatus(); + + int getResultCode(); + + String getResult(); + + Long getInitMsid(); + + Long getCompleteMsid(); + + Date getCreated(); + + Date getLastUpdated(); + + Date getLastPolled(); + + Date getRemoved(); + + Type getInstanceType(); + + Long getInstanceId(); + + String getSessionKey(); + + String getCmdOriginator(); + + boolean isFromPreviousSession(); + + SyncQueueItem getSyncSource(); +} diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 5516751370a..1af3e5bd8c2 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -1,289 +1,303 @@ -// 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.event; - -public class EventTypes { - // VM Events - public static final String EVENT_VM_CREATE = "VM.CREATE"; - public static final String EVENT_VM_DESTROY = "VM.DESTROY"; - public static final String EVENT_VM_START = "VM.START"; - public static final String EVENT_VM_STOP = "VM.STOP"; - public static final String EVENT_VM_REBOOT = "VM.REBOOT"; - public static final String EVENT_VM_UPDATE = "VM.UPDATE"; - public static final String EVENT_VM_UPGRADE = "VM.UPGRADE"; - public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD"; - public static final String EVENT_VM_MIGRATE = "VM.MIGRATE"; - public static final String EVENT_VM_MOVE = "VM.MOVE"; - public static final String EVENT_VM_RESTORE = "VM.RESTORE"; - - // Domain Router - public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE"; - public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY"; - public static final String EVENT_ROUTER_START = "ROUTER.START"; - public static final String EVENT_ROUTER_STOP = "ROUTER.STOP"; - public static final String EVENT_ROUTER_REBOOT = "ROUTER.REBOOT"; - public static final String EVENT_ROUTER_HA = "ROUTER.HA"; - public static final String EVENT_ROUTER_UPGRADE = "ROUTER.UPGRADE"; - - // Console proxy - public static final String EVENT_PROXY_CREATE = "PROXY.CREATE"; - public static final String EVENT_PROXY_DESTROY = "PROXY.DESTROY"; - public static final String EVENT_PROXY_START = "PROXY.START"; - public static final String EVENT_PROXY_STOP = "PROXY.STOP"; - public static final String EVENT_PROXY_REBOOT = "PROXY.REBOOT"; - public static final String EVENT_PROXY_HA = "PROXY.HA"; - - // VNC Console Events - public static final String EVENT_VNC_CONNECT = "VNC.CONNECT"; - public static final String EVENT_VNC_DISCONNECT = "VNC.DISCONNECT"; - - // Network Events - public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN"; - public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE"; - public static final String EVENT_NET_RULE_ADD = "NET.RULEADD"; - public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE"; - public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY"; - public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE"; - public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE"; - public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE"; - public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN"; - public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE"; - - // Load Balancers - public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE"; - public static final String EVENT_REMOVE_FROM_LOAD_BALANCER_RULE = "LB.REMOVE.FROM.RULE"; - public static final String EVENT_LOAD_BALANCER_CREATE = "LB.CREATE"; - public static final String EVENT_LOAD_BALANCER_DELETE = "LB.DELETE"; - public static final String EVENT_LB_STICKINESSPOLICY_CREATE = "LB.STICKINESSPOLICY.CREATE"; - public static final String EVENT_LB_STICKINESSPOLICY_DELETE = "LB.STICKINESSPOLICY.DELETE"; - public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE"; - - // Account events - public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE"; - public static final String EVENT_ACCOUNT_CREATE = "ACCOUNT.CREATE"; - public static final String EVENT_ACCOUNT_DELETE = "ACCOUNT.DELETE"; - public static final String EVENT_ACCOUNT_MARK_DEFAULT_ZONE = "ACCOUNT.MARK.DEFAULT.ZONE"; - - // UserVO Events - public static final String EVENT_USER_LOGIN = "USER.LOGIN"; - public static final String EVENT_USER_LOGOUT = "USER.LOGOUT"; - public static final String EVENT_USER_CREATE = "USER.CREATE"; - public static final String EVENT_USER_DELETE = "USER.DELETE"; - public static final String EVENT_USER_DISABLE = "USER.DISABLE"; - public static final String EVENT_USER_UPDATE = "USER.UPDATE"; - public static final String EVENT_USER_ENABLE = "USER.ENABLE"; - public static final String EVENT_USER_LOCK = "USER.LOCK"; - - // Template Events - public static final String EVENT_TEMPLATE_CREATE = "TEMPLATE.CREATE"; - public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE"; - public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE"; - public static final String EVENT_TEMPLATE_DOWNLOAD_START = "TEMPLATE.DOWNLOAD.START"; - public static final String EVENT_TEMPLATE_DOWNLOAD_SUCCESS = "TEMPLATE.DOWNLOAD.SUCCESS"; - public static final String EVENT_TEMPLATE_DOWNLOAD_FAILED = "TEMPLATE.DOWNLOAD.FAILED"; - public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY"; - public static final String EVENT_TEMPLATE_EXTRACT = "TEMPLATE.EXTRACT"; - public static final String EVENT_TEMPLATE_UPLOAD = "TEMPLATE.UPLOAD"; - public static final String EVENT_TEMPLATE_CLEANUP = "TEMPLATE.CLEANUP"; - - // Volume Events - public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE"; - public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE"; - public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH"; - public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH"; - public static final String EVENT_VOLUME_EXTRACT = "VOLUME.EXTRACT"; - public static final String EVENT_VOLUME_UPLOAD = "VOLUME.UPLOAD"; - public static final String EVENT_VOLUME_MIGRATE = "VOLUME.MIGRATE"; - - // Domains - public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE"; - public static final String EVENT_DOMAIN_DELETE = "DOMAIN.DELETE"; - public static final String EVENT_DOMAIN_UPDATE = "DOMAIN.UPDATE"; - - // Snapshots - public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE"; - public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE"; - public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE"; - public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE"; - public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE"; - - // ISO - public static final String EVENT_ISO_CREATE = "ISO.CREATE"; - public static final String EVENT_ISO_DELETE = "ISO.DELETE"; - public static final String EVENT_ISO_COPY = "ISO.COPY"; - public static final String EVENT_ISO_ATTACH = "ISO.ATTACH"; - public static final String EVENT_ISO_DETACH = "ISO.DETACH"; - public static final String EVENT_ISO_EXTRACT = "ISO.EXTRACT"; - public static final String EVENT_ISO_UPLOAD = "ISO.UPLOAD"; - - // SSVM - public static final String EVENT_SSVM_CREATE = "SSVM.CREATE"; - public static final String EVENT_SSVM_DESTROY = "SSVM.DESTROY"; - public static final String EVENT_SSVM_START = "SSVM.START"; - public static final String EVENT_SSVM_STOP = "SSVM.STOP"; - public static final String EVENT_SSVM_REBOOT = "SSVM.REBOOT"; - public static final String EVENT_SSVM_HA = "SSVM.HA"; - - // Service Offerings - public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE"; - public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT"; - public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE"; - - // Disk Offerings - public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE"; - public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT"; - public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE"; - - // Network offerings - public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE"; - public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN"; - public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT"; - public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE"; - public static final String EVENT_NETWORK_OFFERING_DELETE = "NETWORK.OFFERING.DELETE"; - - // Pods - public static final String EVENT_POD_CREATE = "POD.CREATE"; - public static final String EVENT_POD_EDIT = "POD.EDIT"; - public static final String EVENT_POD_DELETE = "POD.DELETE"; - - // Zones - public static final String EVENT_ZONE_CREATE = "ZONE.CREATE"; - public static final String EVENT_ZONE_EDIT = "ZONE.EDIT"; - public static final String EVENT_ZONE_DELETE = "ZONE.DELETE"; - - // VLANs/IP ranges - public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE"; - public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE"; - - public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE"; - public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE"; - public static final String EVENT_STORAGE_IP_RANGE_UPDATE = "STORAGE.IP.RANGE.UPDATE"; - - // Configuration Table - public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT"; - - // Security Groups - public static final String EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS = "SG.AUTH.INGRESS"; - public static final String EVENT_SECURITY_GROUP_REVOKE_INGRESS = "SG.REVOKE.INGRESS"; - public static final String EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS = "SG.AUTH.EGRESS"; - public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS"; - public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE"; - public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE"; - public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN"; - public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE"; - - // Host - public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT"; - - // Maintenance - public static final String EVENT_MAINTENANCE_CANCEL = "MAINT.CANCEL"; - public static final String EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE = "MAINT.CANCEL.PS"; - public static final String EVENT_MAINTENANCE_PREPARE = "MAINT.PREPARE"; - public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS"; - - // VPN - public static final String EVENT_REMOTE_ACCESS_VPN_CREATE = "VPN.REMOTE.ACCESS.CREATE"; - public static final String EVENT_REMOTE_ACCESS_VPN_DESTROY = "VPN.REMOTE.ACCESS.DESTROY"; - public static final String EVENT_VPN_USER_ADD = "VPN.USER.ADD"; - public static final String EVENT_VPN_USER_REMOVE = "VPN.USER.REMOVE"; - public static final String EVENT_S2S_VPN_GATEWAY_CREATE = "VPN.S2S.VPN.GATEWAY.CREATE"; - public static final String EVENT_S2S_VPN_GATEWAY_DELETE = "VPN.S2S.VPN.GATEWAY.DELETE"; - public static final String EVENT_S2S_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE"; - public static final String EVENT_S2S_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE"; - public static final String EVENT_S2S_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE"; - public static final String EVENT_S2S_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE"; - public static final String EVENT_S2S_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE"; - public static final String EVENT_S2S_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET"; - - // Network - public static final String EVENT_NETWORK_RESTART = "NETWORK.RESTART"; - - // Custom certificates - public static final String EVENT_UPLOAD_CUSTOM_CERTIFICATE = "UPLOAD.CUSTOM.CERTIFICATE"; - - // OneToOnenat - public static final String EVENT_ENABLE_STATIC_NAT = "STATICNAT.ENABLE"; - public static final String EVENT_DISABLE_STATIC_NAT = "STATICNAT.DISABLE"; - - public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN"; - public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE"; - - // Projects - public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE"; - public static final String EVENT_PROJECT_UPDATE = "PROJECT.UPDATE"; - public static final String EVENT_PROJECT_DELETE = "PROJECT.DELETE"; - public static final String EVENT_PROJECT_ACTIVATE = "PROJECT.ACTIVATE"; - public static final String EVENT_PROJECT_SUSPEND = "PROJECT.SUSPEND"; - public static final String EVENT_PROJECT_ACCOUNT_ADD = "PROJECT.ACCOUNT.ADD"; - public static final String EVENT_PROJECT_INVITATION_UPDATE = "PROJECT.INVITATION.UPDATE"; - public static final String EVENT_PROJECT_INVITATION_REMOVE = "PROJECT.INVITATION.REMOVE"; - public static final String EVENT_PROJECT_ACCOUNT_REMOVE = "PROJECT.ACCOUNT.REMOVE"; - - // Network as a Service - public static final String EVENT_NETWORK_ELEMENT_CONFIGURE = "NETWORK.ELEMENT.CONFIGURE"; - - // Physical Network Events - public static final String EVENT_PHYSICAL_NETWORK_CREATE = "PHYSICAL.NETWORK.CREATE"; - public static final String EVENT_PHYSICAL_NETWORK_DELETE = "PHYSICAL.NETWORK.DELETE"; - public static final String EVENT_PHYSICAL_NETWORK_UPDATE = "PHYSICAL.NETWORK.UPDATE"; - - // Physical Network Service Provider Events - public static final String EVENT_SERVICE_PROVIDER_CREATE = "SERVICE.PROVIDER.CREATE"; - public static final String EVENT_SERVICE_PROVIDER_DELETE = "SERVICE.PROVIDER.DELETE"; - public static final String EVENT_SERVICE_PROVIDER_UPDATE = "SERVICE.PROVIDER.UPDATE"; - - // Physical Network TrafficType Events - public static final String EVENT_TRAFFIC_TYPE_CREATE = "TRAFFIC.TYPE.CREATE"; - public static final String EVENT_TRAFFIC_TYPE_DELETE = "TRAFFIC.TYPE.DELETE"; - public static final String EVENT_TRAFFIC_TYPE_UPDATE = "TRAFFIC.TYPE.UPDATE"; - - // external network device events - public static final String EVENT_EXTERNAL_LB_DEVICE_ADD = "PHYSICAL.LOADBALANCER.ADD"; - public static final String EVENT_EXTERNAL_LB_DEVICE_DELETE = "PHYSICAL.LOADBALANCER.DELETE"; - public static final String EVENT_EXTERNAL_LB_DEVICE_CONFIGURE = "PHYSICAL.LOADBALANCER.CONFIGURE"; - - // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module. - public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD = "SWITCH.MGMT.ADD"; - public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE = "SWITCH.MGMT.DELETE"; - public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE = "SWITCH.MGMT.CONFIGURE"; - 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"; - - // tag related events - public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; - public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; - - // VPC - public static final String EVENT_VPC_CREATE = "VPC.CREATE"; - public static final String EVENT_VPC_UPDATE = "VPC.UPDATE"; - public static final String EVENT_VPC_DELETE = "VPC.DELETE"; - public static final String EVENT_VPC_RESTART = "VPC.RESTART"; - - // VPC offerings - public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE"; - public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE"; - public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE"; - - // Private gateway - public static final String EVENT_PRIVATE_GATEWAY_CREATE = "PRIVATE.GATEWAY.CREATE"; - public static final String EVENT_PRIVATE_GATEWAY_DELETE = "PRIVATE.GATEWAY.DELETE"; - - // Static routes - public static final String EVENT_STATIC_ROUTE_CREATE = "STATIC.ROUTE.CREATE"; - public static final String EVENT_STATIC_ROUTE_DELETE = "STATIC.ROUTE.DELETE"; -} +// 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.event; + +public class EventTypes { + // VM Events + public static final String EVENT_VM_CREATE = "VM.CREATE"; + public static final String EVENT_VM_DESTROY = "VM.DESTROY"; + public static final String EVENT_VM_START = "VM.START"; + public static final String EVENT_VM_STOP = "VM.STOP"; + public static final String EVENT_VM_REBOOT = "VM.REBOOT"; + public static final String EVENT_VM_UPDATE = "VM.UPDATE"; + public static final String EVENT_VM_UPGRADE = "VM.UPGRADE"; + public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD"; + public static final String EVENT_VM_MIGRATE = "VM.MIGRATE"; + public static final String EVENT_VM_MOVE = "VM.MOVE"; + public static final String EVENT_VM_RESTORE = "VM.RESTORE"; + + // Domain Router + public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE"; + public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY"; + public static final String EVENT_ROUTER_START = "ROUTER.START"; + public static final String EVENT_ROUTER_STOP = "ROUTER.STOP"; + public static final String EVENT_ROUTER_REBOOT = "ROUTER.REBOOT"; + public static final String EVENT_ROUTER_HA = "ROUTER.HA"; + public static final String EVENT_ROUTER_UPGRADE = "ROUTER.UPGRADE"; + + // Console proxy + public static final String EVENT_PROXY_CREATE = "PROXY.CREATE"; + public static final String EVENT_PROXY_DESTROY = "PROXY.DESTROY"; + public static final String EVENT_PROXY_START = "PROXY.START"; + public static final String EVENT_PROXY_STOP = "PROXY.STOP"; + public static final String EVENT_PROXY_REBOOT = "PROXY.REBOOT"; + public static final String EVENT_PROXY_HA = "PROXY.HA"; + + // VNC Console Events + public static final String EVENT_VNC_CONNECT = "VNC.CONNECT"; + public static final String EVENT_VNC_DISCONNECT = "VNC.DISCONNECT"; + + // Network Events + public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN"; + public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE"; + public static final String EVENT_NET_RULE_ADD = "NET.RULEADD"; + public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE"; + public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY"; + public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE"; + public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE"; + public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE"; + public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN"; + public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE"; + + // Load Balancers + public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE"; + public static final String EVENT_REMOVE_FROM_LOAD_BALANCER_RULE = "LB.REMOVE.FROM.RULE"; + public static final String EVENT_LOAD_BALANCER_CREATE = "LB.CREATE"; + public static final String EVENT_LOAD_BALANCER_DELETE = "LB.DELETE"; + public static final String EVENT_LB_STICKINESSPOLICY_CREATE = "LB.STICKINESSPOLICY.CREATE"; + public static final String EVENT_LB_STICKINESSPOLICY_DELETE = "LB.STICKINESSPOLICY.DELETE"; + public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE"; + + // Account events + public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE"; + public static final String EVENT_ACCOUNT_CREATE = "ACCOUNT.CREATE"; + public static final String EVENT_ACCOUNT_DELETE = "ACCOUNT.DELETE"; + public static final String EVENT_ACCOUNT_MARK_DEFAULT_ZONE = "ACCOUNT.MARK.DEFAULT.ZONE"; + + // UserVO Events + public static final String EVENT_USER_LOGIN = "USER.LOGIN"; + public static final String EVENT_USER_LOGOUT = "USER.LOGOUT"; + public static final String EVENT_USER_CREATE = "USER.CREATE"; + public static final String EVENT_USER_DELETE = "USER.DELETE"; + public static final String EVENT_USER_DISABLE = "USER.DISABLE"; + public static final String EVENT_USER_UPDATE = "USER.UPDATE"; + public static final String EVENT_USER_ENABLE = "USER.ENABLE"; + public static final String EVENT_USER_LOCK = "USER.LOCK"; + + // Template Events + public static final String EVENT_TEMPLATE_CREATE = "TEMPLATE.CREATE"; + public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE"; + public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE"; + public static final String EVENT_TEMPLATE_DOWNLOAD_START = "TEMPLATE.DOWNLOAD.START"; + public static final String EVENT_TEMPLATE_DOWNLOAD_SUCCESS = "TEMPLATE.DOWNLOAD.SUCCESS"; + public static final String EVENT_TEMPLATE_DOWNLOAD_FAILED = "TEMPLATE.DOWNLOAD.FAILED"; + public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY"; + public static final String EVENT_TEMPLATE_EXTRACT = "TEMPLATE.EXTRACT"; + public static final String EVENT_TEMPLATE_UPLOAD = "TEMPLATE.UPLOAD"; + public static final String EVENT_TEMPLATE_CLEANUP = "TEMPLATE.CLEANUP"; + + // Volume Events + public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE"; + public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE"; + public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH"; + public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH"; + public static final String EVENT_VOLUME_EXTRACT = "VOLUME.EXTRACT"; + public static final String EVENT_VOLUME_UPLOAD = "VOLUME.UPLOAD"; + public static final String EVENT_VOLUME_MIGRATE = "VOLUME.MIGRATE"; + + // Domains + public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE"; + public static final String EVENT_DOMAIN_DELETE = "DOMAIN.DELETE"; + public static final String EVENT_DOMAIN_UPDATE = "DOMAIN.UPDATE"; + + // Snapshots + public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE"; + public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE"; + public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE"; + public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE"; + public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE"; + + // ISO + public static final String EVENT_ISO_CREATE = "ISO.CREATE"; + public static final String EVENT_ISO_DELETE = "ISO.DELETE"; + public static final String EVENT_ISO_COPY = "ISO.COPY"; + public static final String EVENT_ISO_ATTACH = "ISO.ATTACH"; + public static final String EVENT_ISO_DETACH = "ISO.DETACH"; + public static final String EVENT_ISO_EXTRACT = "ISO.EXTRACT"; + public static final String EVENT_ISO_UPLOAD = "ISO.UPLOAD"; + + // SSVM + public static final String EVENT_SSVM_CREATE = "SSVM.CREATE"; + public static final String EVENT_SSVM_DESTROY = "SSVM.DESTROY"; + public static final String EVENT_SSVM_START = "SSVM.START"; + public static final String EVENT_SSVM_STOP = "SSVM.STOP"; + public static final String EVENT_SSVM_REBOOT = "SSVM.REBOOT"; + public static final String EVENT_SSVM_HA = "SSVM.HA"; + + // Service Offerings + public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE"; + public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT"; + public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE"; + + // Disk Offerings + public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE"; + public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT"; + public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE"; + + // Network offerings + public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE"; + public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN"; + public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT"; + public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE"; + public static final String EVENT_NETWORK_OFFERING_DELETE = "NETWORK.OFFERING.DELETE"; + + // Pods + public static final String EVENT_POD_CREATE = "POD.CREATE"; + public static final String EVENT_POD_EDIT = "POD.EDIT"; + public static final String EVENT_POD_DELETE = "POD.DELETE"; + + // Zones + public static final String EVENT_ZONE_CREATE = "ZONE.CREATE"; + public static final String EVENT_ZONE_EDIT = "ZONE.EDIT"; + public static final String EVENT_ZONE_DELETE = "ZONE.DELETE"; + + // VLANs/IP ranges + public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE"; + public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE"; + + public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE"; + public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE"; + public static final String EVENT_STORAGE_IP_RANGE_UPDATE = "STORAGE.IP.RANGE.UPDATE"; + + // Configuration Table + public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT"; + + // Security Groups + public static final String EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS = "SG.AUTH.INGRESS"; + public static final String EVENT_SECURITY_GROUP_REVOKE_INGRESS = "SG.REVOKE.INGRESS"; + public static final String EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS = "SG.AUTH.EGRESS"; + public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS"; + public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE"; + public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE"; + public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN"; + public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE"; + + // Host + public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT"; + + // Maintenance + public static final String EVENT_MAINTENANCE_CANCEL = "MAINT.CANCEL"; + public static final String EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE = "MAINT.CANCEL.PS"; + public static final String EVENT_MAINTENANCE_PREPARE = "MAINT.PREPARE"; + public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS"; + + // VPN + public static final String EVENT_REMOTE_ACCESS_VPN_CREATE = "VPN.REMOTE.ACCESS.CREATE"; + public static final String EVENT_REMOTE_ACCESS_VPN_DESTROY = "VPN.REMOTE.ACCESS.DESTROY"; + public static final String EVENT_VPN_USER_ADD = "VPN.USER.ADD"; + public static final String EVENT_VPN_USER_REMOVE = "VPN.USER.REMOVE"; + public static final String EVENT_S2S_VPN_GATEWAY_CREATE = "VPN.S2S.VPN.GATEWAY.CREATE"; + public static final String EVENT_S2S_VPN_GATEWAY_DELETE = "VPN.S2S.VPN.GATEWAY.DELETE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE"; + public static final String EVENT_S2S_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE"; + public static final String EVENT_S2S_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE"; + public static final String EVENT_S2S_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET"; + + // Network + public static final String EVENT_NETWORK_RESTART = "NETWORK.RESTART"; + + // Custom certificates + public static final String EVENT_UPLOAD_CUSTOM_CERTIFICATE = "UPLOAD.CUSTOM.CERTIFICATE"; + + // OneToOnenat + public static final String EVENT_ENABLE_STATIC_NAT = "STATICNAT.ENABLE"; + public static final String EVENT_DISABLE_STATIC_NAT = "STATICNAT.DISABLE"; + + public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN"; + public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE"; + + // Projects + public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE"; + public static final String EVENT_PROJECT_UPDATE = "PROJECT.UPDATE"; + public static final String EVENT_PROJECT_DELETE = "PROJECT.DELETE"; + public static final String EVENT_PROJECT_ACTIVATE = "PROJECT.ACTIVATE"; + public static final String EVENT_PROJECT_SUSPEND = "PROJECT.SUSPEND"; + public static final String EVENT_PROJECT_ACCOUNT_ADD = "PROJECT.ACCOUNT.ADD"; + public static final String EVENT_PROJECT_INVITATION_UPDATE = "PROJECT.INVITATION.UPDATE"; + public static final String EVENT_PROJECT_INVITATION_REMOVE = "PROJECT.INVITATION.REMOVE"; + public static final String EVENT_PROJECT_ACCOUNT_REMOVE = "PROJECT.ACCOUNT.REMOVE"; + + // Network as a Service + public static final String EVENT_NETWORK_ELEMENT_CONFIGURE = "NETWORK.ELEMENT.CONFIGURE"; + + // Physical Network Events + public static final String EVENT_PHYSICAL_NETWORK_CREATE = "PHYSICAL.NETWORK.CREATE"; + public static final String EVENT_PHYSICAL_NETWORK_DELETE = "PHYSICAL.NETWORK.DELETE"; + public static final String EVENT_PHYSICAL_NETWORK_UPDATE = "PHYSICAL.NETWORK.UPDATE"; + + // Physical Network Service Provider Events + public static final String EVENT_SERVICE_PROVIDER_CREATE = "SERVICE.PROVIDER.CREATE"; + public static final String EVENT_SERVICE_PROVIDER_DELETE = "SERVICE.PROVIDER.DELETE"; + public static final String EVENT_SERVICE_PROVIDER_UPDATE = "SERVICE.PROVIDER.UPDATE"; + + // Physical Network TrafficType Events + public static final String EVENT_TRAFFIC_TYPE_CREATE = "TRAFFIC.TYPE.CREATE"; + public static final String EVENT_TRAFFIC_TYPE_DELETE = "TRAFFIC.TYPE.DELETE"; + public static final String EVENT_TRAFFIC_TYPE_UPDATE = "TRAFFIC.TYPE.UPDATE"; + + // external network device events + public static final String EVENT_EXTERNAL_LB_DEVICE_ADD = "PHYSICAL.LOADBALANCER.ADD"; + public static final String EVENT_EXTERNAL_LB_DEVICE_DELETE = "PHYSICAL.LOADBALANCER.DELETE"; + public static final String EVENT_EXTERNAL_LB_DEVICE_CONFIGURE = "PHYSICAL.LOADBALANCER.CONFIGURE"; + + // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module. + public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD = "SWITCH.MGMT.ADD"; + public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE = "SWITCH.MGMT.DELETE"; + public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE = "SWITCH.MGMT.CONFIGURE"; + 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"; + + // tag related events + public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; + public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; + + // VPC + public static final String EVENT_VPC_CREATE = "VPC.CREATE"; + public static final String EVENT_VPC_UPDATE = "VPC.UPDATE"; + public static final String EVENT_VPC_DELETE = "VPC.DELETE"; + public static final String EVENT_VPC_RESTART = "VPC.RESTART"; + + // VPC offerings + public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE"; + public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE"; + public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE"; + + // Private gateway + public static final String EVENT_PRIVATE_GATEWAY_CREATE = "PRIVATE.GATEWAY.CREATE"; + public static final String EVENT_PRIVATE_GATEWAY_DELETE = "PRIVATE.GATEWAY.DELETE"; + + // Static routes + public static final String EVENT_STATIC_ROUTE_CREATE = "STATIC.ROUTE.CREATE"; + public static final String EVENT_STATIC_ROUTE_DELETE = "STATIC.ROUTE.DELETE"; + + // 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"; +} diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index b8ebb93fe8a..e629b0b8d9b 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -1,293 +1,295 @@ -// 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; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import com.cloud.acl.ControlledEntity; -import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.Networks.Mode; -import com.cloud.network.Networks.TrafficType; -import com.cloud.utils.fsm.FiniteState; -import com.cloud.utils.fsm.StateMachine; - -/** - * owned by an account. - */ -public interface Network extends ControlledEntity { - - public enum GuestType { - Shared, - Isolated - } - - public static class Service { - private static List supportedServices = new ArrayList(); - - public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes); - public static final Service Dhcp = new Service("Dhcp"); - public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification); - public static final Service Gateway = new Service("Gateway"); - public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, - Capability.MultipleIps, Capability.TrafficStatistics); - public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, - Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, - Capability.SupportedStickinessMethods, Capability.ElasticLb); - public static final Service UserData = new Service("UserData"); - public static final Service SourceNat = new Service("SourceNat", Capability.SupportedSourceNatTypes, Capability.RedundantRouter); - public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp); - public static final Service PortForwarding = new Service("PortForwarding"); - public static final Service SecurityGroup = new Service("SecurityGroup"); - public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols); - - private String name; - private Capability[] caps; - - public Service(String name, Capability... caps) { - this.name = name; - this.caps = caps; - supportedServices.add(this); - } - - public String getName() { - return name; - } - - public Capability[] getCapabilities() { - return caps; - } - - public boolean containsCapability(Capability cap) { - boolean success = false; - if (caps != null) { - int length = caps.length; - for (int i = 0; i< length; i++) { - if (caps[i].getName().equalsIgnoreCase(cap.getName())) { - success = true; - break; - } - } - } - - return success; - } - - public static Service getService(String serviceName) { - for (Service service : supportedServices) { - if (service.getName().equalsIgnoreCase(serviceName)) { - return service; - } - } - return null; - } - - public static List listAllServices(){ - return supportedServices; - } - } - - /** - * Provider -> NetworkElement must always be one-to-one mapping. Thus for each NetworkElement we need a separate Provider added in here. - */ - 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); - public static final Provider Netscaler = new Provider("Netscaler", true); - public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer", true); - public static final Provider ExternalGateWay = new Provider("ExternalGateWay", true); - public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm", false); - public static final Provider SecurityGroupProvider = new Provider("SecurityGroupProvider", false); - public static final Provider VPCVirtualRouter = new Provider("VpcVirtualRouter", false); - public static final Provider None = new Provider("None", false); - - private String name; - private boolean isExternal; - - public Provider(String name, boolean isExternal) { - this.name = name; - this.isExternal = isExternal; - supportedProviders.add(this); - } - - 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)) { - return provider; - } - } - return null; - } - } - - 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"); - public static final Capability SupportedStickinessMethods = new Capability("SupportedStickinessMethods"); - public static final Capability MultipleIps = new Capability("MultipleIps"); - public static final Capability SupportedSourceNatTypes = new Capability("SupportedSourceNatTypes"); - public static final Capability SupportedVpnProtocols = new Capability("SupportedVpnTypes"); - public static final Capability VpnTypes = new Capability("VpnTypes"); - public static final Capability TrafficStatistics = new Capability("TrafficStatistics"); - public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps"); - public static final Capability AllowDnsSuffixModification = new Capability("AllowDnsSuffixModification"); - public static final Capability RedundantRouter = new Capability("RedundantRouter"); - public static final Capability ElasticIp = new Capability("ElasticIp"); - public static final Capability ElasticLb = new Capability("ElasticLb"); - - private String name; - - public Capability(String name) { - this.name = name; - supportedCapabilities.add(this); - } - - public String getName() { - return name; - } - - public static Capability getCapability(String capabilityName) { - for (Capability capability : supportedCapabilities) { - if (capability.getName().equalsIgnoreCase(capabilityName)) { - return capability; - } - } - return null; - } - } - - enum Event { - ImplementNetwork, - DestroyNetwork, - OperationSucceeded, - OperationFailed; - } - - enum State implements FiniteState { - Allocated("Indicates the network configuration is in allocated but not setup"), - Setup("Indicates the network configuration is setup"), - Implementing("Indicates the network configuration is being implemented"), - Implemented("Indicates the network configuration is in use"), - Shutdown("Indicates the network configuration is being destroyed"), - Destroy("Indicates that the network is destroyed"); - - - @Override - public StateMachine getStateMachine() { - return s_fsm; - } - - @Override - public State getNextState(Event event) { - return s_fsm.getNextState(this, event); - } - - @Override - public List getFromStates(Event event) { - return s_fsm.getFromStates(this, event); - } - - @Override - public Set getPossibleEvents() { - return s_fsm.getPossibleEvents(this); - } - - String _description; - - @Override - public String getDescription() { - return _description; - } - - private State(String description) { - _description = description; - } - - private static StateMachine s_fsm = new StateMachine(); - static { - s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing); - s_fsm.addTransition(State.Implementing, Event.OperationSucceeded, State.Implemented); - s_fsm.addTransition(State.Implementing, Event.OperationFailed, State.Shutdown); - s_fsm.addTransition(State.Implemented, Event.DestroyNetwork, State.Shutdown); - s_fsm.addTransition(State.Shutdown, Event.OperationSucceeded, State.Allocated); - s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented); - } - } - - /** - * @return id of the network profile. Null means the network profile is not from the database. - */ - long getId(); - - String getName(); - - Mode getMode(); - - BroadcastDomainType getBroadcastDomainType(); - - TrafficType getTrafficType(); - - String getGateway(); - - String getCidr(); - - long getDataCenterId(); - - long getNetworkOfferingId(); - - State getState(); - - long getRelated(); - - URI getBroadcastUri(); - - String getDisplayText(); - - String getReservationId(); - - String getNetworkDomain(); - - GuestType getGuestType(); - - Long getPhysicalNetworkId(); - - void setPhysicalNetworkId(Long physicalNetworkId); - - ACLType getAclType(); - - boolean isRestartRequired(); - - boolean getSpecifyIpRanges(); - - /** - * @return - */ - Long getVpcId(); -} +// 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; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import com.cloud.acl.ControlledEntity; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.Mode; +import com.cloud.network.Networks.TrafficType; +import com.cloud.utils.fsm.FiniteState; +import com.cloud.utils.fsm.StateMachine; + +/** + * owned by an account. + */ +public interface Network extends ControlledEntity { + + public enum GuestType { + Shared, + Isolated + } + + public static class Service { + private static List supportedServices = new ArrayList(); + + public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes); + public static final Service Dhcp = new Service("Dhcp"); + public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification); + public static final Service Gateway = new Service("Gateway"); + public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, + Capability.MultipleIps, Capability.TrafficStatistics); + public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, + Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, + Capability.SupportedStickinessMethods, Capability.ElasticLb); + public static final Service UserData = new Service("UserData"); + public static final Service SourceNat = new Service("SourceNat", Capability.SupportedSourceNatTypes, Capability.RedundantRouter); + public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp); + public static final Service PortForwarding = new Service("PortForwarding"); + public static final Service SecurityGroup = new Service("SecurityGroup"); + public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols); + + private String name; + private Capability[] caps; + + public Service(String name, Capability... caps) { + this.name = name; + this.caps = caps; + supportedServices.add(this); + } + + public String getName() { + return name; + } + + public Capability[] getCapabilities() { + return caps; + } + + public boolean containsCapability(Capability cap) { + boolean success = false; + if (caps != null) { + int length = caps.length; + for (int i = 0; i< length; i++) { + if (caps[i].getName().equalsIgnoreCase(cap.getName())) { + success = true; + break; + } + } + } + + return success; + } + + public static Service getService(String serviceName) { + for (Service service : supportedServices) { + if (service.getName().equalsIgnoreCase(serviceName)) { + return service; + } + } + return null; + } + + public static List listAllServices(){ + return supportedServices; + } + } + + /** + * Provider -> NetworkElement must always be one-to-one mapping. Thus for each NetworkElement we need a separate Provider added in here. + */ + 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); + public static final Provider Netscaler = new Provider("Netscaler", true); + public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer", true); + public static final Provider ExternalGateWay = new Provider("ExternalGateWay", true); + public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm", false); + public static final Provider SecurityGroupProvider = new Provider("SecurityGroupProvider", false); + public static final Provider VPCVirtualRouter = new Provider("VpcVirtualRouter", false); + public static final Provider None = new Provider("None", false); + + private String name; + private boolean isExternal; + + public Provider(String name, boolean isExternal) { + this.name = name; + this.isExternal = isExternal; + supportedProviders.add(this); + } + + 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)) { + return provider; + } + } + return null; + } + } + + 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"); + public static final Capability SupportedStickinessMethods = new Capability("SupportedStickinessMethods"); + public static final Capability MultipleIps = new Capability("MultipleIps"); + public static final Capability SupportedSourceNatTypes = new Capability("SupportedSourceNatTypes"); + public static final Capability SupportedVpnProtocols = new Capability("SupportedVpnTypes"); + public static final Capability VpnTypes = new Capability("VpnTypes"); + public static final Capability TrafficStatistics = new Capability("TrafficStatistics"); + public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps"); + public static final Capability AllowDnsSuffixModification = new Capability("AllowDnsSuffixModification"); + 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; + + public Capability(String name) { + this.name = name; + supportedCapabilities.add(this); + } + + public String getName() { + return name; + } + + public static Capability getCapability(String capabilityName) { + for (Capability capability : supportedCapabilities) { + if (capability.getName().equalsIgnoreCase(capabilityName)) { + return capability; + } + } + return null; + } + } + + enum Event { + ImplementNetwork, + DestroyNetwork, + OperationSucceeded, + OperationFailed; + } + + enum State implements FiniteState { + Allocated("Indicates the network configuration is in allocated but not setup"), + Setup("Indicates the network configuration is setup"), + Implementing("Indicates the network configuration is being implemented"), + Implemented("Indicates the network configuration is in use"), + Shutdown("Indicates the network configuration is being destroyed"), + Destroy("Indicates that the network is destroyed"); + + + @Override + public StateMachine getStateMachine() { + return s_fsm; + } + + @Override + public State getNextState(Event event) { + return s_fsm.getNextState(this, event); + } + + @Override + public List getFromStates(Event event) { + return s_fsm.getFromStates(this, event); + } + + @Override + public Set getPossibleEvents() { + return s_fsm.getPossibleEvents(this); + } + + String _description; + + @Override + public String getDescription() { + return _description; + } + + private State(String description) { + _description = description; + } + + private static StateMachine s_fsm = new StateMachine(); + static { + s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing); + s_fsm.addTransition(State.Implementing, Event.OperationSucceeded, State.Implemented); + s_fsm.addTransition(State.Implementing, Event.OperationFailed, State.Shutdown); + s_fsm.addTransition(State.Implemented, Event.DestroyNetwork, State.Shutdown); + s_fsm.addTransition(State.Shutdown, Event.OperationSucceeded, State.Allocated); + s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented); + } + } + + /** + * @return id of the network profile. Null means the network profile is not from the database. + */ + long getId(); + + String getName(); + + Mode getMode(); + + BroadcastDomainType getBroadcastDomainType(); + + TrafficType getTrafficType(); + + String getGateway(); + + String getCidr(); + + long getDataCenterId(); + + long getNetworkOfferingId(); + + State getState(); + + long getRelated(); + + URI getBroadcastUri(); + + String getDisplayText(); + + String getReservationId(); + + String getNetworkDomain(); + + GuestType getGuestType(); + + Long getPhysicalNetworkId(); + + void setPhysicalNetworkId(Long physicalNetworkId); + + ACLType getAclType(); + + 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..f14d10b2d97 --- /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 Integer getDuration(); + + public Integer 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..f4b9ddd1dc6 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleService.java @@ -0,0 +1,80 @@ +// 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; + +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..291739e49d3 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleVmGroup.java @@ -0,0 +1,53 @@ +// 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 { + + static enum Operator { + EQ, GT, LT, GE, LE + }; + + long getId(); + + @Override + long getAccountId(); + + long getLoadBalancerId(); + + long getProfileId(); + + int getMinMembers(); + + int getMaxMembers(); + + int getMemberPort(); + + int getInterval(); + + boolean isRevoke(); + + 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..02719ee2059 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleVmProfile.java @@ -0,0 +1,38 @@ +// 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. +// +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 fb789fd6d73..c0208c2352b 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRule.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -1,222 +1,443 @@ -// 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.lb; - -import java.util.List; - -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.utils.Pair; - -public class LoadBalancingRule implements FirewallRule, LoadBalancer{ - private LoadBalancer lb; - private List destinations; - private List stickinessPolicies; - - 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(); - } - - public int getDefaultPortStart() { - return lb.getDefaultPortStart(); - } - - @Override - public int getDefaultPortEnd() { - return lb.getDefaultPortEnd(); - } - - @Override - 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(); - } - - @Override - 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; - } - - public List getDestinations() { - return destinations; - } - - public List getStickinessPolicies() { - return stickinessPolicies; - } - - - public interface Destination { - String getIpAddress(); - int getDestinationPortStart(); - int getDestinationPortEnd(); - boolean isRevoked(); - } - - public static class LbStickinessPolicy { - private String _methodName; - private List> _params; - private boolean _revoke; - - public LbStickinessPolicy(String methodName, List> params, boolean revoke) { - this._methodName = methodName; - this._params = params; - this._revoke = revoke; - } - - public LbStickinessPolicy(String methodName, List> params) { - this._methodName = methodName; - this._params = params; - this._revoke = false; - } - - public String getMethodName() { - return _methodName; - } - - public List> getParams() { - return _params; - } - - public boolean isRevoked() { - 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; - } - - public String getIpAddress() { - return ip; - } - public int getDestinationPortStart() { - return portStart; - } - public int getDestinationPortEnd() { - return portEnd; - } - - 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; - } -} +// 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.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; + +public class LoadBalancingRule implements FirewallRule, LoadBalancer{ + private final LoadBalancer lb; + private final List destinations; + private final 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(); + } + + @Override + 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(); + } + + @Override + 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; + } + + public List getDestinations() { + return destinations; + } + + public List getStickinessPolicies() { + return stickinessPolicies; + } + + + public interface Destination { + String getIpAddress(); + int getDestinationPortStart(); + int getDestinationPortEnd(); + boolean isRevoked(); + } + + public static class LbStickinessPolicy { + private final String _methodName; + private final List> _params; + private final boolean _revoke; + + public LbStickinessPolicy(String methodName, List> params, boolean revoke) { + this._methodName = methodName; + this._params = params; + this._revoke = revoke; + } + + public LbStickinessPolicy(String methodName, List> params) { + this._methodName = methodName; + this._params = params; + this._revoke = false; + } + + public String getMethodName() { + return _methodName; + } + + public List> getParams() { + return _params; + } + + public boolean isRevoked() { + return _revoke; + } + } + + public static class LbDestination implements Destination { + private final int portStart; + private final int portEnd; + private final 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; + } + + 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 cloudStackApiUrl; + private final String autoScaleUserApiKey; + private final String autoScaleUserSecretKey; + + public LbAutoScaleVmProfile(AutoScaleVmProfile profile, String cloudStackApiUrl, String autoScaleUserApiKey, String autoScaleUserSecretKey) { + this.profile = profile; + this.cloudStackApiUrl = cloudStackApiUrl; + this.autoScaleUserApiKey = autoScaleUserApiKey; + this.autoScaleUserSecretKey = autoScaleUserSecretKey; + } + public AutoScaleVmProfile getProfile() { + return profile; + } + public String getCloudStackApiUrl() { + return cloudStackApiUrl; + } + public String getAutoScaleUserApiKey() { + return autoScaleUserApiKey; + } + public String getAutoScaleUserSecretKey() { + return autoScaleUserSecretKey; + } + } + + 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; + } + } + //public static class LbCounter{ + //private String name; + //private String source; + //private String value; + // + //public LbCounter(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 LbCondition{ + //private long threshold; + //private String relationalOperator; + //private LbCounter counter; + //public LbCondition(int threshold, String relationalOperator, LbCounter counter) + //{ + // this.threshold = threshold; + // this.relationalOperator = relationalOperator; + // this.counter = counter; + //} + //public long getThreshold() { + // return threshold; + //} + //public String getRelationalOperator() { + // return relationalOperator; + //} + //public LbCounter getCounter() { + // return counter; + //} + //} + // + //public static class AutoScaleVmGroup { + //private int minMembers; + //private int maxMembers; + //private List scaleUpPolicies; + //private List scaleDownPolicies; + //private List profile; + //private boolean revoked; + // + //public boolean isRevoked() { + // return revoked; + //} + // + //public void setRevoked(boolean revoked) { + // this.revoked = revoked; + //} + //} + // + //public static class AutoScaleVmProfile { + //private Long zoneId; + //private long domainId; + //private long accountId; + //private Long serviceOfferingId; + //private Long templateId; + //private String otherDeployParams; + //private String snmpCommunity; + //private Integer snmpPort; + // + //} + // + //public static class AutoscalePolicy { + //private int interval; + // + //private int duration; + //private int quietTime; + //private String action; + //private List conditions; + // + //public AutoscalePolicy(int interval, int duration, int quietTime, String action, List conditions) { + // this.interval = interval; + // this.duration = duration; + // this.quietTime = quietTime; + // this.conditions = conditions; + //} + // + //public int getInterval() { + // return interval; + //} + // + //public int getDuration() { + // return duration; + //} + // + //public int getQuietTime() { + // return quietTime; + //} + // + //public String getAction() { + // return action; + //} + // + //public List getConditions() { + // return conditions; + //} + //} +} diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index ad5d0a02fa7..4196a9b34bd 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -1,104 +1,104 @@ -// 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.lb; - -import java.util.List; - -import com.cloud.api.commands.CreateLBStickinessPolicyCmd; -import com.cloud.api.commands.CreateLoadBalancerRuleCmd; -import com.cloud.api.commands.ListLBStickinessPoliciesCmd; -import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd; -import com.cloud.api.commands.ListLoadBalancerRulesCmd; -import com.cloud.api.commands.UpdateLoadBalancerRuleCmd; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.NetworkRuleConflictException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.StickinessPolicy; -import com.cloud.uservm.UserVm; - -public interface LoadBalancingRulesService { - /** - * Create a load balancer rule from the given ipAddress/port to the given private port - * - * @param openFirewall - * TODO - * @param cmd - * the command specifying the ip address, public port, protocol, private port, and algorithm - * @return the newly created LoadBalancerVO if successful, null otherwise - * @throws InsufficientAddressCapacityException - */ - LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException; - - LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd); - - boolean deleteLoadBalancerRule(long lbRuleId, boolean apply); - - /** - * Create a stickiness policy to a load balancer from the given stickiness method name and parameters in - * (name,value) pairs. - * - * @param cmd - * the command specifying the stickiness method name, params (name,value pairs), policy name and - * description. - * @return the newly created stickiness policy if successfull, null otherwise - * @thows NetworkRuleConflictException - */ - public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException; - - public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws ResourceUnavailableException; - - boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply); - /** - * Assign a virtual machine, or list of virtual machines, to a load balancer. - */ - boolean assignToLoadBalancer(long lbRuleId, List vmIds); - - boolean removeFromLoadBalancer(long lbRuleId, List vmIds); - - boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException; - - /** - * List instances that have either been applied to a load balancer or are eligible to be assigned to a load - * balancer. - * - * @param cmd - * @return list of vm instances that have been or can be applied to a load balancer - */ - List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd); - - /** - * List load balancer rules based on the given criteria - * - * @param cmd - * the command that specifies the criteria to use for listing load balancers. Load balancers can be - * listed - * by id, name, public ip, and vm instance id - * @return list of load balancers that match the criteria - */ - List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd); - - /** - * List stickiness policies based on the given criteria - * - * @param cmd - * the command specifies the load balancing rule id. - * @return list of stickiness policies that match the criteria. - */ - List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd); - - List listByNetworkId(long networkId); - - LoadBalancer findById(long LoadBalancer); - -} +// 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.lb; + +import java.util.List; + +import com.cloud.api.commands.CreateLBStickinessPolicyCmd; +import com.cloud.api.commands.CreateLoadBalancerRuleCmd; +import com.cloud.api.commands.ListLBStickinessPoliciesCmd; +import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd; +import com.cloud.api.commands.ListLoadBalancerRulesCmd; +import com.cloud.api.commands.UpdateLoadBalancerRuleCmd; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.uservm.UserVm; + +public interface LoadBalancingRulesService { + /** + * Create a load balancer rule from the given ipAddress/port to the given private port + * + * @param openFirewall + * TODO + * @param cmd + * the command specifying the ip address, public port, protocol, private port, and algorithm + * @return the newly created LoadBalancerVO if successful, null otherwise + * @throws InsufficientAddressCapacityException + */ + LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException; + + LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd); + + boolean deleteLoadBalancerRule(long lbRuleId, boolean apply); + + /** + * Create a stickiness policy to a load balancer from the given stickiness method name and parameters in + * (name,value) pairs. + * + * @param cmd + * the command specifying the stickiness method name, params (name,value pairs), policy name and + * description. + * @return the newly created stickiness policy if successfull, null otherwise + * @thows NetworkRuleConflictException + */ + public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException; + + public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws ResourceUnavailableException; + + boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply); + + /** + * Assign a virtual machine, or list of virtual machines, to a load balancer. + */ + boolean assignToLoadBalancer(long lbRuleId, List vmIds); + + boolean removeFromLoadBalancer(long lbRuleId, List vmIds); + + boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException; + + /** + * List instances that have either been applied to a load balancer or are eligible to be assigned to a load + * balancer. + * + * @param cmd + * @return list of vm instances that have been or can be applied to a load balancer + */ + List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd); + + /** + * List load balancer rules based on the given criteria + * + * @param cmd + * the command that specifies the criteria to use for listing load balancers. Load balancers can be + * listed + * by id, name, public ip, and vm instance id + * @return list of load balancers that match the criteria + */ + List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd); + + /** + * List stickiness policies based on the given criteria + * + * @param cmd + * the command specifies the load balancing rule id. + * @return list of stickiness policies that match the criteria. + */ + List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd); + + List listByNetworkId(long networkId); + + LoadBalancer findById(long LoadBalancer); +} diff --git a/build/build-common.xml b/build/build-common.xml index 8cf0bbcf6a9..c36061f790e 100755 --- a/build/build-common.xml +++ b/build/build-common.xml @@ -48,7 +48,7 @@ + memoryinitialsize="256m" memorymaximumsize="512m" fork="true"> diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 979a6f97bae..869a11931b2 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -49,7 +49,7 @@ listVirtualMachines=com.cloud.api.commands.ListVMsCmd;15 getVMPassword=com.cloud.api.commands.GetVMPasswordCmd;15 migrateVirtualMachine=com.cloud.api.commands.MigrateVMCmd;1 assignVirtualMachine=com.cloud.api.commands.AssignVMCmd;1 -restoreVirtualMachine=com.cloud.api.commands.RestoreVMCmd;15 +restoreVirtualMachine=com.cloud.api.commands.RestoreVMCmd;15 #### snapshot commands createSnapshot=com.cloud.api.commands.CreateSnapshotCmd;15 @@ -128,12 +128,30 @@ createLoadBalancerRule=com.cloud.api.commands.CreateLoadBalancerRuleCmd;15 deleteLoadBalancerRule=com.cloud.api.commands.DeleteLoadBalancerRuleCmd;15 removeFromLoadBalancerRule=com.cloud.api.commands.RemoveFromLoadBalancerRuleCmd;15 assignToLoadBalancerRule=com.cloud.api.commands.AssignToLoadBalancerRuleCmd;15 -createLBStickinessPolicy=com.cloud.api.commands.CreateLBStickinessPolicyCmd;15 -deleteLBStickinessPolicy=com.cloud.api.commands.DeleteLBStickinessPolicyCmd;15 +createLBStickinessPolicy=com.cloud.api.commands.CreateLBStickinessPolicyCmd;15 +deleteLBStickinessPolicy=com.cloud.api.commands.DeleteLBStickinessPolicyCmd;15 listLoadBalancerRules=com.cloud.api.commands.ListLoadBalancerRulesCmd;15 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 #### router commands startRouter=com.cloud.api.commands.StartRouterCmd;7 @@ -180,11 +198,11 @@ listAlerts=com.cloud.api.commands.ListAlertsCmd;3 #### system capacity commands listCapacity=com.cloud.api.commands.ListCapacityCmd;3 - -#### swift commands^M -addSwift=com.cloud.api.commands.AddSwiftCmd;1 -listSwifts=com.cloud.api.commands.ListSwiftsCmd;1 - + +#### swift commands^M +addSwift=com.cloud.api.commands.AddSwiftCmd;1 +listSwifts=com.cloud.api.commands.ListSwiftsCmd;1 + #### host commands addHost=com.cloud.api.commands.AddHostCmd;3 @@ -277,21 +295,21 @@ updateNetwork=com.cloud.api.commands.UpdateNetworkCmd;15 registerSSHKeyPair=com.cloud.api.commands.RegisterSSHKeyPairCmd;15 createSSHKeyPair=com.cloud.api.commands.CreateSSHKeyPairCmd;15 deleteSSHKeyPair=com.cloud.api.commands.DeleteSSHKeyPairCmd;15 -listSSHKeyPairs=com.cloud.api.commands.ListSSHKeyPairsCmd;15 - +listSSHKeyPairs=com.cloud.api.commands.ListSSHKeyPairsCmd;15 + #### Projects commands createProject=com.cloud.api.commands.CreateProjectCmd;15 deleteProject=com.cloud.api.commands.DeleteProjectCmd;15 updateProject=com.cloud.api.commands.UpdateProjectCmd;15 activateProject=com.cloud.api.commands.ActivateProjectCmd;15 suspendProject=com.cloud.api.commands.SuspendProjectCmd;15 -listProjects=com.cloud.api.commands.ListProjectsCmd;15 +listProjects=com.cloud.api.commands.ListProjectsCmd;15 addAccountToProject=com.cloud.api.commands.AddAccountToProjectCmd;15 deleteAccountFromProject=com.cloud.api.commands.DeleteAccountFromProjectCmd;15 listProjectAccounts=com.cloud.api.commands.ListProjectAccountsCmd;15 listProjectInvitations=com.cloud.api.commands.ListProjectInvitationsCmd;15 updateProjectInvitation=com.cloud.api.commands.UpdateProjectInvitationCmd;15 -deleteProjectInvitation=com.cloud.api.commands.DeleteProjectInvitationCmd;15 +deleteProjectInvitation=com.cloud.api.commands.DeleteProjectInvitationCmd;15 #### createFirewallRule=com.cloud.api.commands.CreateFirewallRuleCmd;15 @@ -307,7 +325,7 @@ createPhysicalNetwork=com.cloud.api.commands.CreatePhysicalNetworkCmd;1 deletePhysicalNetwork=com.cloud.api.commands.DeletePhysicalNetworkCmd;1 listPhysicalNetworks=com.cloud.api.commands.ListPhysicalNetworksCmd;1 updatePhysicalNetwork=com.cloud.api.commands.UpdatePhysicalNetworkCmd;1 - + #### Physical Network Service Provider commands listSupportedNetworkServices=com.cloud.api.commands.ListSupportedNetworkServicesCmd;1 addNetworkServiceProvider=com.cloud.api.commands.AddNetworkServiceProviderCmd;1 @@ -320,13 +338,13 @@ addTrafficType=com.cloud.api.commands.AddTrafficTypeCmd;1 deleteTrafficType=com.cloud.api.commands.DeleteTrafficTypeCmd;1 listTrafficTypes=com.cloud.api.commands.ListTrafficTypesCmd;1 updateTrafficType=com.cloud.api.commands.UpdateTrafficTypeCmd;1 -listTrafficTypeImplementors=com.cloud.api.commands.ListTrafficTypeImplementorsCmd;1 +listTrafficTypeImplementors=com.cloud.api.commands.ListTrafficTypeImplementorsCmd;1 #### Storage Network commands createStorageNetworkIpRange=com.cloud.api.commands.CreateStorageNetworkIpRangeCmd;1 deleteStorageNetworkIpRange=com.cloud.api.commands.DeleteStorageNetworkIpRangeCmd;1 listStorageNetworkIpRange=com.cloud.api.commands.listStorageNetworkIpRangeCmd;1 -updateStorageNetworkIpRange=com.cloud.api.commands.UpdateStorageNetworkIpRangeCmd;1 +updateStorageNetworkIpRange=com.cloud.api.commands.UpdateStorageNetworkIpRangeCmd;1 #### Network Devices commands addNetworkDevice=com.cloud.api.commands.AddNetworkDeviceCmd;1 @@ -365,16 +383,16 @@ listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15 createStaticRoute=com.cloud.api.commands.CreateStaticRouteCmd;15 deleteStaticRoute=com.cloud.api.commands.DeleteStaticRouteCmd;15 listStaticRoutes=com.cloud.api.commands.ListStaticRoutesCmd;15 - -### Site-to-site VPN commands -createVpnCustomerGateway=com.cloud.api.commands.CreateVpnCustomerGatewayCmd;1 -createVpnGateway=com.cloud.api.commands.CreateVpnGatewayCmd;1 -createVpnConnection=com.cloud.api.commands.CreateVpnConnectionCmd;1 -deleteVpnCustomerGateway=com.cloud.api.commands.DeleteVpnCustomerGatewayCmd;1 -deleteVpnGateway=com.cloud.api.commands.DeleteVpnGatewayCmd;1 -deleteVpnConnection=com.cloud.api.commands.DeleteVpnConnectionCmd;1 -updateVpnCustomerGateway=com.cloud.api.commands.UpdateVpnCustomerGatewayCmd;1 -resetVpnConnection=com.cloud.api.commands.ResetVpnConnectionCmd;1 -listVpnCustomerGateways=com.cloud.api.commands.ListVpnCustomerGatewaysCmd;15 -listVpnGateways=com.cloud.api.commands.ListVpnGatewaysCmd;15 -listVpnConnections=com.cloud.api.commands.ListVpnConnectionsCmd;15 + +### Site-to-site VPN commands +createVpnCustomerGateway=com.cloud.api.commands.CreateVpnCustomerGatewayCmd;1 +createVpnGateway=com.cloud.api.commands.CreateVpnGatewayCmd;1 +createVpnConnection=com.cloud.api.commands.CreateVpnConnectionCmd;1 +deleteVpnCustomerGateway=com.cloud.api.commands.DeleteVpnCustomerGatewayCmd;1 +deleteVpnGateway=com.cloud.api.commands.DeleteVpnGatewayCmd;1 +deleteVpnConnection=com.cloud.api.commands.DeleteVpnConnectionCmd;1 +updateVpnCustomerGateway=com.cloud.api.commands.UpdateVpnCustomerGatewayCmd;1 +resetVpnConnection=com.cloud.api.commands.ResetVpnConnectionCmd;1 +listVpnCustomerGateways=com.cloud.api.commands.ListVpnCustomerGatewaysCmd;15 +listVpnGateways=com.cloud.api.commands.ListVpnGatewaysCmd;15 +listVpnConnections=com.cloud.api.commands.ListVpnConnectionsCmd;15 diff --git a/core/src/com/cloud/network/resource/NetscalerResource.java b/core/src/com/cloud/network/resource/NetscalerResource.java index c7b31f31464..230104520e0 100644 --- a/core/src/com/cloud/network/resource/NetscalerResource.java +++ b/core/src/com/cloud/network/resource/NetscalerResource.java @@ -1,1533 +1,2138 @@ -// 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.resource; - -import java.util.List; -import java.util.Map; -import javax.naming.ConfigurationException; -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; -import com.cloud.agent.api.MaintainCommand; -import com.cloud.agent.api.PingCommand; -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.IpAssocAnswer; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -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.DestinationTO; -import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO; -import com.cloud.host.Host; -import com.cloud.host.Host.Type; -import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; -import com.cloud.resource.ServerResource; -import com.cloud.serializer.GsonHelper; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -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; - static final int NS_NO_SERIVCE = 344; - static final int NS_OPERATION_NOT_PERMITTED = 257; - static final int NS_INTERFACE_ALREADY_BOUND_TO_VLAN = 2080; -} - -public class NetscalerResource implements ServerResource { - - // deployment configuration - private String _name; - private String _zoneId; - private String _physicalNetworkId; - private String _ip; - private String _username; - private String _password; - private String _publicInterface; - private String _privateInterface; - private Integer _numRetries; - private String _guid; - private boolean _inline; - private boolean _isSdx; - private boolean _cloudManaged; - private String _deviceName; - private String _publicIP; - private String _publicIPNetmask; - private String _publicIPGateway; - private String _publicIPVlan; - - private static final Logger s_logger = Logger.getLogger(NetscalerResource.class); - protected Gson _gson; - private String _objectNamePathSep = "-"; - - // interface to interact with VPX and MPX devices - com.citrix.netscaler.nitro.service.nitro_service _netscalerService ; - - // interface to interact with service VM of the SDX appliance - com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService; - - Long _timeout = new Long(100000); - base_response apiCallResult; - - public NetscalerResource () { - _gson = GsonHelper.getGsonLogger(); - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - try { - _name = (String) params.get("name"); - if (_name == null) { - throw new ConfigurationException("Unable to find name in the configuration parameters"); - } - - _zoneId = (String) params.get("zoneId"); - if (_zoneId == null) { - throw new ConfigurationException("Unable to find zone Id in the configuration parameters"); - } - - _physicalNetworkId = (String) params.get("physicalNetworkId"); - if (_physicalNetworkId == null) { - throw new ConfigurationException("Unable to find physical network id in the configuration parameters"); - } - - _ip = (String) params.get("ip"); - if (_ip == null) { - throw new ConfigurationException("Unable to find IP address in the configuration parameters"); - } - - _username = (String) params.get("username"); - if (_username == null) { - throw new ConfigurationException("Unable to find username in the configuration parameters"); - } - - _password = (String) params.get("password"); - if (_password == null) { - throw new ConfigurationException("Unable to find password in the configuration parameters"); - } - - _publicInterface = (String) params.get("publicinterface"); - if (_publicInterface == null) { - throw new ConfigurationException("Unable to find public interface in the configuration parameters"); - } - - _privateInterface = (String) params.get("privateinterface"); - if (_privateInterface == null) { - throw new ConfigurationException("Unable to find private interface in the configuration parameters"); - } - - _numRetries = NumbersUtil.parseInt((String) params.get("numretries"), 2); - - _guid = (String)params.get("guid"); - if (_guid == null) { - throw new ConfigurationException("Unable to find the guid in the configuration parameters"); - } - - _deviceName = (String) params.get("deviceName"); - if (_deviceName == null) { - throw new ConfigurationException("Unable to find the device name in the configuration parameters"); - } - - _isSdx = _deviceName.equalsIgnoreCase("NetscalerSDXLoadBalancer"); - - _inline = Boolean.parseBoolean((String) params.get("inline")); - - if (((String) params.get("cloudmanaged")) != null) { - _cloudManaged = Boolean.parseBoolean((String) params.get("cloudmanaged")); - } - - // validate device configuration parameters - login(); - validateDeviceType(_deviceName); - validateInterfaces(_publicInterface, _privateInterface); - - //enable load balancing feature - enableLoadBalancingFeature(); - - //if the the device is cloud stack provisioned then make it part of the public network - if (_cloudManaged) { - _publicIP = (String) params.get("publicip"); - _publicIPGateway = (String) params.get("publicipgateway"); - _publicIPNetmask = (String) params.get("publicipnetmask"); - _publicIPVlan = (String) params.get("publicipvlan"); - if ("untagged".equalsIgnoreCase(_publicIPVlan)) { - // 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 - addGuestVlanAndSubnet(Long.parseLong(_publicIPVlan), _publicIP, _publicIPNetmask, false); - } - } - - return true; - } catch (Exception e) { - throw new ConfigurationException(e.getMessage()); - } - } - - private void login() throws ExecutionException { - try { - if (!_isSdx) { - _netscalerService = new nitro_service(_ip, "https"); - _netscalerService.set_credential(_username, _password); - _netscalerService.set_timeout(_timeout); - apiCallResult = _netscalerService.login(); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message); - } - } else { - _netscalerSdxService = new com.citrix.sdx.nitro.service.nitro_service(_ip, "https"); - _netscalerSdxService.set_credential(_username, _password); - com.citrix.sdx.nitro.resource.base.login login = _netscalerSdxService.login(); - if (login == null) { - throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message); - } - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); - } - } - - private void enableLoadBalancingFeature() throws ExecutionException { - if (_isSdx) { - return; - } - try { - String[] features = _netscalerService.get_enabled_features(); - if (features != null) { - for (String feature : features) { - if (feature.equalsIgnoreCase("LB")) { - return; - } - } - } - - // enable load balancing on the device - String[] feature = new String[1]; - feature[0] = "LB"; - apiCallResult = _netscalerService.enable_features(feature); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Enabling load balancing feature on the device failed."); - } - } catch (nitro_exception e) { - throw new ExecutionException("Enabling load balancing feature on the device failed due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Enabling load balancing feature on the device failed due to " + e.getMessage()); - } - } - - private void validateInterfaces(String publicInterface, String privateInterface) throws ExecutionException { - try { - if (!_isSdx && !_cloudManaged) { - Interface publicIf = Interface.get(_netscalerService, publicInterface); - Interface privateIf = Interface.get(_netscalerService, privateInterface); - if (publicIf != null || privateIf != null) { - return; - } else { - throw new ExecutionException("Invalid interface name specified for public/private interfaces."); - } - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - throw new ExecutionException("Invalid interface name specified for public and private interfaces."); - } else { - throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage()); - } - } - - private void validateDeviceType(String deviceType) throws ExecutionException { - try { - if (!_isSdx && !_cloudManaged) { - nshardware nsHw = com.citrix.netscaler.nitro.resource.config.ns.nshardware.get(_netscalerService); - if (nsHw == null) { - throw new ExecutionException("Failed to get the hardware description of the Netscaler device at " + _ip); - } else { - if ((_deviceName.equalsIgnoreCase("NetscalerMPXLoadBalancer") && nsHw.get_hwdescription().contains("MPX")) - || (_deviceName.equalsIgnoreCase("NetscalerVPXLoadBalancer") && nsHw.get_hwdescription().contains("NetScaler Virtual Appliance"))) { - return; - } - throw new ExecutionException("Netscalar device type specified does not match with the actuall device type."); - } - } else if (_isSdx) { - mps serviceVM = mps.get(_netscalerSdxService); - if (serviceVM != null) { - if (serviceVM.get_platform().contains("SDX") || serviceVM.get_product().contains("SDX")) { - return; - } else { - throw new ExecutionException("Netscalar device type specified does not match with the actuall device type."); - } - } else { - throw new ExecutionException("Failed to get the hardware details of the Netscaler device at " + _ip); - } - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify device type specified when matching with actuall device type due to " + e.getMessage()); - } - } - - @Override - public StartupCommand[] initialize() { - StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand(); - cmd.setName(_name); - cmd.setDataCenter(_zoneId); - cmd.setPod(""); - cmd.setPrivateIpAddress(_ip); - cmd.setStorageIpAddress(""); - cmd.setVersion(""); - cmd.setGuid(_guid); - return new StartupCommand[]{cmd}; - } - - @Override - public Answer executeRequest(Command cmd) { - return executeRequest(cmd, _numRetries); - } - - private Answer executeRequest(Command cmd, int numRetries) { - if (cmd instanceof ReadyCommand) { - return execute((ReadyCommand) cmd); - } else if (cmd instanceof MaintainCommand) { - return execute((MaintainCommand) cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand) cmd, numRetries); - } else if (cmd instanceof LoadBalancerConfigCommand) { - return execute((LoadBalancerConfigCommand) cmd, numRetries); - } else if (cmd instanceof ExternalNetworkResourceUsageCommand) { - return execute((ExternalNetworkResourceUsageCommand) cmd, numRetries); - } else if (cmd instanceof CreateLoadBalancerApplianceCommand) { - return execute((CreateLoadBalancerApplianceCommand) cmd, numRetries); - } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) { - return execute((DestroyLoadBalancerApplianceCommand) cmd, numRetries); - } else if (cmd instanceof SetStaticNatRulesCommand) { - return execute((SetStaticNatRulesCommand) cmd, numRetries); - } else { - return Answer.createUnsupportedCommandAnswer(cmd); - } - } - - private Answer execute(ReadyCommand cmd) { - return new ReadyAnswer(cmd); - } - - protected Answer execute(MaintainCommand cmd) { - return new MaintainAnswer(cmd); - } - - private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { - if (_isSdx) { - return Answer.createUnsupportedCommandAnswer(cmd); - } - - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; - try { - IpAddressTO[] ips = cmd.getIpAddresses(); - for (IpAddressTO ip : ips) { - long guestVlanTag = Long.valueOf(ip.getVlanId()); - String vlanSelfIp = ip.getVlanGateway(); - String vlanNetmask = ip.getVlanNetmask(); - - if (ip.isAdd()) { - // Add a new guest VLAN and its subnet and bind it to private interface - addGuestVlanAndSubnet(guestVlanTag, vlanSelfIp, vlanNetmask, true); - } else { - // Check and delete guest VLAN with this tag, self IP, and netmask - deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask); - } - - saveConfiguration(); - results[i++] = ip.getPublicIp() + " - success"; - String action = ip.isAdd() ? "associate" : "remove"; - if (s_logger.isDebugEnabled()) { - s_logger.debug("Netscaler load balancer " + _ip + " successfully executed IPAssocCommand to " + action + " IP " + ip); - } - } - } catch (ExecutionException e) { - s_logger.error("Netscaler loadbalancer " + _ip+ " failed to execute IPAssocCommand due to " + e.getMessage()); - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } else { - results[i++] = IpAssocAnswer.errorResult; - } - } - - return new IpAssocAnswer(cmd, results); - } - - private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) { - try { - if (_isSdx) { - return Answer.createUnsupportedCommandAnswer(cmd); - } - - LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers(); - if (loadBalancers == null) { - return new Answer(cmd); - } - - for (LoadBalancerTO loadBalancer : loadBalancers) { - String srcIp = loadBalancer.getSrcIp(); - int srcPort = loadBalancer.getSrcPort(); - String lbProtocol = getNetScalerProtocol(loadBalancer); - String lbAlgorithm = loadBalancer.getAlgorithm(); - String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); - - boolean destinationsToAdd = false; - for (DestinationTO destination : loadBalancer.getDestinations()) { - if (!destination.isRevoked()) { - destinationsToAdd = true; - break; - } - } - - if (!loadBalancer.isRevoked() && destinationsToAdd) { - - // create a load balancing virtual server - addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies()); - 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 - - // add a new server - if (!nsServerExists(nsServerName)) { - com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server(); - nsServer.set_name(nsServerName); - nsServer.set_ipaddress(destination.getDestIp()); - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(_netscalerService, nsServer); - if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) { - throw new ExecutionException("Failed to add server " + destination.getDestIp() + " due to" + apiCallResult.message); - } - } - - // create a new service using the server added - if (!nsServiceExists(nsServiceName)) { - com.citrix.netscaler.nitro.resource.config.basic.service newService = new com.citrix.netscaler.nitro.resource.config.basic.service(); - newService.set_name(nsServiceName); - newService.set_port(destination.getDestPort()); - newService.set_servername(nsServerName); - newService.set_state("ENABLED"); - newService.set_servicetype(lbProtocol); - - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.add(_netscalerService, newService); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to create service " + nsServiceName + " using server " + nsServerName + " due to" + apiCallResult.message); - } - } - - //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"); - } - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " + srcIp + ":" + srcPort); - } - } else { - // remove a destination from the deployed load balancing rule - 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) { - if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) { - // delete the binding - apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding); - 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 - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, nsServiceName); - if (apiCallResult.errorcode != 0) { - 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)) { - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); - } - } - } - } - } - } - } - } else { - // 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(); - apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding); - 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(); - - // check if service is bound to any other virtual server - if (!isServiceBoundToVirtualServer(serviceName)) { - // no lb virtual servers are bound to this service so delete it - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, serviceName); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to delete service: " + serviceName + " due to " + apiCallResult.message); - } - } - - //delete the server if no more services attached - server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName); - if ((services == null) || (services.length == 0)) { - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); - } - } - } - } - removeLBVirtualServer(nsVirtualServerName); - } - } - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd)); - } - - saveConfiguration(); - return new Answer(cmd); - } catch (ExecutionException e) { - s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage()); - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } else { - return new Answer(cmd, e); - } - } catch (Exception e) { - s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage()); - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } else { - return new Answer(cmd, e); - } - } - } - - private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) { - - if (!_isSdx) { - return Answer.createUnsupportedCommandAnswer(cmd); - } - - try { - String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP(); - String username = "admin"; - String password = "admin"; - - ns ns_obj = new ns(); - ns_obj.set_name(vpxName); - ns_obj.set_ip_address(cmd.getLoadBalancerIP()); - ns_obj.set_netmask(cmd.getNetmask()); - ns_obj.set_gateway(cmd.getGateway()); - ns_obj.set_username(username); - ns_obj.set_password(password); - - // configure VPX instances with defaults - ns_obj.set_feature_license("Standard"); - ns_obj.set_memory_total(new Double(2048)); - ns_obj.set_throughput(new Double(1000)); - ns_obj.set_pps(new Double(1000000)); - ns_obj.set_number_of_ssl_cores(0); - - // 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.")); - } - String profileName = profiles[0].get_name(); - ns_obj.set_nsroot_profile(profileName); - - // use the first VPX image of the available VPX images on the SDX to create an instance of VPX - // 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.")); - } - String imageName = vpxImages[0].get_file_name(); - ns_obj.set_image_name(imageName); - - String publicIf = _publicInterface; - String privateIf = _privateInterface; - - // enable only the interfaces that will be used by VPX - enableVPXInterfaces(_publicInterface, _privateInterface, ns_obj); - - // create new VPX instance - ns newVpx = ns.add(_netscalerSdxService, ns_obj); - - if (newVpx == null) { - new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip)); - } - - // wait for VPX instance to start-up - long startTick = System.currentTimeMillis(); - long startWaitMilliSeconds = 600000; - while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) { - try { - Thread.sleep(10000); - } catch(InterruptedException e) { - } - ns refreshNsObj = new ns(); - refreshNsObj.set_id(newVpx.get_id()); - newVpx = ns.get(_netscalerSdxService, refreshNsObj); - } - - // if vpx instance never came up then error out - if (!newVpx.get_ns_state().equalsIgnoreCase("up")) { - return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip)); - } - - // wait till NS service in side VPX is actually ready - startTick = System.currentTimeMillis(); - boolean nsServiceUp = false; - long nsServiceWaitMilliSeconds = 60000; - while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) { - try { - nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https"); - _netscalerService.set_credential(username, password); - _netscalerService.set_timeout(_timeout); - apiCallResult = _netscalerService.login(); - if (apiCallResult.errorcode == 0) { - nsServiceUp = true; - break; - } - } catch (Exception e) { - Thread.sleep(10000); - continue; - } - } - - if (!nsServiceUp) { - return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip)); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip); - } - - // physical interfaces on the SDX range from 10/1 to 10/8 & 1/1 to 1/8 of which two different port or same port can be used for public and private interfaces - // However the VPX instances created will have interface range start from 10/1 but will only have as many interfaces enabled while creating the VPX instance - // So due to this, we need to map public & private interface on SDX to correct public & private interface of VPX - - int publicIfnum = Integer.parseInt(_publicInterface.substring(_publicInterface.lastIndexOf("/") + 1)); - int privateIfnum = Integer.parseInt(_privateInterface.substring(_privateInterface.lastIndexOf("/") + 1)); - - if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("10/")) { - if (publicIfnum == privateIfnum) { - publicIf = "10/1"; - privateIf = "10/1"; - } else if (publicIfnum > privateIfnum) { - privateIf = "10/1"; - publicIf = "10/2"; - } else { - publicIf = "10/1"; - privateIf = "10/2"; - } - } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("1/")) { - if (publicIfnum == privateIfnum) { - publicIf = "1/1"; - privateIf = "1/1"; - } else if (publicIfnum > privateIfnum) { - privateIf = "1/1"; - publicIf = "1/2"; - } else { - publicIf = "1/1"; - privateIf = "1/2"; - } - } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("10/")) { - publicIf = "1/1"; - privateIf = "10/1"; - } else if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("1/")) { - publicIf = "10/1"; - privateIf = "1/1"; - } - - return new CreateLoadBalancerApplianceAnswer(cmd, true, "provisioned VPX instance", "NetscalerVPXLoadBalancer", "Netscaler", new NetscalerResource(), - publicIf, privateIf, _username, _password); - } catch (Exception e) { - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } - return new CreateLoadBalancerApplianceAnswer(cmd, false, "failed to provisioned VPX instance due to " + e.getMessage(), null, null, null, null, null, null, null); - } - } - - private void enableVPXInterfaces(String publicIf, String privateIf, ns ns_obj) { - // enable VPX to use 10 gigabit Ethernet interfaces if public/private interface - // on SDX is a 10Gig interface - if (publicIf.equals("10/1") || privateIf.equals("10/1")) { - ns_obj.set_if_10_1(new Boolean(true)); - } - - if (publicIf.equals("10/2") || privateIf.equals("10/2")) { - ns_obj.set_if_10_2(new Boolean(true)); - } - - if (publicIf.equals("10/3") || privateIf.equals("10/3")) { - ns_obj.set_if_10_3(new Boolean(true)); - } - - if (publicIf.equals("10/4") || privateIf.equals("10/4")) { - ns_obj.set_if_10_4(new Boolean(true)); - } - - if (publicIf.equals("10/5") || privateIf.equals("10/5")) { - ns_obj.set_if_10_5(new Boolean(true)); - } - - if (publicIf.equals("10/6") || privateIf.equals("10/6")) { - ns_obj.set_if_10_6(new Boolean(true)); - } - - if (publicIf.equals("10/7") || privateIf.equals("10/7")) { - ns_obj.set_if_10_7(new Boolean(true)); - } - - if (publicIf.equals("10/8") || privateIf.equals("10/8")) { - ns_obj.set_if_10_8(new Boolean(true)); - } - - // enable VPX to use 1 gigabit Ethernet interfaces if public/private interface - // on SDX is a 1Gig interface - if (publicIf.equals("1/1") || privateIf.equals("1/1")) { - ns_obj.set_if_1_1(new Boolean(true)); - } - - if (publicIf.equals("1/2") || privateIf.equals("1/2")) { - ns_obj.set_if_1_2(new Boolean(true)); - } - - if (publicIf.equals("1/3") || privateIf.equals("1/3")) { - ns_obj.set_if_1_3(new Boolean(true)); - } - - if (publicIf.equals("1/4") || privateIf.equals("1/4")) { - ns_obj.set_if_1_4(new Boolean(true)); - } - - if (publicIf.equals("1/5") || privateIf.equals("1/5")) { - ns_obj.set_if_1_5(new Boolean(true)); - } - - if (publicIf.equals("1/6") || privateIf.equals("1/6")) { - ns_obj.set_if_1_6(new Boolean(true)); - } - - if (publicIf.equals("1/7") || privateIf.equals("1/7")) { - ns_obj.set_if_1_7(new Boolean(true)); - } - - if (publicIf.equals("1/8") || privateIf.equals("1/8")) { - ns_obj.set_if_1_8(new Boolean(true)); - } - } - - private synchronized Answer execute(DestroyLoadBalancerApplianceCommand cmd, int numRetries) { - String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP(); - if (!_isSdx) { - return Answer.createUnsupportedCommandAnswer(cmd); - } - - try { - ns vpxToDelete =null; - ns[] vpxInstances = ns.get(_netscalerSdxService); - for (ns vpx : vpxInstances) { - if (vpx.get_name().equals(vpxName)) { - vpxToDelete = vpx; - break; - } - } - - if (vpxToDelete == null) { - String msg = "There is no VPX instance " + vpxName + " on the Netscaler SDX device " + _ip + " to delete"; - s_logger.warn(msg); - return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg); - } - - // destroy the VPX instance - ns nsDelObj = new ns(); - nsDelObj.set_id(vpxToDelete.get_id()); - vpxToDelete = ns.delete(_netscalerSdxService, nsDelObj); - String msg = "Deleted VPX instance " + vpxName + " on Netscaler SDX " + _ip + " successfully."; - s_logger.info(msg); - return new DestroyLoadBalancerApplianceAnswer(cmd, true,msg); - } catch (Exception e) { - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } - return new DestroyLoadBalancerApplianceAnswer(cmd, false, "Failed to delete VPX instance " + vpxName + " on Netscaler SDX " + _ip); - } - } - - private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) { - - if (_isSdx) { - return Answer.createUnsupportedCommandAnswer(cmd); - } - - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - - try { - for (StaticNatRuleTO rule : cmd.getRules()) { - String srcIp = rule.getSrcIp(); - String dstIP = rule.getDstIp(); - String iNatRuleName = generateInatRuleName(srcIp, dstIP); - inat iNatRule = null; - - if (!rule.revoked()) { - try { - iNatRule = inat.get(_netscalerService, iNatRuleName); - } catch (nitro_exception e) { - if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { - throw e; - } - } - - if (iNatRule == null) { - iNatRule = new inat(); - iNatRule.set_name(iNatRuleName); - iNatRule.set_publicip(srcIp); - iNatRule.set_privateip(dstIP); - iNatRule.set_usnip("OFF"); - iNatRule.set_usip("ON"); - try { - apiCallResult = inat.add(_netscalerService, iNatRule); - } catch (nitro_exception e) { - if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) { - throw e; - } - } - s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " + srcIp + " to " + dstIP); - } - } else { - try { - inat.delete(_netscalerService, iNatRuleName); - } catch (nitro_exception e) { - if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { - throw e; - } - } - s_logger.debug("Deleted Inat rule on the Netscaler device " + _ip + " to remove static NAT from " + srcIp + " to " + dstIP); - } - - saveConfiguration(); - results[i++] = "Static nat rule from " + srcIp + " to " + dstIP + " successfully " + (rule.revoked() ? " revoked.":" created."); - } - } catch (Exception e) { - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } - results[i++] = "Configuring static nat rule failed due to " + e.getMessage(); - endResult = false; - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) { - try { - if (!_isSdx) { - return getPublicIpBytesSentAndReceived(cmd); - } else { - return Answer.createUnsupportedCommandAnswer(cmd); - } - } catch (ExecutionException e) { - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } else { - return new ExternalNetworkResourceUsageAnswer(cmd, e); - } - } - } - - private void addSubnetIP(String snip, String netmask) throws ExecutionException { - try { - nsip selfIp = new nsip(); - selfIp.set_ipaddress(snip); - selfIp.set_netmask(netmask); - selfIp.set_type("SNIP"); - apiCallResult = nsip.add(_netscalerService, selfIp); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to "+ apiCallResult.message); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage()); - } - } - - private void addGuestVlanAndSubnet(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean guestVlan) throws ExecutionException { - try { - // add vlan object for guest VLAN - if (!nsVlanExists(vlanTag)) { - try { - vlan vlanObj = new vlan(); - vlanObj.set_id(vlanTag); - apiCallResult = vlan.add(_netscalerService, vlanObj); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + e.getMessage()); - } - } - - // add subnet IP object for this guest network - if (!nsSnipExists(vlanSelfIp)) { - try { - nsip selfIp = new nsip(); - selfIp.set_ipaddress(vlanSelfIp); - selfIp.set_netmask(vlanNetmask); - selfIp.set_type("SNIP"); - apiCallResult = nsip.add(_netscalerService, selfIp); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to "+ apiCallResult.message); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + e.getMessage()); - } - } - - // bind the vlan object to subnet IP object - if (!nsVlanNsipBindingExists(vlanTag, vlanSelfIp)) { - try { - vlan_nsip_binding ipVlanBinding = new vlan_nsip_binding(); - ipVlanBinding.set_id(vlanTag); - ipVlanBinding.set_ipaddress(vlanSelfIp); - ipVlanBinding.set_netmask(vlanNetmask); - apiCallResult = vlan_nsip_binding.add(_netscalerService, ipVlanBinding); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to bind VLAN with tag:" + vlanTag + " to the subnet due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to bind VLAN with tage:"+ vlanTag + " to the subnet due to " + e.getMessage()); - } - } - - // bind vlan object to the private interface - try { - vlan_interface_binding vlanBinding = new vlan_interface_binding(); - if (guestVlan) { - vlanBinding.set_ifnum(_privateInterface); - } else { - vlanBinding.set_ifnum(_publicInterface); - } - vlanBinding.set_tagged(true); - vlanBinding.set_id(vlanTag); - apiCallResult = vlan_interface_binding.add(_netscalerService, vlanBinding); - if (apiCallResult.errorcode != 0) { - String vlanInterface = guestVlan ? _privateInterface : _publicInterface; - throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - if (!(e.getErrorCode() == NitroError.NS_INTERFACE_ALREADY_BOUND_TO_VLAN)) { - throw new ExecutionException("Failed to bind VLAN "+ vlanTag + " with interface on the Netscaler device due to " + e.getMessage()); - } - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage()); - } - } - - private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { - try { - - // Delete all servers and associated services from this guest VLAN - deleteServersInGuestVlan(vlanTag, vlanSelfIp, vlanNetmask); - - // unbind vlan to the private interface - try { - vlan_interface_binding vlanIfBinding = new vlan_interface_binding(); - vlanIfBinding.set_id(vlanTag); - vlanIfBinding.set_ifnum(_privateInterface); - vlanIfBinding.set_tagged(true); - apiCallResult = vlan_interface_binding.delete(_netscalerService, vlanIfBinding); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the private interface due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - // if Vlan to interface binding does not exist then ignore the exception and proceed - if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { - throw new ExecutionException("Failed to unbind vlan from the interface while shutdown of guest network on the Netscaler device due to " + e.getMessage()); - } - } - - // unbind the vlan to subnet - try { - vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding(); - vlanSnipBinding.set_netmask(vlanNetmask); - vlanSnipBinding.set_ipaddress(vlanSelfIp); - vlanSnipBinding.set_id(vlanTag); - apiCallResult = vlan_nsip_binding.delete(_netscalerService, vlanSnipBinding); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - // if Vlan to subnet binding does not exist then ignore the exception and proceed - if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { - throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + e.getMessage()); - } - } - - // remove subnet IP - try { - nsip subnetIp = nsip.get(_netscalerService, vlanSelfIp); - apiCallResult = nsip.delete(_netscalerService, subnetIp); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + apiCallResult.message); - } - } catch (nitro_exception e) { - // if subnet SNIP does not exist then ignore the exception and proceed - if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { - throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + e.getMessage()); - } - } - - // remove the vlan from the NetScaler device - if (nsVlanExists(vlanTag)) { - // remove vlan - apiCallResult = com.citrix.netscaler.nitro.resource.config.network.vlan.delete(_netscalerService, vlanTag); - 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) { - throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); - } - } - - private boolean nsVlanExists(long vlanTag) throws ExecutionException { - try { - if (vlan.get(_netscalerService, new Long(vlanTag)) != null) { - return true; - } else { - return false; - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return false; - } else { - throw new ExecutionException("Failed to verify VLAN exists on the NetScaler device due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify VLAN exists on the NetScaler device due to " + e.getMessage()); - } - } - - private boolean nsSnipExists(String subnetIP) throws ExecutionException { - try { - nsip snip = nsip.get(_netscalerService, subnetIP); - return (snip != null); - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return false; - } else { - throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage()); - } - } - - private boolean nsServerExists(String serverName) throws ExecutionException { - try { - if (com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService, serverName) != null) { - return true; - } else { - return false; - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return false; - } else { - throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage()); - } - } - - private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException { - try { - vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag); - if (vlanNsipBindings != null && vlanNsipBindings[0] != null && vlanNsipBindings[0].get_ipaddress().equalsIgnoreCase(vlanSelfIp)) { - return true; - } else { - return false; - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return false; - } else { - throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage()); - } - } - - private lbvserver getVirtualServerIfExisits(String lbVServerName ) throws ExecutionException { - try { - return lbvserver.get(_netscalerService, lbVServerName); - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return null; - } else { - throw new ExecutionException(e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException(e.getMessage()); - } - } - - private boolean isServiceBoundToVirtualServer(String serviceName) throws ExecutionException { - try { - lbvserver[] lbservers = lbvserver.get(_netscalerService); - 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); - if (result != null && result.length > 0) { - return true; - } - } - return false; - } catch (Exception e) { - 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) { - return true; - } else { - return false; - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_NO_SERIVCE) { - return false; - } else { - throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage()); - } - } - - private boolean nsServiceBindingExists(String lbVirtualServer, String serviceName) throws ExecutionException { - try { - com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, lbVirtualServer); - if (serviceBindings != null) { - for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) { - if (serviceName.equalsIgnoreCase(binding.get_servicename())) { - return true; - } - } - } - return false; - } catch (nitro_exception e) { - throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage()); - } - } - - private void deleteServersInGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { - try { - com.citrix.netscaler.nitro.resource.config.basic.server[] serverList = com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService); - - if (serverList == null) { - return; - } - - // remove the server and services associated with guest vlan - for (com.citrix.netscaler.nitro.resource.config.basic.server server : serverList) { - // check if server belong to same subnet as one associated with vlan - if (NetUtils.sameSubnet(vlanSelfIp, server.get_ipaddress(), vlanNetmask)) { - // first remove services associated with this server - com.citrix.netscaler.nitro.resource.config.basic.service serveicesList[] = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService); - if (serveicesList != null) { - for (com.citrix.netscaler.nitro.resource.config.basic.service svc : serveicesList) { - if (svc.get_servername().equals(server.get_ipaddress())) { - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, svc.get_name()); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove service:" + svc.get_name()); - } - } - } - } - // remove the server - apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, server.get_name()); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + server.get_name()); - } - } - } - } catch (Exception e) { - throw new ExecutionException("Failed to delete server and services in the guest vlan:" + vlanTag + " on the Netscaler device due to: "+ e.getMessage()); - } - } - - private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException { - String port = Integer.toString(loadBalancer.getSrcPort()); - String lbProtocol = loadBalancer.getProtocol(); - StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies(); - String nsProtocol = "TCP"; - - if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){ - StickinessPolicyTO stickinessPolicy = stickyPolicies[0]; - if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) || - (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) { - nsProtocol = "HTTP"; - return nsProtocol; - } - } - - if (port.equals(NetUtils.HTTP_PORT)) { - nsProtocol = "HTTP"; - } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) { - nsProtocol = "TCP"; - } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) { - nsProtocol = "UDP"; - } - - return nsProtocol; - } - - private void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies) throws ExecutionException { - try { - String lbMethod; - if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) { - lbMethod = "ROUNDROBIN"; - } else if ("leastconn".equalsIgnoreCase(lbAlgorithm)) { - lbMethod = "LEASTCONNECTION"; - } else if ("source".equalsIgnoreCase(lbAlgorithm)) { - lbMethod = "SOURCEIPHASH"; - } else { - throw new ExecutionException("Got invalid load balancing algorithm: " + lbAlgorithm + " in the load balancing rule"); - } - - boolean vserverExisis = false; - lbvserver vserver = getVirtualServerIfExisits(virtualServerName); - if (vserver == null) { - vserver = new lbvserver(); - } else { - if (!vserver.get_servicetype().equalsIgnoreCase(protocol)) { - throw new ExecutionException("Can not update virtual server:" + virtualServerName + " as current protocol:" + vserver.get_servicetype() + " of virtual server is different from the " - + " intended protocol:" + protocol); - } - vserverExisis = true; - } - vserver.set_name(virtualServerName); - vserver.set_ipv46(publicIp); - vserver.set_port(publicPort); - vserver.set_servicetype(protocol); - vserver.set_lbmethod(lbMethod); - - // netmask can only be set for source IP load balancer algorithm - if (!lbMethod.equalsIgnoreCase("SOURCEIPHASH")) { - vserver.set_netmask(null); - vserver.set_v6netmasklen(null); - } - - if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){ - long timeout = 2;// netscaler default 2 min - String cookieName = null; - StickinessPolicyTO stickinessPolicy = stickyPolicies[0]; - - // get the session persistence parameters - List> paramsList = stickinessPolicy.getParams(); - for(Pair param : paramsList) { - if ("holdtime".equalsIgnoreCase(param.first())) { - timeout = Long.parseLong(param.second()); - } else if ("name".equalsIgnoreCase(param.first())) { - cookieName = param.second(); - } - } - - // configure virtual server based on the persistence method - if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { - vserver.set_persistencetype("COOKIEINSERT"); - } else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { - vserver.set_persistencetype("SOURCEIP"); - } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { - vserver.set_persistencetype("RULE"); - vserver.set_rule("HTTP.REQ.HEADER(\"COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")"); - vserver.set_resrule("HTTP.RES.HEADER(\"SET-COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")"); - } else { - throw new ExecutionException("Got invalid session persistence method: " + stickinessPolicy.getMethodName() + " in the load balancing rule"); - } - - // set session persistence timeout - vserver.set_timeout(timeout); - } else { - if (vserver.get_persistencetype() != null) { - // delete the LB stickyness policy - vserver.set_persistencetype("NONE"); - } - } - - if (vserverExisis) { - apiCallResult = lbvserver.update(_netscalerService,vserver); - } else { - apiCallResult = lbvserver.add(_netscalerService,vserver); - } - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to create new load balancing virtual server:" + virtualServerName + " due to " + apiCallResult.message); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Created load balancing virtual server " + virtualServerName + " on the Netscaler device"); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage()); - } - } - - private void removeLBVirtualServer (String virtualServerName) throws ExecutionException { - try { - lbvserver vserver = lbvserver.get(_netscalerService, virtualServerName); - if (vserver == null) { - return; - } - apiCallResult = lbvserver.delete(_netscalerService, vserver); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to delete virtual server:" + virtualServerName + " due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { - return; - } else { - throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage()); - } - } catch (Exception e) { - throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); - } - } - - private void saveConfiguration() throws ExecutionException { - try { - apiCallResult = nsconfig.save(_netscalerService); - if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message); - } - } catch (nitro_exception e) { - throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage()); - } catch (Exception e) { - throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage()); - } - } - - private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException { - ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd); - - try { - lbvserver_stats[] stats = lbvserver_stats.get(_netscalerService); - - if (stats == null || stats.length == 0) { - return answer; - } - - for (lbvserver_stats stat_entry : stats) { - String lbvserverName = stat_entry.get_name(); - 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); - } - } - } - } catch (Exception e) { - s_logger.error("Failed to get bytes sent and recived statistics due to " + e); - throw new ExecutionException(e.getMessage()); - } - - return answer; - } - - private Answer retry(Command cmd, int numRetries) { - int numRetriesRemaining = numRetries - 1; - s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining); - return executeRequest(cmd, numRetriesRemaining); - } - - private boolean shouldRetry(int numRetries) { - try { - if (numRetries > 0) { - login(); - return true; - } - } catch (Exception e) { - s_logger.error("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); - } - return false; - } - - private String generateInatRuleName(String srcIp, String dstIP) { - return genObjectName("Cloud-Inat", srcIp); - } - - private String generateNSVirtualServerName(String srcIp, long srcPort) { - return genObjectName("Cloud-VirtualServer", srcIp, srcPort); - } - - private String generateNSServerName(String serverIP) { - return genObjectName("Cloud-Server-", serverIP); - } - - private String generateNSServiceName(String ip, long port) { - return genObjectName("Cloud-Service", ip, port); - } - - private String genObjectName(Object... args) { - String objectName = ""; - for (int i = 0; i < args.length; i++) { - objectName += args[i]; - if (i != args.length -1) { - objectName += _objectNamePathSep; - } - } - return objectName; - } - - @Override - public IAgentControl getAgentControl() { - return null; - } - - @Override - public PingCommand getCurrentStatus(long id) { - return new PingCommand(Host.Type.ExternalLoadBalancer, id); - } - - @Override - public Type getType() { - return Host.Type.ExternalLoadBalancer; - } - - @Override - public void setAgentControl(IAgentControl agentControl) { - return; - } - - @Override - public String getName() { - return _name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public void disconnected() { - return; - } -} \ No newline at end of file +// 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.resource; + +import java.util.ArrayList; +import java.util.Collections; +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.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.ExternalNetworkResourceUsageAnswer; +import com.cloud.agent.api.ExternalNetworkResourceUsageCommand; +import com.cloud.agent.api.MaintainAnswer; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.agent.api.PingCommand; +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; +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.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; +import com.cloud.resource.ServerResource; +import com.cloud.serializer.GsonHelper; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.ExecutionException; +import com.cloud.utils.net.NetUtils; +import com.google.gson.Gson; + +class NitroError { + static final int NS_RESOURCE_EXISTS = 273; + static final int NS_RESOURCE_NOT_EXISTS=258; + static final int NS_NO_SERIVCE = 344; + static final int NS_OPERATION_NOT_PERMITTED = 257; + static final int NS_INTERFACE_ALREADY_BOUND_TO_VLAN = 2080; +} + +public class NetscalerResource implements ServerResource { + + // deployment configuration + private String _name; + private String _zoneId; + private String _physicalNetworkId; + private String _ip; + private String _username; + private String _password; + private String _publicInterface; + private String _privateInterface; + private Integer _numRetries; + private String _guid; + private boolean _inline; + private boolean _isSdx; + private boolean _cloudManaged; + private String _deviceName; + private String _publicIP; + private String _publicIPNetmask; + private String _publicIPGateway; + private String _publicIPVlan; + + private static final Logger s_logger = Logger.getLogger(NetscalerResource.class); + protected Gson _gson; + private String _objectNamePathSep = "-"; + + // interface to interact with VPX and MPX devices + com.citrix.netscaler.nitro.service.nitro_service _netscalerService ; + + // interface to interact with service VM of the SDX appliance + com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService; + + Long _timeout = new Long(100000); + base_response apiCallResult; + + public NetscalerResource () { + _gson = GsonHelper.getGsonLogger(); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + try { + _name = (String) params.get("name"); + if (_name == null) { + throw new ConfigurationException("Unable to find name in the configuration parameters"); + } + + _zoneId = (String) params.get("zoneId"); + if (_zoneId == null) { + throw new ConfigurationException("Unable to find zone Id in the configuration parameters"); + } + + _physicalNetworkId = (String) params.get("physicalNetworkId"); + if (_physicalNetworkId == null) { + throw new ConfigurationException("Unable to find physical network id in the configuration parameters"); + } + + _ip = (String) params.get("ip"); + if (_ip == null) { + throw new ConfigurationException("Unable to find IP address in the configuration parameters"); + } + + _username = (String) params.get("username"); + if (_username == null) { + throw new ConfigurationException("Unable to find username in the configuration parameters"); + } + + _password = (String) params.get("password"); + if (_password == null) { + throw new ConfigurationException("Unable to find password in the configuration parameters"); + } + + _publicInterface = (String) params.get("publicinterface"); + if (_publicInterface == null) { + throw new ConfigurationException("Unable to find public interface in the configuration parameters"); + } + + _privateInterface = (String) params.get("privateinterface"); + if (_privateInterface == null) { + throw new ConfigurationException("Unable to find private interface in the configuration parameters"); + } + + _numRetries = NumbersUtil.parseInt((String) params.get("numretries"), 2); + + _guid = (String)params.get("guid"); + if (_guid == null) { + throw new ConfigurationException("Unable to find the guid in the configuration parameters"); + } + + _deviceName = (String) params.get("deviceName"); + if (_deviceName == null) { + throw new ConfigurationException("Unable to find the device name in the configuration parameters"); + } + + _isSdx = _deviceName.equalsIgnoreCase("NetscalerSDXLoadBalancer"); + + _inline = Boolean.parseBoolean((String) params.get("inline")); + + if (((String) params.get("cloudmanaged")) != null) { + _cloudManaged = Boolean.parseBoolean((String) params.get("cloudmanaged")); + } + + // validate device configuration parameters + login(); + validateDeviceType(_deviceName); + validateInterfaces(_publicInterface, _privateInterface); + + //enable load balancing feature + enableLoadBalancingFeature(); + + //if the the device is cloud stack provisioned then make it part of the public network + if (_cloudManaged) { + _publicIP = (String) params.get("publicip"); + _publicIPGateway = (String) params.get("publicipgateway"); + _publicIPNetmask = (String) params.get("publicipnetmask"); + _publicIPVlan = (String) params.get("publicipvlan"); + if ("untagged".equalsIgnoreCase(_publicIPVlan)) { + // 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 + addGuestVlanAndSubnet(Long.parseLong(_publicIPVlan), _publicIP, _publicIPNetmask, false); + } + } + + return true; + } catch (Exception e) { + throw new ConfigurationException(e.getMessage()); + } + } + + private void login() throws ExecutionException { + try { + if (!_isSdx) { + _netscalerService = new com.citrix.netscaler.nitro.service.nitro_service(_ip, "https"); + _netscalerService.set_credential(_username, _password); + _netscalerService.set_timeout(_timeout); + apiCallResult = _netscalerService.login(); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message); + } + } else { + _netscalerSdxService = new com.citrix.sdx.nitro.service.nitro_service(_ip, "https"); + _netscalerSdxService.set_credential(_username, _password); + com.citrix.sdx.nitro.resource.base.login login = _netscalerSdxService.login(); + if (login == null) { + throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message); + } + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); + } + } + + private void enableLoadBalancingFeature() throws ExecutionException { + if (_isSdx) { + return; + } + try { + String[] features = _netscalerService.get_enabled_features(); + if (features != null) { + for (String feature : features) { + if (feature.equalsIgnoreCase("LB")) { + return; + } + } + } + + // enable load balancing on the device + String[] feature = new String[1]; + feature[0] = "LB"; + apiCallResult = _netscalerService.enable_features(feature); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Enabling load balancing feature on the device failed."); + } + } catch (nitro_exception e) { + throw new ExecutionException("Enabling load balancing feature on the device failed due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Enabling load balancing feature on the device failed due to " + e.getMessage()); + } + } + + private void validateInterfaces(String publicInterface, String privateInterface) throws ExecutionException { + try { + if (!_isSdx && !_cloudManaged) { + Interface publicIf = Interface.get(_netscalerService, publicInterface); + Interface privateIf = Interface.get(_netscalerService, privateInterface); + if (publicIf != null || privateIf != null) { + return; + } else { + throw new ExecutionException("Invalid interface name specified for public/private interfaces."); + } + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + throw new ExecutionException("Invalid interface name specified for public and private interfaces."); + } else { + throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage()); + } + } + + private void validateDeviceType(String deviceType) throws ExecutionException { + try { + if (!_isSdx && !_cloudManaged) { + nshardware nsHw = com.citrix.netscaler.nitro.resource.config.ns.nshardware.get(_netscalerService); + if (nsHw == null) { + throw new ExecutionException("Failed to get the hardware description of the Netscaler device at " + _ip); + } else { + if ((_deviceName.equalsIgnoreCase("NetscalerMPXLoadBalancer") && nsHw.get_hwdescription().contains("MPX")) + || (_deviceName.equalsIgnoreCase("NetscalerVPXLoadBalancer") && nsHw.get_hwdescription().contains("NetScaler Virtual Appliance"))) { + return; + } + throw new ExecutionException("Netscalar device type specified does not match with the actuall device type."); + } + } else if (_isSdx) { + mps serviceVM = mps.get(_netscalerSdxService); + if (serviceVM != null) { + if (serviceVM.get_platform().contains("SDX") || serviceVM.get_product().contains("SDX")) { + return; + } else { + throw new ExecutionException("Netscalar device type specified does not match with the actuall device type."); + } + } else { + throw new ExecutionException("Failed to get the hardware details of the Netscaler device at " + _ip); + } + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify device type specified when matching with actuall device type due to " + e.getMessage()); + } + } + + @Override + public StartupCommand[] initialize() { + StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand(); + cmd.setName(_name); + cmd.setDataCenter(_zoneId); + cmd.setPod(""); + cmd.setPrivateIpAddress(_ip); + cmd.setStorageIpAddress(""); + cmd.setVersion(""); + cmd.setGuid(_guid); + return new StartupCommand[]{cmd}; + } + + @Override + public Answer executeRequest(Command cmd) { + return executeRequest(cmd, _numRetries); + } + + private Answer executeRequest(Command cmd, int numRetries) { + if (cmd instanceof ReadyCommand) { + return execute((ReadyCommand) cmd); + } else if (cmd instanceof MaintainCommand) { + return execute((MaintainCommand) cmd); + } else if (cmd instanceof IpAssocCommand) { + return execute((IpAssocCommand) cmd, numRetries); + } else if (cmd instanceof LoadBalancerConfigCommand) { + return execute((LoadBalancerConfigCommand) cmd, numRetries); + } else if (cmd instanceof ExternalNetworkResourceUsageCommand) { + return execute((ExternalNetworkResourceUsageCommand) cmd, numRetries); + } else if (cmd instanceof CreateLoadBalancerApplianceCommand) { + return execute((CreateLoadBalancerApplianceCommand) cmd, numRetries); + } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) { + return execute((DestroyLoadBalancerApplianceCommand) cmd, numRetries); + } else if (cmd instanceof SetStaticNatRulesCommand) { + return execute((SetStaticNatRulesCommand) cmd, numRetries); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } + + private Answer execute(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + protected Answer execute(MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } + + private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { + if (_isSdx) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + long guestVlanTag = Long.valueOf(ip.getVlanId()); + String vlanSelfIp = ip.getVlanGateway(); + String vlanNetmask = ip.getVlanNetmask(); + + if (ip.isAdd()) { + // Add a new guest VLAN and its subnet and bind it to private interface + addGuestVlanAndSubnet(guestVlanTag, vlanSelfIp, vlanNetmask, true); + } else { + // Check and delete guest VLAN with this tag, self IP, and netmask + deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask); + } + + saveConfiguration(); + results[i++] = ip.getPublicIp() + " - success"; + String action = ip.isAdd() ? "associate" : "remove"; + if (s_logger.isDebugEnabled()) { + s_logger.debug("Netscaler load balancer " + _ip + " successfully executed IPAssocCommand to " + action + " IP " + ip); + } + } + } catch (ExecutionException e) { + s_logger.error("Netscaler loadbalancer " + _ip+ " failed to execute IPAssocCommand due to " + e.getMessage()); + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } else { + results[i++] = IpAssocAnswer.errorResult; + } + } + + return new IpAssocAnswer(cmd, results); + } + + private boolean isScaleUpPolicy(AutoScalePolicyTO autoScalePolicyTO) { + return autoScalePolicyTO.getAction().equals("scaleup"); + } + + private boolean isScaleDownPolicy(AutoScalePolicyTO autoScalePolicyTO) { + return autoScalePolicyTO.getAction().equals("scaledown"); + } + + private long allocateNextAvailablePriority(List priorities) { + long cur_prirotiy = 1; + Collections.sort(priorities); + for (Long priority : priorities) { + if(cur_prirotiy != priority) { + priorities.add(cur_prirotiy); + return cur_prirotiy; + } + cur_prirotiy++; + } + return -1; + } + + @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(nsVirtualServerName); + + 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(nsVirtualServerName); + String timerName = generateAutoScaleTimerName(nsVirtualServerName); + String scaleDownActionName = generateAutoScaleScaleDownActionName(nsVirtualServerName); + String scaleUpActionName = generateAutoScaleScaleUpActionName(nsVirtualServerName); + String mtName = generateSnmpMetricTableName(nsVirtualServerName); + String monitorName = generateSnmpMonitorName(nsVirtualServerName); + if(!loadBalancerTO.isAutoScaleVmGroupTO()) + return true; + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + List policies = vmGroupTO.getPolicies(); + + /* Create Counters */ + for (AutoScalePolicyTO autoScalePolicyTO : policies) { + List conditions = autoScalePolicyTO.getConditions(); + for (ConditionTO conditionTO : conditions) { + CounterTO counterTO = conditionTO.getCounter(); + if(counterTO.getSource() == "snmp") + { + break; + } + } + String policyId = Long.toString(autoScalePolicyTO.getId()); + String policyName = generateAutoScalePolicyName(nsVirtualServerName,policyId); + // 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.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; + } + } + + /* 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; + } + + // 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.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_metric(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); + addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancerTO.getStickinessPolicies()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device"); + } + + String serviceGroupName = generateAutoScaleServiceGroupName(nsVirtualServerName); + if(!loadBalancerTO.isAutoScaleVmGroupTO()) + return true; + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + // 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_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(nsVirtualServerName); + String profileName = generateAutoScaleProfileName(nsVirtualServerName); + String timerName = generateAutoScaleTimerName(nsVirtualServerName); + String scaleDownActionName = generateAutoScaleScaleDownActionName(nsVirtualServerName); + String scaleUpActionName = generateAutoScaleScaleUpActionName(nsVirtualServerName); + String mtName = generateSnmpMetricTableName(nsVirtualServerName); + String monitorName = generateSnmpMonitorName(nsVirtualServerName); + if(!loadBalancerTO.isAutoScaleVmGroupTO()) + return true; + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + AutoScaleVmProfileTO profileTO = vmGroupTO.getProfile(); + List policies = vmGroupTO.getPolicies(); + int interval = vmGroupTO.getInterval(); + int snmpPort = profileTO.getSnmpPort(); + String snmpCommunity = profileTO.getSnmpCommunity(); + ArrayList priorities = new ArrayList(); + if(!vmGroupTO.isRevoked()) { + // 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_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 Counters */ + for (AutoScalePolicyTO autoScalePolicyTO : policies) { + boolean isPolicyRevoked = autoScalePolicyTO.isRevoked(); + List conditions = autoScalePolicyTO.getConditions(); + HashMap snmpMetrics = new HashMap(); + 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 = counterName.replace(' ', '_'); + 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_metric(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_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; + } + } + + // formatter.format("SYS.CUR_VSERVER.METRIC_TABLE(%s).AVG_VAL.%s(%ld)",counterName, operator, +// threshold); + boolean newMetric = !snmpMetrics.containsKey(counterName); + if(newMetric) { + snmpMetrics.put(counterName, snmpCounterNumber++); + } + formatter.format("SYS.VSERVER.SNMP_TABLE(%d).AVG_VAL.%s(%d)",snmpMetrics.get(counterName), operator, threshold); + + 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_metrictable(mtName); + 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; + } + } + } + else if (counterTO.getSource().equals("netscaler")) + { + formatter.format("SYS.VSERVER(%s).%s.AVG_VAL.%s(%d)",nsVirtualServerName, counterName, operator, threshold); + } + if(policyExpression.length() != 0) { + policyExpression += " && "; + } + policyExpression += conditionExpression; + } + policyExpression = "(" + policyExpression + ")"; + + String policyId = Long.toString(autoScalePolicyTO.getId()); + String policyName = generateAutoScalePolicyName(nsVirtualServerName,policyId); + if(!isPolicyRevoked) { + // 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((isScaleUpPolicy(autoScalePolicyTO))? scaleUpActionName : scaleDownActionName); + timerPolicy.set_rule(policyExpression); + timerPolicy.add(_netscalerService, timerPolicy); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // bind timer policy + // 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 = autoScalePolicyTO.getDuration()/interval; + long priority = allocateNextAvailablePriority(priorities); + try { + timer_policy_binding.set_name(timerName); + timer_policy_binding.set_policyname(policyName); + timer_policy_binding.set_vserver(nsVirtualServerName); + 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; + } + } + } + + return true; + } + + private synchronized void applyAutoScaleConfig(LoadBalancerTO loadBalancer) throws Exception, ExecutionException { + AutoScaleVmGroupTO vmGroupTO = loadBalancer.getAutoScaleVmGroupTO(); + if(vmGroupTO.getState().equals("New")) { + assert !loadBalancer.isRevoked(); + createAutoScaleConfig(loadBalancer); + } + if(loadBalancer.isRevoked() || vmGroupTO.getState().equals("Revoke")) { + removeAutoScaleConfig(loadBalancer); + } + if(vmGroupTO.getState().equals("Enabled")) { + assert !loadBalancer.isRevoked(); + enableAutoScaleConfig(loadBalancer); + } + if(vmGroupTO.getState().equals("Disabled")) { + assert !loadBalancer.isRevoked(); + disableAutoScaleConfig(loadBalancer); + } + } + + private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) { + try { + if (_isSdx) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers(); + if (loadBalancers == null) { + return new Answer(cmd); + } + + for (LoadBalancerTO loadBalancer : loadBalancers) { + String srcIp = loadBalancer.getSrcIp(); + int srcPort = loadBalancer.getSrcPort(); + String lbProtocol = getNetScalerProtocol(loadBalancer); + String lbAlgorithm = loadBalancer.getAlgorithm(); + String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + + if(loadBalancer.isAutoScaleVmGroupTO()) { + applyAutoScaleConfig(loadBalancer); + new Answer(cmd); + } + + boolean destinationsToAdd = false; + for (DestinationTO destination : loadBalancer.getDestinations()) { + if (!destination.isRevoked()) { + destinationsToAdd = true; + break; + } + } + + if (!loadBalancer.isRevoked() && destinationsToAdd) { + + // create a load balancing virtual server + addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies()); + 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 + + // add a new server + if (!nsServerExists(nsServerName)) { + com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server(); + nsServer.set_name(nsServerName); + nsServer.set_ipaddress(destination.getDestIp()); + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(_netscalerService, nsServer); + if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) { + throw new ExecutionException("Failed to add server " + destination.getDestIp() + " due to" + apiCallResult.message); + } + } + + // create a new service using the server added + if (!nsServiceExists(nsServiceName)) { + com.citrix.netscaler.nitro.resource.config.basic.service newService = new com.citrix.netscaler.nitro.resource.config.basic.service(); + newService.set_name(nsServiceName); + newService.set_port(destination.getDestPort()); + newService.set_servername(nsServerName); + newService.set_state("ENABLED"); + newService.set_servicetype(lbProtocol); + + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.add(_netscalerService, newService); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to create service " + nsServiceName + " using server " + nsServerName + " due to" + apiCallResult.message); + } + } + + //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"); + } + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " + srcIp + ":" + srcPort); + } + } else { + // remove a destination from the deployed load balancing rule + 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) { + if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) { + // delete the binding + apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding); + 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 + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, nsServiceName); + if (apiCallResult.errorcode != 0) { + 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)) { + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); + } + } + } + } + } + } + } + } else { + // 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(); + apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding); + 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(); + + // check if service is bound to any other virtual server + if (!isServiceBoundToVirtualServer(serviceName)) { + // no lb virtual servers are bound to this service so delete it + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, serviceName); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to delete service: " + serviceName + " due to " + apiCallResult.message); + } + } + + //delete the server if no more services attached + server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName); + if ((services == null) || (services.length == 0)) { + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); + } + } + } + } + removeLBVirtualServer(nsVirtualServerName); + } + } + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd)); + } + + saveConfiguration(); + return new Answer(cmd); + } catch (ExecutionException e) { + s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage()); + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } else { + return new Answer(cmd, e); + } + } catch (Exception e) { + s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage()); + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } else { + return new Answer(cmd, e); + } + } + } + + private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) { + + if (!_isSdx) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + try { + String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP(); + String username = "admin"; + String password = "admin"; + + ns ns_obj = new ns(); + ns_obj.set_name(vpxName); + ns_obj.set_ip_address(cmd.getLoadBalancerIP()); + ns_obj.set_netmask(cmd.getNetmask()); + ns_obj.set_gateway(cmd.getGateway()); + ns_obj.set_username(username); + ns_obj.set_password(password); + + // configure VPX instances with defaults + ns_obj.set_feature_license("Standard"); + ns_obj.set_memory_total(new Double(2048)); + ns_obj.set_throughput(new Double(1000)); + ns_obj.set_pps(new Double(1000000)); + ns_obj.set_number_of_ssl_cores(0); + + // 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.")); + } + String profileName = profiles[0].get_name(); + ns_obj.set_nsroot_profile(profileName); + + // use the first VPX image of the available VPX images on the SDX to create an instance of VPX + // 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.")); + } + String imageName = vpxImages[0].get_file_name(); + ns_obj.set_image_name(imageName); + + String publicIf = _publicInterface; + String privateIf = _privateInterface; + + // enable only the interfaces that will be used by VPX + enableVPXInterfaces(_publicInterface, _privateInterface, ns_obj); + + // create new VPX instance + ns newVpx = ns.add(_netscalerSdxService, ns_obj); + + if (newVpx == null) { + new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip)); + } + + // wait for VPX instance to start-up + long startTick = System.currentTimeMillis(); + long startWaitMilliSeconds = 600000; + while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) { + try { + Thread.sleep(10000); + } catch(InterruptedException e) { + } + ns refreshNsObj = new ns(); + refreshNsObj.set_id(newVpx.get_id()); + newVpx = ns.get(_netscalerSdxService, refreshNsObj); + } + + // if vpx instance never came up then error out + if (!newVpx.get_ns_state().equalsIgnoreCase("up")) { + return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip)); + } + + // wait till NS service in side VPX is actually ready + startTick = System.currentTimeMillis(); + boolean nsServiceUp = false; + long nsServiceWaitMilliSeconds = 60000; + while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) { + try { + nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https"); + _netscalerService.set_credential(username, password); + _netscalerService.set_timeout(_timeout); + apiCallResult = _netscalerService.login(); + if (apiCallResult.errorcode == 0) { + nsServiceUp = true; + break; + } + } catch (Exception e) { + Thread.sleep(10000); + continue; + } + } + + if (!nsServiceUp) { + return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip)); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip); + } + + // physical interfaces on the SDX range from 10/1 to 10/8 & 1/1 to 1/8 of which two different port or same +// port can be used for public and private interfaces + // However the VPX instances created will have interface range start from 10/1 but will only have as many +// interfaces enabled while creating the VPX instance + // So due to this, we need to map public & private interface on SDX to correct public & private interface of +// VPX + + int publicIfnum = Integer.parseInt(_publicInterface.substring(_publicInterface.lastIndexOf("/") + 1)); + int privateIfnum = Integer.parseInt(_privateInterface.substring(_privateInterface.lastIndexOf("/") + 1)); + + if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("10/")) { + if (publicIfnum == privateIfnum) { + publicIf = "10/1"; + privateIf = "10/1"; + } else if (publicIfnum > privateIfnum) { + privateIf = "10/1"; + publicIf = "10/2"; + } else { + publicIf = "10/1"; + privateIf = "10/2"; + } + } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("1/")) { + if (publicIfnum == privateIfnum) { + publicIf = "1/1"; + privateIf = "1/1"; + } else if (publicIfnum > privateIfnum) { + privateIf = "1/1"; + publicIf = "1/2"; + } else { + publicIf = "1/1"; + privateIf = "1/2"; + } + } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("10/")) { + publicIf = "1/1"; + privateIf = "10/1"; + } else if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("1/")) { + publicIf = "10/1"; + privateIf = "1/1"; + } + + return new CreateLoadBalancerApplianceAnswer(cmd, true, "provisioned VPX instance", "NetscalerVPXLoadBalancer", "Netscaler", new NetscalerResource(), + publicIf, privateIf, _username, _password); + } catch (Exception e) { + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } + return new CreateLoadBalancerApplianceAnswer(cmd, false, "failed to provisioned VPX instance due to " + e.getMessage(), null, null, null, null, null, null, null); + } + } + + private void enableVPXInterfaces(String publicIf, String privateIf, ns ns_obj) { + // enable VPX to use 10 gigabit Ethernet interfaces if public/private interface + // on SDX is a 10Gig interface + if (publicIf.equals("10/1") || privateIf.equals("10/1")) { + ns_obj.set_if_10_1(new Boolean(true)); + } + + if (publicIf.equals("10/2") || privateIf.equals("10/2")) { + ns_obj.set_if_10_2(new Boolean(true)); + } + + if (publicIf.equals("10/3") || privateIf.equals("10/3")) { + ns_obj.set_if_10_3(new Boolean(true)); + } + + if (publicIf.equals("10/4") || privateIf.equals("10/4")) { + ns_obj.set_if_10_4(new Boolean(true)); + } + + if (publicIf.equals("10/5") || privateIf.equals("10/5")) { + ns_obj.set_if_10_5(new Boolean(true)); + } + + if (publicIf.equals("10/6") || privateIf.equals("10/6")) { + ns_obj.set_if_10_6(new Boolean(true)); + } + + if (publicIf.equals("10/7") || privateIf.equals("10/7")) { + ns_obj.set_if_10_7(new Boolean(true)); + } + + if (publicIf.equals("10/8") || privateIf.equals("10/8")) { + ns_obj.set_if_10_8(new Boolean(true)); + } + + // enable VPX to use 1 gigabit Ethernet interfaces if public/private interface + // on SDX is a 1Gig interface + if (publicIf.equals("1/1") || privateIf.equals("1/1")) { + ns_obj.set_if_1_1(new Boolean(true)); + } + + if (publicIf.equals("1/2") || privateIf.equals("1/2")) { + ns_obj.set_if_1_2(new Boolean(true)); + } + + if (publicIf.equals("1/3") || privateIf.equals("1/3")) { + ns_obj.set_if_1_3(new Boolean(true)); + } + + if (publicIf.equals("1/4") || privateIf.equals("1/4")) { + ns_obj.set_if_1_4(new Boolean(true)); + } + + if (publicIf.equals("1/5") || privateIf.equals("1/5")) { + ns_obj.set_if_1_5(new Boolean(true)); + } + + if (publicIf.equals("1/6") || privateIf.equals("1/6")) { + ns_obj.set_if_1_6(new Boolean(true)); + } + + if (publicIf.equals("1/7") || privateIf.equals("1/7")) { + ns_obj.set_if_1_7(new Boolean(true)); + } + + if (publicIf.equals("1/8") || privateIf.equals("1/8")) { + ns_obj.set_if_1_8(new Boolean(true)); + } + } + + private synchronized Answer execute(DestroyLoadBalancerApplianceCommand cmd, int numRetries) { + String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP(); + if (!_isSdx) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + try { + ns vpxToDelete =null; + ns[] vpxInstances = ns.get(_netscalerSdxService); + for (ns vpx : vpxInstances) { + if (vpx.get_name().equals(vpxName)) { + vpxToDelete = vpx; + break; + } + } + + if (vpxToDelete == null) { + String msg = "There is no VPX instance " + vpxName + " on the Netscaler SDX device " + _ip + " to delete"; + s_logger.warn(msg); + return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg); + } + + // destroy the VPX instance + ns nsDelObj = new ns(); + nsDelObj.set_id(vpxToDelete.get_id()); + vpxToDelete = ns.delete(_netscalerSdxService, nsDelObj); + String msg = "Deleted VPX instance " + vpxName + " on Netscaler SDX " + _ip + " successfully."; + s_logger.info(msg); + return new DestroyLoadBalancerApplianceAnswer(cmd, true,msg); + } catch (Exception e) { + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } + return new DestroyLoadBalancerApplianceAnswer(cmd, false, "Failed to delete VPX instance " + vpxName + " on Netscaler SDX " + _ip); + } + } + + private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) { + + if (_isSdx) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + String[] results = new String[cmd.getRules().length]; + int i = 0; + boolean endResult = true; + + try { + for (StaticNatRuleTO rule : cmd.getRules()) { + String srcIp = rule.getSrcIp(); + String dstIP = rule.getDstIp(); + String iNatRuleName = generateInatRuleName(srcIp, dstIP); + inat iNatRule = null; + + if (!rule.revoked()) { + try { + iNatRule = inat.get(_netscalerService, iNatRuleName); + } catch (nitro_exception e) { + if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { + throw e; + } + } + + if (iNatRule == null) { + iNatRule = new inat(); + iNatRule.set_name(iNatRuleName); + iNatRule.set_publicip(srcIp); + iNatRule.set_privateip(dstIP); + iNatRule.set_usnip("OFF"); + iNatRule.set_usip("ON"); + try { + apiCallResult = inat.add(_netscalerService, iNatRule); + } catch (nitro_exception e) { + if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) { + throw e; + } + } + s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " + srcIp + " to " + dstIP); + } + } else { + try { + inat.delete(_netscalerService, iNatRuleName); + } catch (nitro_exception e) { + if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { + throw e; + } + } + s_logger.debug("Deleted Inat rule on the Netscaler device " + _ip + " to remove static NAT from " + srcIp + " to " + dstIP); + } + + saveConfiguration(); + results[i++] = "Static nat rule from " + srcIp + " to " + dstIP + " successfully " + (rule.revoked() ? " revoked.":" created."); + } + } catch (Exception e) { + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } + results[i++] = "Configuring static nat rule failed due to " + e.getMessage(); + endResult = false; + return new SetStaticNatRulesAnswer(cmd, results, endResult); + } + + return new SetStaticNatRulesAnswer(cmd, results, endResult); + } + + private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) { + try { + if (!_isSdx) { + return getPublicIpBytesSentAndReceived(cmd); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } catch (ExecutionException e) { + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } else { + return new ExternalNetworkResourceUsageAnswer(cmd, e); + } + } + } + + private void addSubnetIP(String snip, String netmask) throws ExecutionException { + try { + nsip selfIp = new nsip(); + selfIp.set_ipaddress(snip); + selfIp.set_netmask(netmask); + selfIp.set_type("SNIP"); + apiCallResult = nsip.add(_netscalerService, selfIp); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to "+ apiCallResult.message); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage()); + } + } + + private void addGuestVlanAndSubnet(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean guestVlan) throws ExecutionException { + try { + // add vlan object for guest VLAN + if (!nsVlanExists(vlanTag)) { + try { + vlan vlanObj = new vlan(); + vlanObj.set_id(vlanTag); + apiCallResult = vlan.add(_netscalerService, vlanObj); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + e.getMessage()); + } + } + + // add subnet IP object for this guest network + if (!nsSnipExists(vlanSelfIp)) { + try { + nsip selfIp = new nsip(); + selfIp.set_ipaddress(vlanSelfIp); + selfIp.set_netmask(vlanNetmask); + selfIp.set_type("SNIP"); + apiCallResult = nsip.add(_netscalerService, selfIp); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to "+ apiCallResult.message); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + e.getMessage()); + } + } + + // bind the vlan object to subnet IP object + if (!nsVlanNsipBindingExists(vlanTag, vlanSelfIp)) { + try { + vlan_nsip_binding ipVlanBinding = new vlan_nsip_binding(); + ipVlanBinding.set_id(vlanTag); + ipVlanBinding.set_ipaddress(vlanSelfIp); + ipVlanBinding.set_netmask(vlanNetmask); + apiCallResult = vlan_nsip_binding.add(_netscalerService, ipVlanBinding); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to bind VLAN with tag:" + vlanTag + " to the subnet due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to bind VLAN with tage:"+ vlanTag + " to the subnet due to " + e.getMessage()); + } + } + + // bind vlan object to the private interface + try { + vlan_interface_binding vlanBinding = new vlan_interface_binding(); + if (guestVlan) { + vlanBinding.set_ifnum(_privateInterface); + } else { + vlanBinding.set_ifnum(_publicInterface); + } + vlanBinding.set_tagged(true); + vlanBinding.set_id(vlanTag); + apiCallResult = vlan_interface_binding.add(_netscalerService, vlanBinding); + if (apiCallResult.errorcode != 0) { + String vlanInterface = guestVlan ? _privateInterface : _publicInterface; + throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + if (!(e.getErrorCode() == NitroError.NS_INTERFACE_ALREADY_BOUND_TO_VLAN)) { + throw new ExecutionException("Failed to bind VLAN "+ vlanTag + " with interface on the Netscaler device due to " + e.getMessage()); + } + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage()); + } + } + + private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { + try { + + // Delete all servers and associated services from this guest VLAN + deleteServersInGuestVlan(vlanTag, vlanSelfIp, vlanNetmask); + + // unbind vlan to the private interface + try { + vlan_interface_binding vlanIfBinding = new vlan_interface_binding(); + vlanIfBinding.set_id(vlanTag); + vlanIfBinding.set_ifnum(_privateInterface); + vlanIfBinding.set_tagged(true); + apiCallResult = vlan_interface_binding.delete(_netscalerService, vlanIfBinding); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the private interface due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + // if Vlan to interface binding does not exist then ignore the exception and proceed + if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { + throw new ExecutionException("Failed to unbind vlan from the interface while shutdown of guest network on the Netscaler device due to " + e.getMessage()); + } + } + + // unbind the vlan to subnet + try { + vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding(); + vlanSnipBinding.set_netmask(vlanNetmask); + vlanSnipBinding.set_ipaddress(vlanSelfIp); + vlanSnipBinding.set_id(vlanTag); + apiCallResult = vlan_nsip_binding.delete(_netscalerService, vlanSnipBinding); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + // if Vlan to subnet binding does not exist then ignore the exception and proceed + if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { + throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + e.getMessage()); + } + } + + // remove subnet IP + try { + nsip subnetIp = nsip.get(_netscalerService, vlanSelfIp); + apiCallResult = nsip.delete(_netscalerService, subnetIp); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + apiCallResult.message); + } + } catch (nitro_exception e) { + // if subnet SNIP does not exist then ignore the exception and proceed + if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) { + throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + e.getMessage()); + } + } + + // remove the vlan from the NetScaler device + if (nsVlanExists(vlanTag)) { + // remove vlan + apiCallResult = com.citrix.netscaler.nitro.resource.config.network.vlan.delete(_netscalerService, vlanTag); + 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) { + throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); + } + } + + private boolean nsVlanExists(long vlanTag) throws ExecutionException { + try { + if (vlan.get(_netscalerService, new Long(vlanTag)) != null) { + return true; + } else { + return false; + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return false; + } else { + throw new ExecutionException("Failed to verify VLAN exists on the NetScaler device due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify VLAN exists on the NetScaler device due to " + e.getMessage()); + } + } + + private boolean nsSnipExists(String subnetIP) throws ExecutionException { + try { + nsip snip = nsip.get(_netscalerService, subnetIP); + return (snip != null); + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return false; + } else { + throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage()); + } + } + + private boolean nsServerExists(String serverName) throws ExecutionException { + try { + if (com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService, serverName) != null) { + return true; + } else { + return false; + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return false; + } else { + throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage()); + } + } + + private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException { + try { + vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag); + if (vlanNsipBindings != null && vlanNsipBindings[0] != null && vlanNsipBindings[0].get_ipaddress().equalsIgnoreCase(vlanSelfIp)) { + return true; + } else { + return false; + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return false; + } else { + throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage()); + } + } + + private lbvserver getVirtualServerIfExisits(String lbVServerName ) throws ExecutionException { + try { + return lbvserver.get(_netscalerService, lbVServerName); + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return null; + } else { + throw new ExecutionException(e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException(e.getMessage()); + } + } + + private boolean isServiceBoundToVirtualServer(String serviceName) throws ExecutionException { + try { + lbvserver[] lbservers = lbvserver.get(_netscalerService); + for (lbvserver vserver : lbservers) { + filtervalue[] filter = new filtervalue[1]; + filter[0] = new filtervalue("servicename", serviceName); + lbvserver_service_binding[] result = lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter); + if (result != null && result.length > 0) { + return true; + } + } + return false; + } catch (Exception e) { + 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) { + return true; + } else { + return false; + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_NO_SERIVCE) { + return false; + } else { + throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage()); + } + } + + private boolean nsServiceBindingExists(String lbVirtualServer, String serviceName) throws ExecutionException { + try { + com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, lbVirtualServer); + if (serviceBindings != null) { + for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) { + if (serviceName.equalsIgnoreCase(binding.get_servicename())) { + return true; + } + } + } + return false; + } catch (nitro_exception e) { + throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage()); + } + } + + private void deleteServersInGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { + try { + com.citrix.netscaler.nitro.resource.config.basic.server[] serverList = com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService); + + if (serverList == null) { + return; + } + + // remove the server and services associated with guest vlan + for (com.citrix.netscaler.nitro.resource.config.basic.server server : serverList) { + // check if server belong to same subnet as one associated with vlan + if (NetUtils.sameSubnet(vlanSelfIp, server.get_ipaddress(), vlanNetmask)) { + // first remove services associated with this server + com.citrix.netscaler.nitro.resource.config.basic.service serveicesList[] = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService); + if (serveicesList != null) { + for (com.citrix.netscaler.nitro.resource.config.basic.service svc : serveicesList) { + if (svc.get_servername().equals(server.get_ipaddress())) { + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, svc.get_name()); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to remove service:" + svc.get_name()); + } + } + } + } + // remove the server + apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, server.get_name()); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to remove server:" + server.get_name()); + } + } + } + } catch (Exception e) { + throw new ExecutionException("Failed to delete server and services in the guest vlan:" + vlanTag + " on the Netscaler device due to: "+ e.getMessage()); + } + } + + private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException { + String port = Integer.toString(loadBalancer.getSrcPort()); + String lbProtocol = loadBalancer.getProtocol(); + StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies(); + String nsProtocol = "TCP"; + + if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){ + StickinessPolicyTO stickinessPolicy = stickyPolicies[0]; + if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) || + (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) { + nsProtocol = "HTTP"; + return nsProtocol; + } + } + + if (port.equals(NetUtils.HTTP_PORT)) { + nsProtocol = "HTTP"; + } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) { + nsProtocol = "TCP"; + } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) { + nsProtocol = "UDP"; + } + + return nsProtocol; + } + + private void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies) throws ExecutionException { + try { + String lbMethod; + if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) { + lbMethod = "ROUNDROBIN"; + } else if ("leastconn".equalsIgnoreCase(lbAlgorithm)) { + lbMethod = "LEASTCONNECTION"; + } else if ("source".equalsIgnoreCase(lbAlgorithm)) { + lbMethod = "SOURCEIPHASH"; + } else { + throw new ExecutionException("Got invalid load balancing algorithm: " + lbAlgorithm + " in the load balancing rule"); + } + + boolean vserverExisis = false; + lbvserver vserver = getVirtualServerIfExisits(virtualServerName); + if (vserver == null) { + vserver = new lbvserver(); + } else { + if (!vserver.get_servicetype().equalsIgnoreCase(protocol)) { + throw new ExecutionException("Can not update virtual server:" + virtualServerName + " as current protocol:" + vserver.get_servicetype() + " of virtual server is different from the " + + " intended protocol:" + protocol); + } + vserverExisis = true; + } + vserver.set_name(virtualServerName); + vserver.set_ipv46(publicIp); + vserver.set_port(publicPort); + vserver.set_servicetype(protocol); + vserver.set_lbmethod(lbMethod); + + // netmask can only be set for source IP load balancer algorithm + if (!lbMethod.equalsIgnoreCase("SOURCEIPHASH")) { + vserver.set_netmask(null); + vserver.set_v6netmasklen(null); + } + + if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){ + long timeout = 2;// netscaler default 2 min + String cookieName = null; + StickinessPolicyTO stickinessPolicy = stickyPolicies[0]; + + // get the session persistence parameters + List> paramsList = stickinessPolicy.getParams(); + for(Pair param : paramsList) { + if ("holdtime".equalsIgnoreCase(param.first())) { + timeout = Long.parseLong(param.second()); + } else if ("name".equalsIgnoreCase(param.first())) { + cookieName = param.second(); + } + } + + // configure virtual server based on the persistence method + if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { + vserver.set_persistencetype("COOKIEINSERT"); + } else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { + vserver.set_persistencetype("SOURCEIP"); + } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { + vserver.set_persistencetype("RULE"); + vserver.set_rule("HTTP.REQ.HEADER(\"COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")"); + vserver.set_resrule("HTTP.RES.HEADER(\"SET-COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")"); + } else { + throw new ExecutionException("Got invalid session persistence method: " + stickinessPolicy.getMethodName() + " in the load balancing rule"); + } + + // set session persistence timeout + vserver.set_timeout(timeout); + } else { + if (vserver.get_persistencetype() != null) { + // delete the LB stickyness policy + vserver.set_persistencetype("NONE"); + } + } + + if (vserverExisis) { + apiCallResult = lbvserver.update(_netscalerService,vserver); + } else { + apiCallResult = lbvserver.add(_netscalerService,vserver); + } + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to create new load balancing virtual server:" + virtualServerName + " due to " + apiCallResult.message); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Created load balancing virtual server " + virtualServerName + " on the Netscaler device"); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage()); + } + } + + private void removeLBVirtualServer (String virtualServerName) throws ExecutionException { + try { + lbvserver vserver = lbvserver.get(_netscalerService, virtualServerName); + if (vserver == null) { + return; + } + apiCallResult = lbvserver.delete(_netscalerService, vserver); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Failed to delete virtual server:" + virtualServerName + " due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return; + } else { + throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + } + } + + private void saveConfiguration() throws ExecutionException { + try { + apiCallResult = nsconfig.save(_netscalerService); + if (apiCallResult.errorcode != 0) { + throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message); + } + } catch (nitro_exception e) { + throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage()); + } + } + + private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException { + ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd); + + try { + lbvserver_stats[] stats = lbvserver_stats.get(_netscalerService); + + if (stats == null || stats.length == 0) { + return answer; + } + + for (lbvserver_stats stat_entry : stats) { + String lbvserverName = stat_entry.get_name(); + 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); + } + } + } + } catch (Exception e) { + s_logger.error("Failed to get bytes sent and recived statistics due to " + e); + throw new ExecutionException(e.getMessage()); + } + + return answer; + } + + private Answer retry(Command cmd, int numRetries) { + int numRetriesRemaining = numRetries - 1; + s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining); + return executeRequest(cmd, numRetriesRemaining); + } + + private boolean shouldRetry(int numRetries) { + try { + if (numRetries > 0) { + login(); + return true; + } + } catch (Exception e) { + s_logger.error("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); + } + return false; + } + + private String generateInatRuleName(String srcIp, String dstIP) { + return genObjectName("Cloud-Inat", srcIp); + } + + private String generateNSVirtualServerName(String srcIp, long srcPort) { + return genObjectName("Cloud-VirtualServer", srcIp, srcPort); + } + + private String generateAutoScaleServiceGroupName(String virtualServerName) { + return genObjectName("Cloud-AutoScaleServiceGroup", virtualServerName); + } + + private String generateAutoScaleTimerName(String virtualServerName) { + return genObjectName("Cloud-AutoScale-Timer", virtualServerName); + } + + private String generateAutoScaleProfileName(String virtualServerName) { + return genObjectName("Cloud-AutoScale-Profile", virtualServerName); + } + + private String generateAutoScaleScaleUpActionName(String virtualServerName) { + return genObjectName("Cloud-AutoScale-ScaleUpAction", virtualServerName); + } + + private String generateAutoScaleScaleDownActionName(String virtualServerName) { + return genObjectName("Cloud-AutoScale-ScaleDownAction", virtualServerName); + } + + private String generateAutoScalePolicyName(String virtualServerName, String poilcyId) { + return genObjectName("Cloud-AutoScale-Policy", virtualServerName, poilcyId); + } + + private String generateSnmpMetricTableName(String virtualServerName) { + return genObjectName("Cloud-MetricTable", virtualServerName); + } + + private String generateSnmpMonitorName(String virtualServerName) { + return genObjectName("Cloud-Monitor", virtualServerName); + } + + private String generateSnmpMetricName(String counterName) { + return counterName; + } + + private String generateNSServerName(String serverIP) { + return genObjectName("Cloud-Server-", serverIP); + } + + private String generateNSServiceName(String ip, long port) { + return genObjectName("Cloud-Service", ip, port); + } + + private String genObjectName(Object... args) { + String objectName = ""; + for (int i = 0; i < args.length; i++) { + objectName += args[i]; + if (i != args.length -1) { + objectName += _objectNamePathSep; + } + } + return objectName; + } + + @Override + public IAgentControl getAgentControl() { + return null; + } + + @Override + public PingCommand getCurrentStatus(long id) { + return new PingCommand(Host.Type.ExternalLoadBalancer, id); + } + + @Override + public Type getType() { + return Host.Type.ExternalLoadBalancer; + } + + @Override + public void setAgentControl(IAgentControl agentControl) { + return; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void disconnected() { + return; + } +} diff --git a/deps/cloud-netscaler.jar b/deps/cloud-netscaler.jar index a073b5067c8..64d9701b2d1 100755 Binary files a/deps/cloud-netscaler.jar and b/deps/cloud-netscaler.jar differ diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 7f7a7af8db2..d8b2413de67 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -1,802 +1,852 @@ -// 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.api; - -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobVO; -import com.cloud.capacity.CapacityVO; -import com.cloud.capacity.dao.CapacityDao; -import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; -import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationService; -import com.cloud.configuration.Resource.ResourceType; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Vlan; -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.AccountVlanMapDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.domain.DomainVO; -import com.cloud.domain.dao.DomainDao; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.ha.HighAvailabilityManager; -import com.cloud.host.Host; -import com.cloud.host.HostStats; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; -import com.cloud.network.Network.Capability; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; -import com.cloud.network.NetworkDomainVO; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkProfile; -import com.cloud.network.NetworkRuleConfigVO; -import com.cloud.network.NetworkVO; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.Site2SiteCustomerGatewayVO; -import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.dao.FirewallRulesCidrsDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkDomainDao; -import com.cloud.network.dao.NetworkRuleConfigDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.security.SecurityGroup; -import com.cloud.network.security.SecurityGroupManager; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.VpcManager; -import com.cloud.offering.NetworkOffering; -import com.cloud.offering.ServiceOffering; -import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.projects.Project; -import com.cloud.projects.ProjectService; -import com.cloud.resource.ResourceManager; -import com.cloud.server.Criteria; -import com.cloud.server.ManagementServer; -import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.server.StatsCollector; -import com.cloud.server.TaggedResourceService; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.GuestOSCategoryDao; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.UploadDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; -import com.cloud.user.Account; -import com.cloud.user.AccountDetailsDao; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserVO; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.uservm.UserVm; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VmStats; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.UserVmData; -import com.cloud.vm.dao.VMInstanceDao; - -public class ApiDBUtils { - private static ManagementServer _ms; - public static AsyncJobManager _asyncMgr; - private static SecurityGroupManager _securityGroupMgr; - private static StorageManager _storageMgr; - private static UserVmManager _userVmMgr; - private static NetworkManager _networkMgr; - private static StatsCollector _statsCollector; - - private static AccountDao _accountDao; - private static AccountVlanMapDao _accountVlanMapDao; - private static ClusterDao _clusterDao; - private static CapacityDao _capacityDao; - private static DiskOfferingDao _diskOfferingDao; - private static DomainDao _domainDao; - private static DomainRouterDao _domainRouterDao; - private static GuestOSDao _guestOSDao; - private static GuestOSCategoryDao _guestOSCategoryDao; - private static HostDao _hostDao; - private static IPAddressDao _ipAddressDao; - private static LoadBalancerDao _loadBalancerDao; - private static SecurityGroupDao _securityGroupDao; - private static NetworkRuleConfigDao _networkRuleConfigDao; - private static HostPodDao _podDao; - private static ServiceOfferingDao _serviceOfferingDao; - private static SnapshotDao _snapshotDao; - private static StoragePoolDao _storagePoolDao; - private static VMTemplateDao _templateDao; - private static VMTemplateDetailsDao _templateDetailsDao; - private static VMTemplateHostDao _templateHostDao; - private static VMTemplateSwiftDao _templateSwiftDao; - private static UploadDao _uploadDao; - private static UserDao _userDao; - private static UserStatisticsDao _userStatsDao; - private static UserVmDao _userVmDao; - private static VlanDao _vlanDao; - private static VolumeDao _volumeDao; - private static Site2SiteVpnGatewayDao _site2SiteVpnGatewayDao; - private static Site2SiteCustomerGatewayDao _site2SiteCustomerGatewayDao; - private static VolumeHostDao _volumeHostDao; - private static DataCenterDao _zoneDao; - private static NetworkOfferingDao _networkOfferingDao; - private static NetworkDao _networkDao; - private static ConfigurationService _configMgr; - private static ConfigurationDao _configDao; - private static ConsoleProxyDao _consoleProxyDao; - private static FirewallRulesCidrsDao _firewallCidrsDao; - private static VMInstanceDao _vmDao; - private static ResourceLimitService _resourceLimitMgr; - private static ProjectService _projectMgr; - private static ResourceManager _resourceMgr; - private static AccountDetailsDao _accountDetailsDao; - private static NetworkDomainDao _networkDomainDao; - private static HighAvailabilityManager _haMgr; - private static TaggedResourceService _taggedResourceService; - private static VpcManager _vpcMgr; - - static { - _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - _asyncMgr = locator.getManager(AsyncJobManager.class); - _securityGroupMgr = locator.getManager(SecurityGroupManager.class); - _storageMgr = locator.getManager(StorageManager.class); - _userVmMgr = locator.getManager(UserVmManager.class); - _networkMgr = locator.getManager(NetworkManager.class); - _configMgr = locator.getManager(ConfigurationService.class); - - _accountDao = locator.getDao(AccountDao.class); - _accountVlanMapDao = locator.getDao(AccountVlanMapDao.class); - _clusterDao = locator.getDao(ClusterDao.class); - _capacityDao = locator.getDao(CapacityDao.class); - _diskOfferingDao = locator.getDao(DiskOfferingDao.class); - _domainDao = locator.getDao(DomainDao.class); - _domainRouterDao = locator.getDao(DomainRouterDao.class); - _guestOSDao = locator.getDao(GuestOSDao.class); - _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); - _hostDao = locator.getDao(HostDao.class); - _ipAddressDao = locator.getDao(IPAddressDao.class); - _loadBalancerDao = locator.getDao(LoadBalancerDao.class); - _networkRuleConfigDao = locator.getDao(NetworkRuleConfigDao.class); - _podDao = locator.getDao(HostPodDao.class); - _serviceOfferingDao = locator.getDao(ServiceOfferingDao.class); - _snapshotDao = locator.getDao(SnapshotDao.class); - _storagePoolDao = locator.getDao(StoragePoolDao.class); - _templateDao = locator.getDao(VMTemplateDao.class); - _templateDetailsDao = locator.getDao(VMTemplateDetailsDao.class); - _templateHostDao = locator.getDao(VMTemplateHostDao.class); - _templateSwiftDao = locator.getDao(VMTemplateSwiftDao.class); - _uploadDao = locator.getDao(UploadDao.class); - _userDao = locator.getDao(UserDao.class); - _userStatsDao = locator.getDao(UserStatisticsDao.class); - _userVmDao = locator.getDao(UserVmDao.class); - _vlanDao = locator.getDao(VlanDao.class); - _volumeDao = locator.getDao(VolumeDao.class); - _site2SiteVpnGatewayDao = locator.getDao(Site2SiteVpnGatewayDao.class); - _site2SiteCustomerGatewayDao = locator.getDao(Site2SiteCustomerGatewayDao.class); - _volumeHostDao = locator.getDao(VolumeHostDao.class); - _zoneDao = locator.getDao(DataCenterDao.class); - _securityGroupDao = locator.getDao(SecurityGroupDao.class); - _networkOfferingDao = locator.getDao(NetworkOfferingDao.class); - _networkDao = locator.getDao(NetworkDao.class); - _configDao = locator.getDao(ConfigurationDao.class); - _consoleProxyDao = locator.getDao(ConsoleProxyDao.class); - _firewallCidrsDao = locator.getDao(FirewallRulesCidrsDao.class); - _vmDao = locator.getDao(VMInstanceDao.class); - _resourceLimitMgr = locator.getManager(ResourceLimitService.class); - _projectMgr = locator.getManager(ProjectService.class); - _resourceMgr = locator.getManager(ResourceManager.class); - _accountDetailsDao = locator.getDao(AccountDetailsDao.class); - _networkDomainDao = locator.getDao(NetworkDomainDao.class); - _haMgr = locator.getManager(HighAvailabilityManager.class); - _taggedResourceService = locator.getManager(TaggedResourceService.class); - _vpcMgr = locator.getManager(VpcManager.class); - - // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned - _statsCollector = StatsCollector.getInstance(); - } - - // /////////////////////////////////////////////////////////// - // ManagementServer methods // - // /////////////////////////////////////////////////////////// - - public static VMInstanceVO findVMInstanceById(long vmId) { - return _vmDao.findById(vmId); - } - - public static long getMemoryOrCpuCapacitybyHost(Long hostId, short capacityType) { - // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) - // so if this Utils class can have some kind of config rather than a static initializer (maybe from - // management server instantiation?) then maybe the management server method can be moved entirely - // into this utils class. - return _ms.getMemoryOrCpuCapacityByHost(hostId,capacityType); - } - - public static long getStorageCapacitybyPool(Long poolId, short capacityType) { - // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) - // so if this Utils class can have some kind of config rather than a static initializer (maybe from - // management server instantiation?) then maybe the management server method can be moved entirely - // 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); - } - - public static List findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId){ - return _capacityDao.findNonSharedStorageForClusterPodZone(zoneId,podId,clusterId); - } - - public static List getCapacityByPod(){ - return null; - - } - - public static Long getPodIdForVlan(long vlanDbId) { - return _networkMgr.getPodIdForVlan(vlanDbId); - } - - public static String getVersion() { - return _ms.getVersion(); - } - - public static List searchForUserVMs(Criteria c, List permittedAccounts) { - return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), null, false, permittedAccounts, false, null, null); - } - - public static List searchForStoragePools(Criteria c) { - return _ms.searchForStoragePools(c); - } - - // /////////////////////////////////////////////////////////// - // Manager methods // - // /////////////////////////////////////////////////////////// - - public static long findCorrectResourceLimit(ResourceType type, long accountId) { - AccountVO account = _accountDao.findById(accountId); - - if (account == null) { - return -1; - } - - return _resourceLimitMgr.findCorrectResourceLimitForAccount(account, type); - } - - public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) { - return _asyncMgr.findInstancePendingAsyncJob(instanceType, instanceId); - } - - public static long getResourceCount(ResourceType type, long accountId) { - AccountVO account = _accountDao.findById(accountId); - - if (account == null) { - return -1; - } - - return _resourceLimitMgr.getResourceCount(account, type); - } - - public static String getSecurityGroupsNamesForVm(long vmId) { - return _securityGroupMgr.getSecurityGroupsNamesForVm(vmId); - } - - public static List getSecurityGroupsForVm(long vmId) { - return _securityGroupMgr.getSecurityGroupsForVm(vmId); - } - - public static String getSnapshotIntervalTypes(long snapshotId) { - SnapshotVO snapshot = _snapshotDao.findById(snapshotId); - return snapshot.getType().name(); - } - - public static String getStoragePoolTags(long poolId) { - return _storageMgr.getStoragePoolTags(poolId); - } - - public static boolean isLocalStorageActiveOnHost(Host host) { - return _storageMgr.isLocalStorageActiveOnHost(host); - } - - public static InstanceGroupVO findInstanceGroupForVM(long vmId) { - return _userVmMgr.getGroupForVm(vmId); - } - - // /////////////////////////////////////////////////////////// - // Misc methods // - // /////////////////////////////////////////////////////////// - - public static HostStats getHostStatistics(long hostId) { - return _statsCollector.getHostStats(hostId); - } - - public static StorageStats getStoragePoolStatistics(long id) { - return _statsCollector.getStoragePoolStats(id); - } - - public static VmStats getVmStatistics(long hostId) { - return _statsCollector.getVmStats(hostId); - } - - 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); - } - - public static CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId){ - return _storageMgr.getSecondaryStorageUsedStats(hostId, zoneId); - } - - // /////////////////////////////////////////////////////////// - // Dao methods // - // /////////////////////////////////////////////////////////// - - public static Account findAccountById(Long accountId) { - return _accountDao.findByIdIncludingRemoved(accountId); - } - - public static Account findAccountByIdIncludingRemoved(Long accountId) { - return _accountDao.findByIdIncludingRemoved(accountId); - } - - public static Account findAccountByNameDomain(String accountName, Long domainId) { - return _accountDao.findActiveAccount(accountName, domainId); - } - - public static ClusterVO findClusterById(long clusterId) { - return _clusterDao.findById(clusterId); - } - - public static DiskOfferingVO findDiskOfferingById(Long diskOfferingId) { - return _diskOfferingDao.findByIdIncludingRemoved(diskOfferingId); - } - - public static DomainVO findDomainById(Long domainId) { - return _domainDao.findByIdIncludingRemoved(domainId); - } - - public static DomainVO findDomainByIdIncludingRemoved(Long domainId) { - return _domainDao.findByIdIncludingRemoved(domainId); - } - - public static DomainRouterVO findDomainRouterById(Long routerId) { - return _domainRouterDao.findByIdIncludingRemoved(routerId); - } - - public static GuestOS findGuestOSById(Long id) { - return _guestOSDao.findByIdIncludingRemoved(id); - } - - public static GuestOS findGuestOSByDisplayName(String displayName) { - return _guestOSDao.listByDisplayName(displayName); - } - - public static HostVO findHostById(Long hostId) { - return _hostDao.findByIdIncludingRemoved(hostId); - } - - public static IPAddressVO findIpAddressById(long addressId) { - return _ipAddressDao.findById(addressId); - } - - public static GuestOSCategoryVO getHostGuestOSCategory(long hostId) { - Long guestOSCategoryID = _resourceMgr.getGuestOSCategoryId(hostId); - - if (guestOSCategoryID != null) { - return _guestOSCategoryDao.findById(guestOSCategoryID); - } else { - return null; - } - } - - public static String getHostTags(long hostId) { - return _resourceMgr.getHostTags(hostId); - } - - public static LoadBalancerVO findLoadBalancerById(Long loadBalancerId) { - return _loadBalancerDao.findById(loadBalancerId); - } - - public static NetworkRuleConfigVO findNetworkRuleById(Long ruleId) { - return _networkRuleConfigDao.findById(ruleId); - } - - public static SecurityGroup findSecurityGroupById(Long groupId) { - return _securityGroupDao.findById(groupId); - } - - public static HostPodVO findPodById(Long podId) { - return _podDao.findById(podId); - } - - public static VolumeVO findRootVolume(long vmId) { - List volumes = _volumeDao.findByInstanceAndType(vmId, Type.ROOT); - if (volumes != null && volumes.size() == 1) { - return volumes.get(0); - } else { - return null; - } - } - - public static ServiceOffering findServiceOfferingById(Long serviceOfferingId) { - return _serviceOfferingDao.findByIdIncludingRemoved(serviceOfferingId); - } - - public static Snapshot findSnapshotById(long snapshotId) { - SnapshotVO snapshot = _snapshotDao.findById(snapshotId); - if (snapshot != null && snapshot.getRemoved() == null && snapshot.getStatus() == Snapshot.Status.BackedUp) { - return snapshot; - } else { - return null; - } - } - - public static StoragePoolVO findStoragePoolById(Long storagePoolId) { - return _storagePoolDao.findByIdIncludingRemoved(storagePoolId); - } - - 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; - } - - public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId) { - return findTemplateHostRef(templateId, zoneId, false); - } - - public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId, boolean readyOnly) { - VMTemplateVO vmTemplate = findTemplateById(templateId); - if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { - List res = _templateHostDao.listByTemplateId(templateId); - return res.size() == 0 ? null : res.get(0); - } else { - 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); - } - - public static UploadVO findUploadById(Long id) { - return _uploadDao.findById(id); - } - - public static User findUserById(Long userId) { - return _userDao.findById(userId); - } - - public static UserVm findUserVmById(Long vmId) { - return _userVmDao.findById(vmId); - } - - public static VlanVO findVlanById(long vlanDbId) { - return _vlanDao.findById(vlanDbId); - } - - public static VolumeVO findVolumeById(Long volumeId) { - return _volumeDao.findByIdIncludingRemoved(volumeId); - } - - public static Site2SiteVpnGatewayVO findVpnGatewayById(Long vpnGatewayId) { - return _site2SiteVpnGatewayDao.findById(vpnGatewayId); - } - - public static Site2SiteCustomerGatewayVO findCustomerGatewayById(Long customerGatewayId) { - return _site2SiteCustomerGatewayDao.findById(customerGatewayId); - } - - public static List listUsersByAccount(long accountId) { - return _userDao.listByAccount(accountId); - } - - public static DataCenterVO findZoneById(Long zoneId) { - return _zoneDao.findById(zoneId); - } - - public static Long getAccountIdForVlan(long vlanDbId) { - List accountVlanMaps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId); - if (accountVlanMaps.isEmpty()) { - return null; - } else { - return accountVlanMaps.get(0).getAccountId(); - } - } - - public static HypervisorType getVolumeHyperType(long volumeId) { - return _volumeDao.getHypervisorType(volumeId); - } - - public static HypervisorType getHypervisorTypeFromFormat(ImageFormat format){ - return _storageMgr.getHypervisorTypeFromFormat(format); - } - - public static List listTemplateHostBy(long templateId, Long zoneId, boolean readyOnly) { - if (zoneId != null) { - VMTemplateVO vmTemplate = findTemplateById(templateId); - if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { - return _templateHostDao.listByTemplateId(templateId); - } else { - return _templateHostDao.listByZoneTemplate(zoneId, templateId, readyOnly); - } - } else { - return _templateHostDao.listByOnlyTemplateId(templateId); - } - } - - public static List listUserStatsBy(Long accountId) { - return _userStatsDao.listBy(accountId); - } - - public static List listUserVMsByHostId(long hostId) { - return _userVmDao.listByHostId(hostId); - } - - public static List listZones() { - return _zoneDao.listAll(); - } - - public static boolean volumeIsOnSharedStorage(long volumeId) { - // Check that the volume is valid - VolumeVO volume = _volumeDao.findById(volumeId); - if (volume == null) { - throw new InvalidParameterValueException("Please specify a valid volume ID.", null); - } - - return _storageMgr.volumeOnSharedStoragePool(volume); - } - - public static List getNics(VirtualMachine vm) { - return _networkMgr.getNicProfiles(vm); - } - - public static NetworkProfile getNetworkProfile(long networkId) { - return _networkMgr.convertNetworkToNetworkProfile(networkId); - } - - public static NetworkOfferingVO findNetworkOfferingById(long networkOfferingId) { - return _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId); - } - - public static List listVlanByNetworkId(long networkId) { - return _vlanDao.listVlansByNetworkId(networkId); - } - - public static NetworkVO findNetworkById(long id) { - return _networkDao.findById(id); - } - - public static Map> getNetworkCapabilities(long networkId, long zoneId) { - return _networkMgr.getNetworkCapabilities(networkId); - } - - public static long getPublicNetworkIdByZone(long zoneId) { - return _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId(); - } - - public static Long getVlanNetworkId(long vlanId) { - VlanVO vlan = _vlanDao.findById(vlanId); - if (vlan != null) { - return vlan.getNetworkId(); - } else { - return null; - } - } - - public static Integer getNetworkRate(long networkOfferingId) { - return _configMgr.getNetworkOfferingNetworkRate(networkOfferingId); - } - - public static Account getVlanAccount(long vlanId) { - return _configMgr.getVlanAccount(vlanId); - } - - public static boolean isSecurityGroupEnabledInZone(long zoneId) { - DataCenterVO dc = _zoneDao.findById(zoneId); - if (dc == null) { - return false; - } else { - return dc.isSecurityGroupEnabled(); - } - } - - public static Long getDedicatedNetworkDomain(long networkId) { - return _networkMgr.getDedicatedNetworkDomain(networkId); - } - - public static float getCpuOverprovisioningFactor() { - String opFactor = _configDao.getValue(Config.CPUOverprovisioningFactor.key()); - float cpuOverprovisioningFactor = NumbersUtil.parseFloat(opFactor, 1); - return cpuOverprovisioningFactor; - } - - public static boolean isExtractionDisabled(){ - 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); - } - - public static ConsoleProxyVO findConsoleProxy(long id) { - return _consoleProxyDao.findById(id); - } - - public static List findFirewallSourceCidrs(long 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); - } - - 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; - } - - public static Map> listNetworkOfferingServices(long networkOfferingId) { - return _networkMgr.getNetworkOfferingServiceProvidersMap(networkOfferingId); - } - - public static List getElementServices(Provider 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); - } - - public static long 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(); - } - - public static String getUuid(String resourceId, TaggedResourceType resourceType) { - return _taggedResourceService.getUuid(resourceId, resourceType); - } - - public static Map> listVpcOffServices(long vpcOffId) { - return _vpcMgr.getVpcOffSvcProvidersMap(vpcOffId); - } - - public static List listVpcNetworks(long vpcId) { - return _networkMgr.listNetworksByVpc(vpcId); - } - - public static boolean canUseForDeploy(Network network) { - return _networkMgr.canUseForDeploy(network); - } - - public static List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { - return _taggedResourceService.listByResourceTypeAndId(type, resourceId); - } - - public static boolean isOfferingForVpc(NetworkOffering offering) { - boolean vpcProvider = _configMgr.isOfferingForVpc(offering); - return vpcProvider; - } -} +// 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.api; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.cloud.async.AsyncJobManager; +import com.cloud.async.AsyncJobVO; +import com.cloud.capacity.CapacityVO; +import com.cloud.capacity.dao.CapacityDao; +import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationService; +import com.cloud.configuration.Resource.ResourceType; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.AccountVlanMapVO; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.Vlan; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.AccountVlanMapDao; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.ha.HighAvailabilityManager; +import com.cloud.host.Host; +import com.cloud.host.HostStats; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkDomainVO; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkProfile; +import com.cloud.network.NetworkRuleConfigVO; +import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.network.as.CounterVO; +import com.cloud.network.as.ConditionVO; +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.CounterDao; +import com.cloud.network.as.dao.ConditionDao; +import com.cloud.network.dao.FirewallRulesCidrsDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDomainDao; +import com.cloud.network.dao.NetworkRuleConfigDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.security.SecurityGroup; +import com.cloud.network.security.SecurityGroupManager; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.VpcManager; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.projects.Project; +import com.cloud.projects.ProjectService; +import com.cloud.resource.ResourceManager; +import com.cloud.server.Criteria; +import com.cloud.server.ManagementServer; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.StatsCollector; +import com.cloud.server.TaggedResourceService; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOS; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.StorageStats; +import com.cloud.storage.UploadVO; +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateSwiftVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeHostVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.StoragePoolDao; +import com.cloud.storage.dao.UploadDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplateDetailsDao; +import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.dao.VMTemplateSwiftDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.user.Account; +import com.cloud.user.AccountDetailsDao; +import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.User; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.UserVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserDao; +import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.uservm.UserVm; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.vm.ConsoleProxyVO; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.InstanceGroupVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.UserVmManager; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VmStats; +import com.cloud.vm.dao.ConsoleProxyDao; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmData; +import com.cloud.vm.dao.VMInstanceDao; + +public class ApiDBUtils { + private static ManagementServer _ms; + public static AsyncJobManager _asyncMgr; + private static SecurityGroupManager _securityGroupMgr; + private static StorageManager _storageMgr; + private static UserVmManager _userVmMgr; + private static NetworkManager _networkMgr; + private static StatsCollector _statsCollector; + + private static AccountDao _accountDao; + private static AccountVlanMapDao _accountVlanMapDao; + private static ClusterDao _clusterDao; + private static CapacityDao _capacityDao; + private static DiskOfferingDao _diskOfferingDao; + private static DomainDao _domainDao; + private static DomainRouterDao _domainRouterDao; + private static GuestOSDao _guestOSDao; + private static GuestOSCategoryDao _guestOSCategoryDao; + private static HostDao _hostDao; + private static IPAddressDao _ipAddressDao; + private static LoadBalancerDao _loadBalancerDao; + private static SecurityGroupDao _securityGroupDao; + private static NetworkRuleConfigDao _networkRuleConfigDao; + private static HostPodDao _podDao; + private static ServiceOfferingDao _serviceOfferingDao; + private static SnapshotDao _snapshotDao; + private static StoragePoolDao _storagePoolDao; + private static VMTemplateDao _templateDao; + private static VMTemplateDetailsDao _templateDetailsDao; + private static VMTemplateHostDao _templateHostDao; + private static VMTemplateSwiftDao _templateSwiftDao; + private static UploadDao _uploadDao; + private static UserDao _userDao; + private static UserStatisticsDao _userStatsDao; + private static UserVmDao _userVmDao; + private static VlanDao _vlanDao; + private static VolumeDao _volumeDao; + private static Site2SiteVpnGatewayDao _site2SiteVpnGatewayDao; + private static Site2SiteCustomerGatewayDao _site2SiteCustomerGatewayDao; + private static VolumeHostDao _volumeHostDao; + private static DataCenterDao _zoneDao; + private static NetworkOfferingDao _networkOfferingDao; + private static NetworkDao _networkDao; + private static ConfigurationService _configMgr; + private static ConfigurationDao _configDao; + private static ConsoleProxyDao _consoleProxyDao; + private static FirewallRulesCidrsDao _firewallCidrsDao; + private static VMInstanceDao _vmDao; + private static ResourceLimitService _resourceLimitMgr; + private static ProjectService _projectMgr; + private static ResourceManager _resourceMgr; + private static AccountDetailsDao _accountDetailsDao; + private static NetworkDomainDao _networkDomainDao; + private static HighAvailabilityManager _haMgr; + private static TaggedResourceService _taggedResourceService; + private static VpcManager _vpcMgr; + 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); + _asyncMgr = locator.getManager(AsyncJobManager.class); + _securityGroupMgr = locator.getManager(SecurityGroupManager.class); + _storageMgr = locator.getManager(StorageManager.class); + _userVmMgr = locator.getManager(UserVmManager.class); + _networkMgr = locator.getManager(NetworkManager.class); + _configMgr = locator.getManager(ConfigurationService.class); + + _accountDao = locator.getDao(AccountDao.class); + _accountVlanMapDao = locator.getDao(AccountVlanMapDao.class); + _clusterDao = locator.getDao(ClusterDao.class); + _capacityDao = locator.getDao(CapacityDao.class); + _diskOfferingDao = locator.getDao(DiskOfferingDao.class); + _domainDao = locator.getDao(DomainDao.class); + _domainRouterDao = locator.getDao(DomainRouterDao.class); + _guestOSDao = locator.getDao(GuestOSDao.class); + _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); + _hostDao = locator.getDao(HostDao.class); + _ipAddressDao = locator.getDao(IPAddressDao.class); + _loadBalancerDao = locator.getDao(LoadBalancerDao.class); + _networkRuleConfigDao = locator.getDao(NetworkRuleConfigDao.class); + _podDao = locator.getDao(HostPodDao.class); + _serviceOfferingDao = locator.getDao(ServiceOfferingDao.class); + _snapshotDao = locator.getDao(SnapshotDao.class); + _storagePoolDao = locator.getDao(StoragePoolDao.class); + _templateDao = locator.getDao(VMTemplateDao.class); + _templateDetailsDao = locator.getDao(VMTemplateDetailsDao.class); + _templateHostDao = locator.getDao(VMTemplateHostDao.class); + _templateSwiftDao = locator.getDao(VMTemplateSwiftDao.class); + _uploadDao = locator.getDao(UploadDao.class); + _userDao = locator.getDao(UserDao.class); + _userStatsDao = locator.getDao(UserStatisticsDao.class); + _userVmDao = locator.getDao(UserVmDao.class); + _vlanDao = locator.getDao(VlanDao.class); + _volumeDao = locator.getDao(VolumeDao.class); + _site2SiteVpnGatewayDao = locator.getDao(Site2SiteVpnGatewayDao.class); + _site2SiteCustomerGatewayDao = locator.getDao(Site2SiteCustomerGatewayDao.class); + _volumeHostDao = locator.getDao(VolumeHostDao.class); + _zoneDao = locator.getDao(DataCenterDao.class); + _securityGroupDao = locator.getDao(SecurityGroupDao.class); + _networkOfferingDao = locator.getDao(NetworkOfferingDao.class); + _networkDao = locator.getDao(NetworkDao.class); + _configDao = locator.getDao(ConfigurationDao.class); + _consoleProxyDao = locator.getDao(ConsoleProxyDao.class); + _firewallCidrsDao = locator.getDao(FirewallRulesCidrsDao.class); + _vmDao = locator.getDao(VMInstanceDao.class); + _resourceLimitMgr = locator.getManager(ResourceLimitService.class); + _projectMgr = locator.getManager(ProjectService.class); + _resourceMgr = locator.getManager(ResourceManager.class); + _accountDetailsDao = locator.getDao(AccountDetailsDao.class); + _networkDomainDao = locator.getDao(NetworkDomainDao.class); + _haMgr = locator.getManager(HighAvailabilityManager.class); + _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcMgr = locator.getManager(VpcManager.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(); + } + + // /////////////////////////////////////////////////////////// + // ManagementServer methods // + // /////////////////////////////////////////////////////////// + + public static VMInstanceVO findVMInstanceById(long vmId) { + return _vmDao.findById(vmId); + } + + public static long getMemoryOrCpuCapacitybyHost(Long hostId, short capacityType) { + // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) + // so if this Utils class can have some kind of config rather than a static initializer (maybe from + // management server instantiation?) then maybe the management server method can be moved entirely + // into this utils class. + return _ms.getMemoryOrCpuCapacityByHost(hostId,capacityType); + } + + public static long getStorageCapacitybyPool(Long poolId, short capacityType) { + // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) + // so if this Utils class can have some kind of config rather than a static initializer (maybe from + // management server instantiation?) then maybe the management server method can be moved entirely + // 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); + } + + public static List findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId){ + return _capacityDao.findNonSharedStorageForClusterPodZone(zoneId,podId,clusterId); + } + + public static List getCapacityByPod(){ + return null; + + } + + public static Long getPodIdForVlan(long vlanDbId) { + return _networkMgr.getPodIdForVlan(vlanDbId); + } + + public static String getVersion() { + return _ms.getVersion(); + } + + public static List searchForUserVMs(Criteria c, List permittedAccounts) { + return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), null, false, permittedAccounts, false, null, null); + } + + public static List searchForStoragePools(Criteria c) { + return _ms.searchForStoragePools(c); + } + + // /////////////////////////////////////////////////////////// + // Manager methods // + // /////////////////////////////////////////////////////////// + + public static long findCorrectResourceLimit(ResourceType type, long accountId) { + AccountVO account = _accountDao.findById(accountId); + + if (account == null) { + return -1; + } + + return _resourceLimitMgr.findCorrectResourceLimitForAccount(account, type); + } + + public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) { + return _asyncMgr.findInstancePendingAsyncJob(instanceType, instanceId); + } + + public static long getResourceCount(ResourceType type, long accountId) { + AccountVO account = _accountDao.findById(accountId); + + if (account == null) { + return -1; + } + + return _resourceLimitMgr.getResourceCount(account, type); + } + + public static String getSecurityGroupsNamesForVm(long vmId) { + return _securityGroupMgr.getSecurityGroupsNamesForVm(vmId); + } + + public static List getSecurityGroupsForVm(long vmId) { + return _securityGroupMgr.getSecurityGroupsForVm(vmId); + } + + public static String getSnapshotIntervalTypes(long snapshotId) { + SnapshotVO snapshot = _snapshotDao.findById(snapshotId); + return snapshot.getType().name(); + } + + public static String getStoragePoolTags(long poolId) { + return _storageMgr.getStoragePoolTags(poolId); + } + + public static boolean isLocalStorageActiveOnHost(Host host) { + return _storageMgr.isLocalStorageActiveOnHost(host); + } + + public static InstanceGroupVO findInstanceGroupForVM(long vmId) { + return _userVmMgr.getGroupForVm(vmId); + } + + // /////////////////////////////////////////////////////////// + // Misc methods // + // /////////////////////////////////////////////////////////// + + public static HostStats getHostStatistics(long hostId) { + return _statsCollector.getHostStats(hostId); + } + + public static StorageStats getStoragePoolStatistics(long id) { + return _statsCollector.getStoragePoolStats(id); + } + + public static VmStats getVmStatistics(long hostId) { + return _statsCollector.getVmStats(hostId); + } + + 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); + } + + public static CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId){ + return _storageMgr.getSecondaryStorageUsedStats(hostId, zoneId); + } + + // /////////////////////////////////////////////////////////// + // Dao methods // + // /////////////////////////////////////////////////////////// + + public static Account findAccountById(Long accountId) { + return _accountDao.findByIdIncludingRemoved(accountId); + } + + public static Account findAccountByIdIncludingRemoved(Long accountId) { + return _accountDao.findByIdIncludingRemoved(accountId); + } + + public static Account findAccountByNameDomain(String accountName, Long domainId) { + return _accountDao.findActiveAccount(accountName, domainId); + } + + public static ClusterVO findClusterById(long clusterId) { + return _clusterDao.findById(clusterId); + } + + public static DiskOfferingVO findDiskOfferingById(Long diskOfferingId) { + return _diskOfferingDao.findByIdIncludingRemoved(diskOfferingId); + } + + public static DomainVO findDomainById(Long domainId) { + return _domainDao.findByIdIncludingRemoved(domainId); + } + + public static DomainVO findDomainByIdIncludingRemoved(Long domainId) { + return _domainDao.findByIdIncludingRemoved(domainId); + } + + public static DomainRouterVO findDomainRouterById(Long routerId) { + return _domainRouterDao.findByIdIncludingRemoved(routerId); + } + + public static GuestOS findGuestOSById(Long id) { + return _guestOSDao.findByIdIncludingRemoved(id); + } + + public static GuestOS findGuestOSByDisplayName(String displayName) { + return _guestOSDao.listByDisplayName(displayName); + } + + public static HostVO findHostById(Long hostId) { + return _hostDao.findByIdIncludingRemoved(hostId); + } + + public static IPAddressVO findIpAddressById(long addressId) { + return _ipAddressDao.findById(addressId); + } + + public static GuestOSCategoryVO getHostGuestOSCategory(long hostId) { + Long guestOSCategoryID = _resourceMgr.getGuestOSCategoryId(hostId); + + if (guestOSCategoryID != null) { + return _guestOSCategoryDao.findById(guestOSCategoryID); + } else { + return null; + } + } + + public static String getHostTags(long hostId) { + return _resourceMgr.getHostTags(hostId); + } + + public static LoadBalancerVO findLoadBalancerById(Long loadBalancerId) { + return _loadBalancerDao.findById(loadBalancerId); + } + + public static NetworkRuleConfigVO findNetworkRuleById(Long ruleId) { + return _networkRuleConfigDao.findById(ruleId); + } + + public static SecurityGroup findSecurityGroupById(Long groupId) { + return _securityGroupDao.findById(groupId); + } + + public static HostPodVO findPodById(Long podId) { + return _podDao.findById(podId); + } + + public static VolumeVO findRootVolume(long vmId) { + List volumes = _volumeDao.findByInstanceAndType(vmId, Type.ROOT); + if (volumes != null && volumes.size() == 1) { + return volumes.get(0); + } else { + return null; + } + } + + public static ServiceOffering findServiceOfferingById(Long serviceOfferingId) { + return _serviceOfferingDao.findByIdIncludingRemoved(serviceOfferingId); + } + + public static Snapshot findSnapshotById(long snapshotId) { + SnapshotVO snapshot = _snapshotDao.findById(snapshotId); + if (snapshot != null && snapshot.getRemoved() == null && snapshot.getStatus() == Snapshot.Status.BackedUp) { + return snapshot; + } else { + return null; + } + } + + public static StoragePoolVO findStoragePoolById(Long storagePoolId) { + return _storagePoolDao.findByIdIncludingRemoved(storagePoolId); + } + + 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; + } + + public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId) { + return findTemplateHostRef(templateId, zoneId, false); + } + + public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId, boolean readyOnly) { + VMTemplateVO vmTemplate = findTemplateById(templateId); + if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { + List res = _templateHostDao.listByTemplateId(templateId); + return res.size() == 0 ? null : res.get(0); + } else { + 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); + } + + public static UploadVO findUploadById(Long id) { + return _uploadDao.findById(id); + } + + public static User findUserById(Long userId) { + return _userDao.findById(userId); + } + + public static UserVm findUserVmById(Long vmId) { + return _userVmDao.findById(vmId); + } + + public static VlanVO findVlanById(long vlanDbId) { + return _vlanDao.findById(vlanDbId); + } + + public static VolumeVO findVolumeById(Long volumeId) { + return _volumeDao.findByIdIncludingRemoved(volumeId); + } + + public static Site2SiteVpnGatewayVO findVpnGatewayById(Long vpnGatewayId) { + return _site2SiteVpnGatewayDao.findById(vpnGatewayId); + } + + public static Site2SiteCustomerGatewayVO findCustomerGatewayById(Long customerGatewayId) { + return _site2SiteCustomerGatewayDao.findById(customerGatewayId); + } + + public static List listUsersByAccount(long accountId) { + return _userDao.listByAccount(accountId); + } + + public static DataCenterVO findZoneById(Long zoneId) { + return _zoneDao.findById(zoneId); + } + + public static Long getAccountIdForVlan(long vlanDbId) { + List accountVlanMaps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId); + if (accountVlanMaps.isEmpty()) { + return null; + } else { + return accountVlanMaps.get(0).getAccountId(); + } + } + + public static HypervisorType getVolumeHyperType(long volumeId) { + return _volumeDao.getHypervisorType(volumeId); + } + + public static HypervisorType getHypervisorTypeFromFormat(ImageFormat format){ + return _storageMgr.getHypervisorTypeFromFormat(format); + } + + public static List listTemplateHostBy(long templateId, Long zoneId, boolean readyOnly) { + if (zoneId != null) { + VMTemplateVO vmTemplate = findTemplateById(templateId); + if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { + return _templateHostDao.listByTemplateId(templateId); + } else { + return _templateHostDao.listByZoneTemplate(zoneId, templateId, readyOnly); + } + } else { + return _templateHostDao.listByOnlyTemplateId(templateId); + } + } + + public static List listUserStatsBy(Long accountId) { + return _userStatsDao.listBy(accountId); + } + + public static List listUserVMsByHostId(long hostId) { + return _userVmDao.listByHostId(hostId); + } + + public static List listZones() { + return _zoneDao.listAll(); + } + + public static boolean volumeIsOnSharedStorage(long volumeId) { + // Check that the volume is valid + VolumeVO volume = _volumeDao.findById(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("Please specify a valid volume ID.", null); + } + + return _storageMgr.volumeOnSharedStoragePool(volume); + } + + public static List getNics(VirtualMachine vm) { + return _networkMgr.getNicProfiles(vm); + } + + public static NetworkProfile getNetworkProfile(long networkId) { + return _networkMgr.convertNetworkToNetworkProfile(networkId); + } + + public static NetworkOfferingVO findNetworkOfferingById(long networkOfferingId) { + return _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId); + } + + public static List listVlanByNetworkId(long networkId) { + return _vlanDao.listVlansByNetworkId(networkId); + } + + public static NetworkVO findNetworkById(long id) { + return _networkDao.findById(id); + } + + public static Map> getNetworkCapabilities(long networkId, long zoneId) { + return _networkMgr.getNetworkCapabilities(networkId); + } + + public static long getPublicNetworkIdByZone(long zoneId) { + return _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId(); + } + + public static Long getVlanNetworkId(long vlanId) { + VlanVO vlan = _vlanDao.findById(vlanId); + if (vlan != null) { + return vlan.getNetworkId(); + } else { + return null; + } + } + + public static Integer getNetworkRate(long networkOfferingId) { + return _configMgr.getNetworkOfferingNetworkRate(networkOfferingId); + } + + public static Account getVlanAccount(long vlanId) { + return _configMgr.getVlanAccount(vlanId); + } + + public static boolean isSecurityGroupEnabledInZone(long zoneId) { + DataCenterVO dc = _zoneDao.findById(zoneId); + if (dc == null) { + return false; + } else { + return dc.isSecurityGroupEnabled(); + } + } + + public static Long getDedicatedNetworkDomain(long networkId) { + return _networkMgr.getDedicatedNetworkDomain(networkId); + } + + public static float getCpuOverprovisioningFactor() { + String opFactor = _configDao.getValue(Config.CPUOverprovisioningFactor.key()); + float cpuOverprovisioningFactor = NumbersUtil.parseFloat(opFactor, 1); + return cpuOverprovisioningFactor; + } + + public static boolean isExtractionDisabled(){ + 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); + } + + public static ConsoleProxyVO findConsoleProxy(long id) { + return _consoleProxyDao.findById(id); + } + + public static List findFirewallSourceCidrs(long 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); + } + + 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; + } + + public static Map> listNetworkOfferingServices(long networkOfferingId) { + return _networkMgr.getNetworkOfferingServiceProvidersMap(networkOfferingId); + } + + public static List getElementServices(Provider 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); + } + + public static long 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(); + } + + public static String getUuid(String resourceId, TaggedResourceType resourceType) { + return _taggedResourceService.getUuid(resourceId, resourceType); + } + + public static Map> listVpcOffServices(long vpcOffId) { + return _vpcMgr.getVpcOffSvcProvidersMap(vpcOffId); + } + + public static List listVpcNetworks(long vpcId) { + return _networkMgr.listNetworksByVpc(vpcId); + } + + public static boolean canUseForDeploy(Network network) { + return _networkMgr.canUseForDeploy(network); + } + + 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 List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { + return _taggedResourceService.listByResourceTypeAndId(type, resourceId); + } + + public static boolean isOfferingForVpc(NetworkOffering offering) { + boolean vpcProvider = _configMgr.isOfferingForVpc(offering); + return vpcProvider; + } + + 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 d7fc489e8fa..d63732c8410 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1,3872 +1,4030 @@ -// 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.api; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.apache.log4j.Logger; - -import com.cloud.acl.ControlledEntity; -import com.cloud.acl.ControlledEntity.ACLType; -import com.cloud.api.ApiConstants.HostDetails; -import com.cloud.api.ApiConstants.VMDetails; -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.CapabilityResponse; -import com.cloud.api.response.CapacityResponse; -import com.cloud.api.response.ClusterResponse; -import com.cloud.api.response.ConfigurationResponse; -import com.cloud.api.response.ControlledEntityResponse; -import com.cloud.api.response.CreateCmdResponse; -import com.cloud.api.response.DiskOfferingResponse; -import com.cloud.api.response.DomainResponse; -import com.cloud.api.response.DomainRouterResponse; -import com.cloud.api.response.EventResponse; -import com.cloud.api.response.ExtractResponse; -import com.cloud.api.response.FirewallResponse; -import com.cloud.api.response.FirewallRuleResponse; -import com.cloud.api.response.HostResponse; -import com.cloud.api.response.HypervisorCapabilitiesResponse; -import com.cloud.api.response.IPAddressResponse; -import com.cloud.api.response.InstanceGroupResponse; -import com.cloud.api.response.IpForwardingRuleResponse; -import com.cloud.api.response.LBStickinessPolicyResponse; -import com.cloud.api.response.LBStickinessResponse; -import com.cloud.api.response.LDAPConfigResponse; -import com.cloud.api.response.ListResponse; -import com.cloud.api.response.LoadBalancerResponse; -import com.cloud.api.response.NetworkACLResponse; -import com.cloud.api.response.NetworkOfferingResponse; -import com.cloud.api.response.NetworkResponse; -import com.cloud.api.response.NicResponse; -import com.cloud.api.response.PhysicalNetworkResponse; -import com.cloud.api.response.PodResponse; -import com.cloud.api.response.PrivateGatewayResponse; -import com.cloud.api.response.ProjectAccountResponse; -import com.cloud.api.response.ProjectInvitationResponse; -import com.cloud.api.response.ProjectResponse; -import com.cloud.api.response.ProviderResponse; -import com.cloud.api.response.RemoteAccessVpnResponse; -import com.cloud.api.response.ResourceCountResponse; -import com.cloud.api.response.ResourceLimitResponse; -import com.cloud.api.response.ResourceTagResponse; -import com.cloud.api.response.SecurityGroupResponse; -import com.cloud.api.response.SecurityGroupResultObject; -import com.cloud.api.response.SecurityGroupRuleResponse; -import com.cloud.api.response.SecurityGroupRuleResultObject; -import com.cloud.api.response.ServiceOfferingResponse; -import com.cloud.api.response.ServiceResponse; -import com.cloud.api.response.Site2SiteCustomerGatewayResponse; -import com.cloud.api.response.Site2SiteVpnConnectionResponse; -import com.cloud.api.response.Site2SiteVpnGatewayResponse; -import com.cloud.api.response.SnapshotPolicyResponse; -import com.cloud.api.response.SnapshotResponse; -import com.cloud.api.response.StaticRouteResponse; -import com.cloud.api.response.StorageNetworkIpRangeResponse; -import com.cloud.api.response.StoragePoolResponse; -import com.cloud.api.response.SwiftResponse; -import com.cloud.api.response.SystemVmInstanceResponse; -import com.cloud.api.response.SystemVmResponse; -import com.cloud.api.response.TemplatePermissionsResponse; -import com.cloud.api.response.TemplateResponse; -import com.cloud.api.response.TrafficTypeResponse; -import com.cloud.api.response.UserResponse; -import com.cloud.api.response.UserVmResponse; -import com.cloud.api.response.VirtualRouterProviderResponse; -import com.cloud.api.response.VlanIpRangeResponse; -import com.cloud.api.response.VolumeResponse; -import com.cloud.api.response.VpcOfferingResponse; -import com.cloud.api.response.VpcResponse; -import com.cloud.api.response.VpnUsersResponse; -import com.cloud.api.response.ZoneResponse; -import com.cloud.async.AsyncJob; -import com.cloud.capacity.Capacity; -import com.cloud.capacity.CapacityVO; -import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; -import com.cloud.configuration.Configuration; -import com.cloud.configuration.Resource.ResourceOwnerType; -import com.cloud.configuration.Resource.ResourceType; -import com.cloud.configuration.ResourceCount; -import com.cloud.configuration.ResourceLimit; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.StorageNetworkIpRange; -import com.cloud.dc.Vlan; -import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; -import com.cloud.domain.Domain; -import com.cloud.event.Event; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.Host; -import com.cloud.host.HostStats; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; -import com.cloud.network.Network.Capability; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; -import com.cloud.network.NetworkProfile; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteCustomerGatewayVO; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StickinessPolicy; -import com.cloud.network.security.SecurityGroup; -import com.cloud.network.security.SecurityGroupRules; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.network.security.SecurityRule; -import com.cloud.network.security.SecurityRule.SecurityRuleType; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.StaticRoute; -import com.cloud.network.vpc.Vpc; -import com.cloud.network.vpc.VpcOffering; -import com.cloud.offering.DiskOffering; -import com.cloud.offering.NetworkOffering; -import com.cloud.offering.ServiceOffering; -import com.cloud.org.Cluster; -import com.cloud.projects.Project; -import com.cloud.projects.ProjectAccount; -import com.cloud.projects.ProjectInvitation; -import com.cloud.server.Criteria; -import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.Swift; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.snapshot.SnapshotPolicy; -import com.cloud.template.VirtualMachineTemplate; -import com.cloud.test.PodZoneConfig; -import com.cloud.user.Account; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.user.UserContext; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserVO; -import com.cloud.uservm.UserVm; -import com.cloud.utils.Pair; -import com.cloud.utils.StringUtils; -import com.cloud.utils.net.NetUtils; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.InstanceGroup; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachine.Type; -import com.cloud.vm.VmStats; -import com.cloud.vm.dao.UserVmData; -import com.cloud.vm.dao.UserVmData.NicData; -import com.cloud.vm.dao.UserVmData.SecurityGroupData; - -public class ApiResponseHelper implements ResponseGenerator { - - public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class); - private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##"); - - @Override - public UserResponse createUserResponse(User user) { - UserResponse userResponse = new UserResponse(); - Account account = ApiDBUtils.findAccountById(user.getAccountId()); - userResponse.setAccountName(account.getAccountName()); - userResponse.setAccountType(account.getType()); - userResponse.setCreated(user.getCreated()); - userResponse.setDomainId(account.getDomainId()); - userResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName()); - userResponse.setEmail(user.getEmail()); - userResponse.setFirstname(user.getFirstname()); - userResponse.setId(user.getId()); - userResponse.setLastname(user.getLastname()); - userResponse.setState(user.getState().toString()); - userResponse.setTimezone(user.getTimezone()); - userResponse.setUsername(user.getUsername()); - userResponse.setApiKey(user.getApiKey()); - userResponse.setSecretKey(user.getSecretKey()); - userResponse.setObjectName("user"); - - return userResponse; - } - - // this method is used for response generation via createAccount (which creates an account + user) - @Override - public AccountResponse createUserAccountResponse(UserAccount user) { - return createAccountResponse(ApiDBUtils.findAccountById(user.getAccountId())); - } - - @Override - public AccountResponse createAccountResponse(Account account) { - boolean accountIsAdmin = (account.getType() == Account.ACCOUNT_TYPE_ADMIN); - AccountResponse accountResponse = new AccountResponse(); - accountResponse.setId(account.getId()); - accountResponse.setName(account.getAccountName()); - accountResponse.setAccountType(account.getType()); - accountResponse.setDomainId(account.getDomainId()); - accountResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName()); - accountResponse.setState(account.getState().toString()); - accountResponse.setNetworkDomain(account.getNetworkDomain()); - accountResponse.setDefaultZone(account.getDefaultZoneId()); - - // get network stat - List stats = ApiDBUtils.listUserStatsBy(account.getId()); - if (stats == null) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal error searching for user stats"); - } - - Long bytesSent = 0L; - Long bytesReceived = 0L; - for (UserStatisticsVO stat : stats) { - Long rx = stat.getNetBytesReceived() + stat.getCurrentBytesReceived(); - Long tx = stat.getNetBytesSent() + stat.getCurrentBytesSent(); - bytesReceived = bytesReceived + Long.valueOf(rx); - bytesSent = bytesSent + Long.valueOf(tx); - } - accountResponse.setBytesReceived(bytesReceived); - accountResponse.setBytesSent(bytesSent); - - // Get resource limits and counts - - Long vmLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.user_vm, account.getId()); - String vmLimitDisplay = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit); - Long vmTotal = ApiDBUtils.getResourceCount(ResourceType.user_vm, account.getId()); - String vmAvail = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit - vmTotal); - accountResponse.setVmLimit(vmLimitDisplay); - accountResponse.setVmTotal(vmTotal); - accountResponse.setVmAvailable(vmAvail); - - Long ipLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.public_ip, account.getId()); - String ipLimitDisplay = (accountIsAdmin || ipLimit == -1) ? "Unlimited" : String.valueOf(ipLimit); - Long ipTotal = ApiDBUtils.getResourceCount(ResourceType.public_ip, account.getId()); - - Long ips = ipLimit - ipTotal; - // check how many free ips are left, and if it's less than max allowed number of ips from account - use this - // value - Long ipsLeft = ApiDBUtils.countFreePublicIps(); - boolean unlimited = true; - if (ips.longValue() > ipsLeft.longValue()) { - ips = ipsLeft; - unlimited = false; - } - - String ipAvail = ((accountIsAdmin || ipLimit == -1) && unlimited) ? "Unlimited" : String.valueOf(ips); - - accountResponse.setIpLimit(ipLimitDisplay); - accountResponse.setIpTotal(ipTotal); - accountResponse.setIpAvailable(ipAvail); - - Long volumeLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.volume, account.getId()); - String volumeLimitDisplay = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit); - Long volumeTotal = ApiDBUtils.getResourceCount(ResourceType.volume, account.getId()); - String volumeAvail = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit - volumeTotal); - accountResponse.setVolumeLimit(volumeLimitDisplay); - accountResponse.setVolumeTotal(volumeTotal); - accountResponse.setVolumeAvailable(volumeAvail); - - Long snapshotLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.snapshot, account.getId()); - String snapshotLimitDisplay = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit); - Long snapshotTotal = ApiDBUtils.getResourceCount(ResourceType.snapshot, account.getId()); - String snapshotAvail = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit - snapshotTotal); - accountResponse.setSnapshotLimit(snapshotLimitDisplay); - accountResponse.setSnapshotTotal(snapshotTotal); - accountResponse.setSnapshotAvailable(snapshotAvail); - - Long templateLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.template, account.getId()); - String templateLimitDisplay = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit); - Long templateTotal = ApiDBUtils.getResourceCount(ResourceType.template, account.getId()); - String templateAvail = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit - templateTotal); - accountResponse.setTemplateLimit(templateLimitDisplay); - accountResponse.setTemplateTotal(templateTotal); - accountResponse.setTemplateAvailable(templateAvail); - - // Get stopped and running VMs - int vmStopped = 0; - int vmRunning = 0; - - List permittedAccounts = new ArrayList(); - permittedAccounts.add(account.getId()); - - List virtualMachines = ApiDBUtils.searchForUserVMs(new Criteria(), permittedAccounts); - - // get Running/Stopped VMs - for (Iterator iter = virtualMachines.iterator(); iter.hasNext();) { - // count how many stopped/running vms we have - UserVm vm = iter.next(); - - if (vm.getState() == State.Stopped) { - vmStopped++; - } else if (vm.getState() == State.Running) { - vmRunning++; - } - } - - accountResponse.setVmStopped(vmStopped); - accountResponse.setVmRunning(vmRunning); - accountResponse.setObjectName("account"); - - //get resource limits for projects - Long projectLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.project, account.getId()); - String projectLimitDisplay = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit); - Long projectTotal = ApiDBUtils.getResourceCount(ResourceType.project, account.getId()); - String projectAvail = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal); - accountResponse.setProjectLimit(projectLimitDisplay); - accountResponse.setProjectTotal(projectTotal); - accountResponse.setProjectAvailable(projectAvail); - - //get resource limits for networks - Long networkLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.network, account.getId()); - String networkLimitDisplay = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit); - Long networkTotal = ApiDBUtils.getResourceCount(ResourceType.network, account.getId()); - String networkAvail = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal); - accountResponse.setNetworkLimit(networkLimitDisplay); - accountResponse.setNetworkTotal(networkTotal); - accountResponse.setNetworkAvailable(networkAvail); - - // adding all the users for an account as part of the response obj - List usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId()); - List userResponseList = new ArrayList(); - for (UserVO user : usersForAccount) { - UserResponse userResponse = createUserResponse(user); - userResponseList.add(userResponse); - } - - accountResponse.setUsers(userResponseList); - accountResponse.setDetails(ApiDBUtils.getAccountDetails(account.getId())); - return accountResponse; - } - - @Override - public UserResponse createUserResponse(UserAccount user) { - UserResponse userResponse = new UserResponse(); - userResponse.setAccountName(user.getAccountName()); - userResponse.setAccountType(user.getType()); - userResponse.setCreated(user.getCreated()); - userResponse.setDomainId(user.getDomainId()); - userResponse.setDomainName(ApiDBUtils.findDomainById(user.getDomainId()).getName()); - userResponse.setEmail(user.getEmail()); - userResponse.setFirstname(user.getFirstname()); - userResponse.setId(user.getId()); - userResponse.setLastname(user.getLastname()); - userResponse.setState(user.getState()); - userResponse.setTimezone(user.getTimezone()); - userResponse.setUsername(user.getUsername()); - userResponse.setApiKey(user.getApiKey()); - userResponse.setSecretKey(user.getSecretKey()); - userResponse.setAccountId((user.getAccountId())); - userResponse.setObjectName("user"); - - return userResponse; - } - - @Override - public DomainResponse createDomainResponse(Domain domain) { - DomainResponse domainResponse = new DomainResponse(); - domainResponse.setDomainName(domain.getName()); - domainResponse.setId(domain.getId()); - domainResponse.setLevel(domain.getLevel()); - domainResponse.setNetworkDomain(domain.getNetworkDomain()); - domainResponse.setParentDomainId(domain.getParent()); - StringBuilder domainPath = new StringBuilder("ROOT"); - (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1); - domainResponse.setPath(domainPath.toString()); - if (domain.getParent() != null) { - domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName()); - } - if (domain.getChildCount() > 0) { - domainResponse.setHasChild(true); - } - domainResponse.setObjectName("domain"); - return domainResponse; - } - - @Override - public DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering) { - DiskOfferingResponse diskOfferingResponse = new DiskOfferingResponse(); - diskOfferingResponse.setId(offering.getId()); - diskOfferingResponse.setName(offering.getName()); - diskOfferingResponse.setDisplayText(offering.getDisplayText()); - diskOfferingResponse.setCreated(offering.getCreated()); - diskOfferingResponse.setDiskSize(offering.getDiskSize() / (1024 * 1024 * 1024)); - if (offering.getDomainId() != null) { - diskOfferingResponse.setDomain(ApiDBUtils.findDomainById(offering.getDomainId()).getName()); - diskOfferingResponse.setDomainId(offering.getDomainId()); - } - diskOfferingResponse.setTags(offering.getTags()); - diskOfferingResponse.setCustomized(offering.isCustomized()); - diskOfferingResponse.setObjectName("diskoffering"); - return diskOfferingResponse; - } - - @Override - public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) { - ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse(); - if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) { - populateDomain(resourceLimitResponse, limit.getOwnerId()); - } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) { - Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId()); - populateAccount(resourceLimitResponse, limit.getOwnerId()); - populateDomain(resourceLimitResponse, accountTemp.getDomainId()); - } - resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); - resourceLimitResponse.setMax(limit.getMax()); - resourceLimitResponse.setObjectName("resourcelimit"); - - return resourceLimitResponse; - } - - @Override - public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) { - ResourceCountResponse resourceCountResponse = new ResourceCountResponse(); - - if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) { - Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId()); - if (accountTemp != null) { - populateAccount(resourceCountResponse, accountTemp.getId()); - populateDomain(resourceCountResponse, accountTemp.getDomainId()); - } - } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) { - populateDomain(resourceCountResponse, resourceCount.getOwnerId()); - } - - resourceCountResponse.setResourceType(Integer.valueOf(resourceCount.getType().getOrdinal()).toString()); - resourceCountResponse.setResourceCount(resourceCount.getCount()); - resourceCountResponse.setObjectName("resourcecount"); - return resourceCountResponse; - } - - @Override - public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) { - ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse(); - offeringResponse.setId(offering.getId()); - offeringResponse.setName(offering.getName()); - offeringResponse.setIsSystemOffering(offering.getSystemUse()); - offeringResponse.setDefaultUse(offering.getDefaultUse()); - offeringResponse.setSystemVmType(offering.getSystemVmType()); - offeringResponse.setDisplayText(offering.getDisplayText()); - offeringResponse.setCpuNumber(offering.getCpu()); - offeringResponse.setCpuSpeed(offering.getSpeed()); - offeringResponse.setMemory(offering.getRamSize()); - offeringResponse.setCreated(offering.getCreated()); - offeringResponse.setStorageType(offering.getUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString()); - offeringResponse.setOfferHa(offering.getOfferHA()); - offeringResponse.setLimitCpuUse(offering.getLimitCpuUse()); - offeringResponse.setTags(offering.getTags()); - if (offering.getDomainId() != null) { - offeringResponse.setDomain(ApiDBUtils.findDomainById(offering.getDomainId()).getName()); - offeringResponse.setDomainId(offering.getDomainId()); - } - offeringResponse.setNetworkRate(offering.getRateMbps()); - offeringResponse.setHostTag(offering.getHostTag()); - offeringResponse.setObjectName("serviceoffering"); - - return offeringResponse; - } - - @Override - public ConfigurationResponse createConfigurationResponse(Configuration cfg) { - ConfigurationResponse cfgResponse = new ConfigurationResponse(); - cfgResponse.setCategory(cfg.getCategory()); - cfgResponse.setDescription(cfg.getDescription()); - cfgResponse.setName(cfg.getName()); - cfgResponse.setValue(cfg.getValue()); - cfgResponse.setObjectName("configuration"); - - return cfgResponse; - } - - @Override - public SnapshotResponse createSnapshotResponse(Snapshot snapshot) { - SnapshotResponse snapshotResponse = new SnapshotResponse(); - snapshotResponse.setId(snapshot.getId()); - - populateOwner(snapshotResponse, snapshot); - - VolumeVO volume = findVolumeById(snapshot.getVolumeId()); - String snapshotTypeStr = snapshot.getType().name(); - snapshotResponse.setSnapshotType(snapshotTypeStr); - snapshotResponse.setVolumeId(snapshot.getVolumeId()); - if (volume != null) { - snapshotResponse.setVolumeName(volume.getName()); - snapshotResponse.setVolumeType(volume.getVolumeType().name()); - } - snapshotResponse.setCreated(snapshot.getCreated()); - 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(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - snapshotResponse.setTags(tagResponses); - - snapshotResponse.setObjectName("snapshot"); - return snapshotResponse; - } - - @Override - public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) { - SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse(); - policyResponse.setId(policy.getId()); - policyResponse.setVolumeId(policy.getVolumeId()); - policyResponse.setSchedule(policy.getSchedule()); - policyResponse.setIntervalType(policy.getInterval()); - policyResponse.setMaxSnaps(policy.getMaxSnaps()); - policyResponse.setTimezone(policy.getTimezone()); - policyResponse.setObjectName("snapshotpolicy"); - - return policyResponse; - } - - @Override - public HostResponse createHostResponse(Host host) { - return createHostResponse(host, EnumSet.of(HostDetails.all)); - } - - @Override - public HostResponse createHostResponse(Host host, EnumSet details) { - HostResponse hostResponse = new HostResponse(); - hostResponse.setId(host.getId()); - hostResponse.setCapabilities(host.getCapabilities()); - hostResponse.setClusterId(host.getClusterId()); - hostResponse.setCpuNumber(host.getCpus()); - hostResponse.setZoneId(host.getDataCenterId()); - hostResponse.setDisconnectedOn(host.getDisconnectedOn()); - hostResponse.setHypervisor(host.getHypervisorType()); - hostResponse.setHostType(host.getType()); - hostResponse.setLastPinged(new Date(host.getLastPinged())); - hostResponse.setManagementServerId(host.getManagementServerId()); - hostResponse.setName(host.getName()); - hostResponse.setPodId(host.getPodId()); - hostResponse.setRemoved(host.getRemoved()); - hostResponse.setCpuSpeed(host.getSpeed()); - hostResponse.setState(host.getStatus()); - hostResponse.setIpAddress(host.getPrivateIpAddress()); - hostResponse.setVersion(host.getVersion()); - hostResponse.setCreated(host.getCreated()); - - if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity) - || details.contains(HostDetails.stats) || details.contains(HostDetails.events)) { - - GuestOSCategoryVO guestOSCategory = ApiDBUtils.getHostGuestOSCategory(host.getId()); - if (guestOSCategory != null) { - hostResponse.setOsCategoryId(guestOSCategory.getId()); - hostResponse.setOsCategoryName(guestOSCategory.getName()); - } - hostResponse.setZoneName(ApiDBUtils.findZoneById(host.getDataCenterId()).getName()); - - if (host.getPodId() != null) { - HostPodVO pod = ApiDBUtils.findPodById(host.getPodId()); - if (pod != null) { - hostResponse.setPodName(pod.getName()); - } - } - - if (host.getClusterId() != null) { - ClusterVO cluster = ApiDBUtils.findClusterById(host.getClusterId()); - hostResponse.setClusterName(cluster.getName()); - hostResponse.setClusterType(cluster.getClusterType().toString()); - } - } - - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - if (host.getType() == Host.Type.Routing) { - if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)) { - // set allocated capacities - Long mem = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_MEMORY); - Long cpu = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_CPU); - - hostResponse.setMemoryAllocated(mem); - 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)) { - hostResponse.setHaHost(true); - } else { - hostResponse.setHaHost(false); - } - } else { - hostResponse.setHaHost(false); - } - - hostResponse.setHypervisorVersion(host.getHypervisorVersion()); - - String cpuAlloc = decimalFormat.format(((float) cpu / (float) (host.getCpus() * host.getSpeed())) * 100f) + "%"; - hostResponse.setCpuAllocated(cpuAlloc); - String cpuWithOverprovisioning = new Float(host.getCpus() * host.getSpeed() * ApiDBUtils.getCpuOverprovisioningFactor()).toString(); - hostResponse.setCpuWithOverprovisioning(cpuWithOverprovisioning); - } - - if (details.contains(HostDetails.all) || details.contains(HostDetails.stats)) { - // set CPU/RAM/Network stats - String cpuUsed = null; - HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId()); - if (hostStats != null) { - float cpuUtil = (float) hostStats.getCpuUtilization(); - cpuUsed = decimalFormat.format(cpuUtil) + "%"; - hostResponse.setCpuUsed(cpuUsed); - hostResponse.setMemoryUsed((new Double(hostStats.getUsedMemory())).longValue()); - hostResponse.setNetworkKbsRead((new Double(hostStats.getNetworkReadKBs())).longValue()); - hostResponse.setNetworkKbsWrite((new Double(hostStats.getNetworkWriteKBs())).longValue()); - - } - } - - } else if (host.getType() == Host.Type.SecondaryStorage) { - StorageStats secStorageStats = ApiDBUtils.getSecondaryStorageStatistics(host.getId()); - if (secStorageStats != null) { - hostResponse.setDiskSizeTotal(secStorageStats.getCapacityBytes()); - hostResponse.setDiskSizeAllocated(secStorageStats.getByteUsed()); - } - } - - hostResponse.setLocalStorageActive(ApiDBUtils.isLocalStorageActiveOnHost(host)); - - if (details.contains(HostDetails.all) || details.contains(HostDetails.events)) { - Set possibleEvents = host.getStatus().getPossibleEvents(); - if ((possibleEvents != null) && !possibleEvents.isEmpty()) { - String events = ""; - Iterator iter = possibleEvents.iterator(); - while (iter.hasNext()) { - com.cloud.host.Status.Event event = iter.next(); - events += event.toString(); - if (iter.hasNext()) { - events += "; "; - } - } - hostResponse.setEvents(events); - } - } - - hostResponse.setResourceState(host.getResourceState().toString()); - hostResponse.setObjectName("host"); - - return hostResponse; - } - - @Override - public SwiftResponse createSwiftResponse(Swift swift) { - SwiftResponse swiftResponse = new SwiftResponse(); - swiftResponse.setId(swift.getId()); - swiftResponse.setUrl(swift.getUrl()); - swiftResponse.setAccount(swift.getAccount()); - swiftResponse.setUsername(swift.getUserName()); - swiftResponse.setObjectName("swift"); - return swiftResponse; - } - - @Override - public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) { - Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId()); - - VlanIpRangeResponse vlanResponse = new VlanIpRangeResponse(); - vlanResponse.setId(vlan.getId()); - vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork)); - vlanResponse.setVlan(vlan.getVlanTag()); - vlanResponse.setZoneId(vlan.getDataCenterId()); - - if (podId != null) { - HostPodVO pod = ApiDBUtils.findPodById(podId); - vlanResponse.setPodId(podId); - if (pod != null) { - vlanResponse.setPodName(pod.getName()); - } - } - - vlanResponse.setGateway(vlan.getVlanGateway()); - vlanResponse.setNetmask(vlan.getVlanNetmask()); - - // get start ip and end ip of corresponding vlan - String ipRange = vlan.getIpRange(); - String[] range = ipRange.split("-"); - vlanResponse.setStartIp(range[0]); - vlanResponse.setEndIp(range[1]); - - vlanResponse.setNetworkId(vlan.getNetworkId()); - Account owner = ApiDBUtils.getVlanAccount(vlan.getId()); - if (owner != null) { - populateAccount(vlanResponse, owner.getId()); - populateDomain(vlanResponse, owner.getDomainId()); - } - - vlanResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId()); - - vlanResponse.setObjectName("vlan"); - return vlanResponse; - } - - @Override - public IPAddressResponse createIPAddressResponse(IpAddress ipAddr) { - VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId()); - boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork); - long zoneId = ipAddr.getDataCenterId(); - - IPAddressResponse ipResponse = new IPAddressResponse(); - ipResponse.setId(ipAddr.getId()); - ipResponse.setIpAddress(ipAddr.getAddress().toString()); - if (ipAddr.getAllocatedTime() != null) { - ipResponse.setAllocated(ipAddr.getAllocatedTime()); - } - ipResponse.setZoneId(zoneId); - ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddr.getDataCenterId()).getName()); - ipResponse.setSourceNat(ipAddr.isSourceNat()); - ipResponse.setIsSystem(ipAddr.getSystem()); - - // get account information - if (ipAddr.getAllocatedToAccountId() != null) { - populateOwner(ipResponse, ipAddr); - } - - ipResponse.setForVirtualNetwork(forVirtualNetworks); - ipResponse.setStaticNat(ipAddr.isOneToOneNat()); - - if (ipAddr.getAssociatedWithVmId() != null) { - UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId()); - ipResponse.setVirtualMachineId(vm.getId()); - ipResponse.setVirtualMachineName(vm.getHostName()); - if (vm.getDisplayName() != null) { - ipResponse.setVirtualMachineDisplayName(vm.getDisplayName()); - } else { - ipResponse.setVirtualMachineDisplayName(vm.getHostName()); - } - } - - ipResponse.setAssociatedNetworkId(ipAddr.getAssociatedWithNetworkId()); - ipResponse.setVpcId(ipAddr.getVpcId()); - - // Network id the ip is associated with (if associated networkId is null, try to get this information from vlan) - Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId()); - - // Network id the ip belongs to - Long networkId; - if (vlanNetworkId != null) { - networkId = vlanNetworkId; - } else { - networkId = ApiDBUtils.getPublicNetworkIdByZone(zoneId); - } - - ipResponse.setNetworkId(networkId); - ipResponse.setState(ipAddr.getState().toString()); - ipResponse.setPhysicalNetworkId(ipAddr.getPhysicalNetworkId()); - - // show this info to admin only - Account account = UserContext.current().getCaller(); - if ((account == null) || account.getType() == Account.ACCOUNT_TYPE_ADMIN) { - ipResponse.setVlanId(ipAddr.getVlanId()); - ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); - } - - if (ipAddr.getSystem()) { - if (ipAddr.isOneToOneNat()) { - ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString()); - } else { - ipResponse.setPurpose(IpAddress.Purpose.Lb.toString()); - } - } - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - ipResponse.setTags(tagResponses); - - ipResponse.setObjectName("ipaddress"); - return ipResponse; - } - - @Override - public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer) { - LoadBalancerResponse lbResponse = new LoadBalancerResponse(); - lbResponse.setId(loadBalancer.getId()); - lbResponse.setName(loadBalancer.getName()); - lbResponse.setDescription(loadBalancer.getDescription()); - List cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId()); - lbResponse.setCidrList(StringUtils.join(cidrs, ",")); - - IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId()); - lbResponse.setPublicIpId(publicIp.getId()); - lbResponse.setPublicIp(publicIp.getAddress().addr()); - lbResponse.setPublicPort(Integer.toString(loadBalancer.getSourcePortStart())); - lbResponse.setPrivatePort(Integer.toString(loadBalancer.getDefaultPortStart())); - lbResponse.setAlgorithm(loadBalancer.getAlgorithm()); - FirewallRule.State state = loadBalancer.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - lbResponse.setState(stateToSet); - populateOwner(lbResponse, loadBalancer); - lbResponse.setZoneId(publicIp.getDataCenterId()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, loadBalancer.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - lbResponse.setTags(tagResponses); - - lbResponse.setObjectName("loadbalancer"); - return lbResponse; - } - - @Override - public PodResponse createPodResponse(Pod pod, Boolean showCapacities) { - String[] ipRange = new String[2]; - if (pod.getDescription() != null && pod.getDescription().length() > 0) { - ipRange = pod.getDescription().split("-"); - } else { - ipRange[0] = pod.getDescription(); - } - - PodResponse podResponse = new PodResponse(); - podResponse.setId(pod.getId()); - podResponse.setName(pod.getName()); - podResponse.setZoneId(pod.getDataCenterId()); - podResponse.setZoneName(PodZoneConfig.getZoneName(pod.getDataCenterId())); - podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize())); - podResponse.setStartIp(ipRange[0]); - podResponse.setEndIp(((ipRange.length > 1) && (ipRange[1] != null)) ? ipRange[1] : ""); - podResponse.setGateway(pod.getGateway()); - podResponse.setAllocationState(pod.getAllocationState().toString()); - if (showCapacities != null && showCapacities) { - List capacities = ApiDBUtils.getCapacityByClusterPodZone(null, pod.getId(), null); - Set capacityResponses = new HashSet(); - float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); - - for (SummedCapacity capacity : capacities) { - CapacityResponse capacityResponse = new CapacityResponse(); - capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); - if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { - capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); - } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { - List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null); - capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); - } else { - capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); - } - if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); - } else { - capacityResponse.setPercentUsed(s_percentFormat.format(0L)); - } - capacityResponses.add(capacityResponse); - } - // Do it for stats as well. - capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId())); - podResponse.setCapacitites(new ArrayList(capacityResponses)); - } - podResponse.setObjectName("pod"); - return podResponse; - } - - @Override - public ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities) { - Account account = UserContext.current().getCaller(); - ZoneResponse zoneResponse = new ZoneResponse(); - zoneResponse.setId(dataCenter.getId()); - zoneResponse.setName(dataCenter.getName()); - zoneResponse.setSecurityGroupsEnabled(ApiDBUtils.isSecurityGroupEnabledInZone(dataCenter.getId())); - - if ((dataCenter.getDescription() != null) && !dataCenter.getDescription().equalsIgnoreCase("null")) { - zoneResponse.setDescription(dataCenter.getDescription()); - } - - if ((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) { - zoneResponse.setDns1(dataCenter.getDns1()); - zoneResponse.setDns2(dataCenter.getDns2()); - zoneResponse.setInternalDns1(dataCenter.getInternalDns1()); - zoneResponse.setInternalDns2(dataCenter.getInternalDns2()); - // FIXME zoneResponse.setVlan(dataCenter.get.getVnet()); - zoneResponse.setGuestCidrAddress(dataCenter.getGuestNetworkCidr()); - } - - if (showCapacities != null && showCapacities) { - List capacities = ApiDBUtils.getCapacityByClusterPodZone(dataCenter.getId(), null, null); - Set capacityResponses = new HashSet(); - float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); - - for (SummedCapacity capacity : capacities) { - CapacityResponse capacityResponse = new CapacityResponse(); - capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); - if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { - capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); - } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { - List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(dataCenter.getId(), null, null); - capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); - } else { - capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); - } - if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); - } else { - capacityResponse.setPercentUsed(s_percentFormat.format(0L)); - } - capacityResponses.add(capacityResponse); - } - // Do it for stats as well. - capacityResponses.addAll(getStatsCapacityresponse(null, null, null, dataCenter.getId())); - - zoneResponse.setCapacitites(new ArrayList(capacityResponses)); - } - - // set network domain info - zoneResponse.setDomain(dataCenter.getDomain()); - - // set domain info - Long domainId = dataCenter.getDomainId(); - if (domainId != null) { - Domain domain = ApiDBUtils.findDomainById(domainId); - zoneResponse.setDomainId(domain.getId()); - zoneResponse.setDomainName(domain.getName()); - } - - zoneResponse.setType(dataCenter.getNetworkType().toString()); - zoneResponse.setAllocationState(dataCenter.getAllocationState().toString()); - zoneResponse.setZoneToken(dataCenter.getZoneToken()); - zoneResponse.setDhcpProvider(dataCenter.getDhcpProvider()); - zoneResponse.setObjectName("zone"); - return zoneResponse; - } - - private List getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) { - List capacities = new ArrayList(); - capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId)); - if (clusterId == null && podId == null) { - capacities.add(ApiDBUtils.getSecondaryStorageUsedStats(poolId, zoneId)); - } - - List capacityResponses = new ArrayList(); - for (CapacityVO capacity : capacities) { - CapacityResponse capacityResponse = new CapacityResponse(); - capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); - capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); - if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); - } else { - capacityResponse.setPercentUsed(s_percentFormat.format(0L)); - } - capacityResponses.add(capacityResponse); - } - - return capacityResponses; - } - - @Override - public VolumeResponse createVolumeResponse(Volume volume) { - VolumeResponse volResponse = new VolumeResponse(); - volResponse.setId(volume.getId()); - - if (volume.getName() != null) { - volResponse.setName(volume.getName()); - } else { - volResponse.setName(""); - } - - volResponse.setZoneId(volume.getDataCenterId()); - volResponse.setZoneName(ApiDBUtils.findZoneById(volume.getDataCenterId()).getName()); - - volResponse.setVolumeType(volume.getVolumeType().toString()); - volResponse.setDeviceId(volume.getDeviceId()); - - Long instanceId = volume.getInstanceId(); - if (instanceId != null && volume.getState() != Volume.State.Destroy) { - VMInstanceVO vm = ApiDBUtils.findVMInstanceById(instanceId); - if (vm != null) { - volResponse.setVirtualMachineId(vm.getId()); - volResponse.setVirtualMachineName(vm.getHostName()); - UserVm userVm = ApiDBUtils.findUserVmById(vm.getId()); - if (userVm != null) { - if (userVm.getDisplayName() != null) { - volResponse.setVirtualMachineDisplayName(userVm.getDisplayName()); - } else { - volResponse.setVirtualMachineDisplayName(userVm.getHostName()); - } - volResponse.setVirtualMachineState(vm.getState().toString()); - } else { - s_logger.error("User Vm with Id: " + instanceId + " does not exist for volume " + volume.getId()); - } - } else { - s_logger.error("Vm with Id: " + instanceId + " does not exist for volume " + volume.getId()); - } - } - - // Show the virtual size of the volume - volResponse.setSize(volume.getSize()); - - volResponse.setCreated(volume.getCreated()); - volResponse.setState(volume.getState().toString()); - if(volume.getState() == Volume.State.UploadOp){ - com.cloud.storage.VolumeHostVO volumeHostRef = ApiDBUtils.findVolumeHostRef(volume.getId(), volume.getDataCenterId()); - volResponse.setSize(volumeHostRef.getSize()); - 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()); - if (volumeHostRef.getDownloadState() != Status.DOWNLOADED) { - String volumeStatus = "Processing"; - if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { - if (volumeHostRef.getDownloadPercent() == 100) { - volumeStatus = "Checking Volume"; - } else { - volumeStatus = volumeHostRef.getDownloadPercent() + "% Uploaded"; - } - volResponse.setState("Uploading"); - } else { - volumeStatus = volumeHostRef.getErrorString(); - if(volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.NOT_DOWNLOADED){ - volResponse.setState("UploadNotStarted"); - }else { - volResponse.setState("UploadError"); - } - } - volResponse.setStatus(volumeStatus); - } else if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { - volResponse.setStatus("Upload Complete"); - volResponse.setState("Uploaded"); - } else { - volResponse.setStatus("Successfully Installed"); - } - } - - populateOwner(volResponse, volume); - - String storageType; - try { - if (volume.getPoolId() == null) { - if (volume.getState() == Volume.State.Allocated || volume.getState() == Volume.State.UploadOp) { - /* set it as shared, so the UI can attach it to VM */ - storageType = "shared"; - } else { - storageType = "unknown"; - } - } else { - storageType = ApiDBUtils.volumeIsOnSharedStorage(volume.getId()) ? ServiceOffering.StorageType.shared.toString() : ServiceOffering.StorageType.local.toString(); - } - } catch (InvalidParameterValueException e) { - s_logger.error(e.getMessage(), e); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Volume " + volume.getName() + " does not have a valid ID"); - } - - volResponse.setStorageType(storageType); - if (volume.getVolumeType().equals(Volume.Type.ROOT)) { - volResponse.setServiceOfferingId(volume.getDiskOfferingId()); - } else { - volResponse.setDiskOfferingId(volume.getDiskOfferingId()); - } - - DiskOfferingVO diskOffering = ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId()); - if (volume.getVolumeType().equals(Volume.Type.ROOT)) { - volResponse.setServiceOfferingName(diskOffering.getName()); - volResponse.setServiceOfferingDisplayText(diskOffering.getDisplayText()); - } else { - volResponse.setDiskOfferingName(diskOffering.getName()); - volResponse.setDiskOfferingDisplayText(diskOffering.getDisplayText()); - } - - Long poolId = volume.getPoolId(); - String poolName = (poolId == null) ? "none" : ApiDBUtils.findStoragePoolById(poolId).getName(); - volResponse.setStoragePoolName(poolName); - // volResponse.setSourceId(volume.getSourceId()); - // if (volume.getSourceType() != null) { - // volResponse.setSourceType(volume.getSourceType().toString()); - // } - - // return hypervisor for ROOT and Resource domain only - Account caller = UserContext.current().getCaller(); - if ((caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) && volume.getState() != Volume.State.UploadOp) { - volResponse.setHypervisor(ApiDBUtils.getVolumeHyperType(volume.getId()).toString()); - } - - volResponse.setAttached(volume.getAttached()); - 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; - } - } - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Volume, volume.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - volResponse.setTags(tagResponses); - - volResponse.setExtractable(isExtractable); - volResponse.setObjectName("volume"); - return volResponse; - } - - @Override - public InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group) { - InstanceGroupResponse groupResponse = new InstanceGroupResponse(); - groupResponse.setId(group.getId()); - groupResponse.setName(group.getName()); - groupResponse.setCreated(group.getCreated()); - - populateOwner(groupResponse, group); - - groupResponse.setObjectName("instancegroup"); - return groupResponse; - } - - @Override - public StoragePoolResponse createStoragePoolResponse(StoragePool pool) { - StoragePoolResponse poolResponse = new StoragePoolResponse(); - poolResponse.setId(pool.getId()); - poolResponse.setName(pool.getName()); - poolResponse.setState(pool.getStatus()); - poolResponse.setPath(pool.getPath()); - poolResponse.setIpAddress(pool.getHostAddress()); - poolResponse.setZoneId(pool.getDataCenterId()); - poolResponse.setZoneName(ApiDBUtils.findZoneById(pool.getDataCenterId()).getName()); - if (pool.getPoolType() != null) { - poolResponse.setType(pool.getPoolType().toString()); - } - if (pool.getPodId() != null) { - poolResponse.setPodId(pool.getPodId()); - HostPodVO pod = ApiDBUtils.findPodById(pool.getPodId()); - if (pod != null) { - poolResponse.setPodName(pod.getName()); - } - } - if (pool.getCreated() != null) { - poolResponse.setCreated(pool.getCreated()); - } - - StorageStats stats = ApiDBUtils.getStoragePoolStatistics(pool.getId()); - long allocatedSize = ApiDBUtils.getStorageCapacitybyPool(pool.getId(), Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED); - poolResponse.setDiskSizeTotal(pool.getCapacityBytes()); - poolResponse.setDiskSizeAllocated(allocatedSize); - - if (stats != null) { - Long used = stats.getByteUsed(); - poolResponse.setDiskSizeUsed(used); - } - - if (pool.getClusterId() != null) { - ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId()); - poolResponse.setClusterId(cluster.getId()); - poolResponse.setClusterName(cluster.getName()); - } - poolResponse.setTags(ApiDBUtils.getStoragePoolTags(pool.getId())); - poolResponse.setObjectName("storagepool"); - return poolResponse; - } - - @Override - public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) { - ClusterResponse clusterResponse = new ClusterResponse(); - clusterResponse.setId(cluster.getId()); - clusterResponse.setName(cluster.getName()); - clusterResponse.setPodId(cluster.getPodId()); - clusterResponse.setZoneId(cluster.getDataCenterId()); - clusterResponse.setHypervisorType(cluster.getHypervisorType().toString()); - clusterResponse.setClusterType(cluster.getClusterType().toString()); - clusterResponse.setAllocationState(cluster.getAllocationState().toString()); - clusterResponse.setManagedState(cluster.getManagedState().toString()); - HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId()); - if (pod != null) { - clusterResponse.setPodName(pod.getName()); - } - DataCenterVO zone = ApiDBUtils.findZoneById(cluster.getDataCenterId()); - clusterResponse.setZoneName(zone.getName()); - if (showCapacities != null && showCapacities) { - List capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId()); - Set capacityResponses = new HashSet(); - float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); - - for (SummedCapacity capacity : capacities) { - CapacityResponse capacityResponse = new CapacityResponse(); - capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); - - if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { - capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); - } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { - List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId()); - capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); - } else { - capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); - } - if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); - } else { - capacityResponse.setPercentUsed(s_percentFormat.format(0L)); - } - capacityResponses.add(capacityResponse); - } - // Do it for stats as well. - capacityResponses.addAll(getStatsCapacityresponse(null, cluster.getId(), pod.getId(), pod.getDataCenterId())); - clusterResponse.setCapacitites(new ArrayList(capacityResponses)); - } - clusterResponse.setObjectName("cluster"); - return clusterResponse; - } - - @Override - public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule) { - FirewallRuleResponse response = new FirewallRuleResponse(); - response.setId(fwRule.getId()); - response.setPrivateStartPort(Integer.toString(fwRule.getDestinationPortStart())); - response.setPrivateEndPort(Integer.toString(fwRule.getDestinationPortEnd())); - response.setProtocol(fwRule.getProtocol()); - response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart())); - response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd())); - List cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId()); - response.setCidrList(StringUtils.join(cidrs, ",")); - - IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); - response.setPublicIpAddressId(ip.getId()); - response.setPublicIpAddress(ip.getAddress().addr()); - - if (ip != null && fwRule.getDestinationIpAddress() != null) { - UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId()); - if (vm != null) { - response.setVirtualMachineId(vm.getId()); - response.setVirtualMachineName(vm.getHostName()); - - if (vm.getDisplayName() != null) { - response.setVirtualMachineDisplayName(vm.getDisplayName()); - } else { - response.setVirtualMachineDisplayName(vm.getHostName()); - } - } - } - FirewallRule.State state = fwRule.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setState(stateToSet); - response.setObjectName("portforwardingrule"); - return response; - } - - @Override - public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule) { - IpForwardingRuleResponse response = new IpForwardingRuleResponse(); - response.setId(fwRule.getId()); - response.setProtocol(fwRule.getProtocol()); - - IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); - response.setPublicIpAddressId(ip.getId()); - response.setPublicIpAddress(ip.getAddress().addr()); - - if (ip != null && fwRule.getDestIpAddress() != null) { - UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId()); - if (vm != null) {// vm might be destroyed - response.setVirtualMachineId(vm.getId()); - response.setVirtualMachineName(vm.getHostName()); - if (vm.getDisplayName() != null) { - response.setVirtualMachineDisplayName(vm.getDisplayName()); - } else { - response.setVirtualMachineDisplayName(vm.getHostName()); - } - } - } - FirewallRule.State state = fwRule.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - - response.setStartPort(fwRule.getSourcePortStart()); - response.setEndPort(fwRule.getSourcePortEnd()); - response.setProtocol(fwRule.getProtocol()); - response.setState(stateToSet); - response.setObjectName("ipforwardingrule"); - return response; - } - - @Override - public List createUserVmResponse(String objectName, EnumSet details, UserVm... userVms) { - Account caller = UserContext.current().getCaller(); - Map dataCenters = new HashMap(); - Map hosts = new HashMap(); - Map templates = new HashMap(); - Map serviceOfferings = new HashMap(); - Map networks = new HashMap(); - - List vmResponses = new ArrayList(); - - for (UserVm userVm : userVms) { - UserVmResponse userVmResponse = new UserVmResponse(); - Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId())); - if (acct != null) { - userVmResponse.setAccountName(acct.getAccountName()); - userVmResponse.setDomainId(acct.getDomainId()); - userVmResponse.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName()); - } - - userVmResponse.setId(userVm.getId()); - userVmResponse.setName(userVm.getHostName()); - userVmResponse.setCreated(userVm.getCreated()); - - userVmResponse.setHaEnable(userVm.isHaEnabled()); - - if (userVm.getDisplayName() != null) { - userVmResponse.setDisplayName(userVm.getDisplayName()); - } else { - userVmResponse.setDisplayName(userVm.getHostName()); - } - - if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { - userVmResponse.setInstanceName(userVm.getInstanceName()); - } - - - if (userVm.getPassword() != null) { - userVmResponse.setPassword(userVm.getPassword()); - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.group)) { - InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId()); - if (group != null) { - userVmResponse.setGroup(group.getName()); - userVmResponse.setGroupId(group.getId()); - } - - } - - // Data Center Info - DataCenter zone = dataCenters.get(userVm.getDataCenterIdToDeployIn()); - if (zone == null) { - zone = ApiDBUtils.findZoneById(userVm.getDataCenterIdToDeployIn()); - dataCenters.put(zone.getId(), zone); - } - - userVmResponse.setZoneId(zone.getId()); - userVmResponse.setZoneName(zone.getName()); - - // if user is an admin, display host id - if (((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)) && (userVm.getHostId() != null)) { - Host host = hosts.get(userVm.getHostId()); - - if (host == null) { - host = ApiDBUtils.findHostById(userVm.getHostId()); - hosts.put(host.getId(), host); - } - - userVmResponse.setHostId(host.getId()); - userVmResponse.setHostName(host.getName()); - } - - if (userVm.getState() != null) { - if (userVm.getHostId() != null) { - Host host = hosts.get(userVm.getHostId()); - - if (host == null) { - host = ApiDBUtils.findHostById(userVm.getHostId()); - hosts.put(host.getId(), host); - } - if (host.getStatus() != com.cloud.host.Status.Up) { - userVmResponse.setState(VirtualMachine.State.Unknown.toString()); - } else { - userVmResponse.setState(userVm.getState().toString()); - } - } else { - userVmResponse.setState(userVm.getState().toString()); - } - } - - 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()); - if (template == null) { - template = ApiDBUtils.findTemplateById(userVm.getTemplateId()); - if (template != null) { - templates.put(template.getId(), template); - } - } - - if (template != null) { - userVmResponse.setTemplateId(userVm.getTemplateId()); - userVmResponse.setTemplateName(template.getName()); - userVmResponse.setTemplateDisplayText(template.getDisplayText()); - userVmResponse.setPasswordEnabled(template.getEnablePassword()); - } else { - userVmResponse.setTemplateId(-1L); - userVmResponse.setTemplateName("ISO Boot"); - userVmResponse.setTemplateDisplayText("ISO Boot"); - userVmResponse.setPasswordEnabled(false); - } - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.iso)) { - // ISO Info - VMTemplateVO iso = templates.get(userVm.getIsoId()); - if (iso == null) { - iso = ApiDBUtils.findTemplateById(userVm.getIsoId()); - if (iso != null) { - templates.put(iso.getId(), iso); - } - } - - if (iso != null) { - userVmResponse.setIsoId(iso.getId()); - userVmResponse.setIsoName(iso.getName()); - } - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) { - // Service Offering Info - ServiceOffering offering = serviceOfferings.get(userVm.getServiceOfferingId()); - - if (offering == null) { - offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId()); - serviceOfferings.put(offering.getId(), offering); - } - - userVmResponse.setServiceOfferingId(offering.getId()); - userVmResponse.setServiceOfferingName(offering.getName()); - userVmResponse.setCpuNumber(offering.getCpu()); - userVmResponse.setCpuSpeed(offering.getSpeed()); - userVmResponse.setMemory(offering.getRamSize()); - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.volume)) { - VolumeVO rootVolume = ApiDBUtils.findRootVolume(userVm.getId()); - if (rootVolume != null) { - userVmResponse.setRootDeviceId(rootVolume.getDeviceId()); - String rootDeviceType = "Not created"; - if (rootVolume.getPoolId() != null) { - StoragePoolVO storagePool = ApiDBUtils.findStoragePoolById(rootVolume.getPoolId()); - rootDeviceType = storagePool.getPoolType().toString(); - } - userVmResponse.setRootDeviceType(rootDeviceType); - } - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.stats)) { - // stats calculation - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - String cpuUsed = null; - VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId()); - if (vmStats != null) { - float cpuUtil = (float) vmStats.getCPUUtilization(); - cpuUsed = decimalFormat.format(cpuUtil) + "%"; - userVmResponse.setCpuUsed(cpuUsed); - - Double networkKbRead = Double.valueOf(vmStats.getNetworkReadKBs()); - userVmResponse.setNetworkKbsRead(networkKbRead.longValue()); - - Double networkKbWrite = Double.valueOf(vmStats.getNetworkWriteKBs()); - userVmResponse.setNetworkKbsWrite(networkKbWrite.longValue()); - } - } - - userVmResponse.setGuestOsId(userVm.getGuestOSId()); - - if (details.contains(VMDetails.all) || details.contains(VMDetails.secgrp)) { - // security groups - list only when zone is security group enabled - if (zone.isSecurityGroupEnabled()) { - List securityGroups = ApiDBUtils.getSecurityGroupsForVm(userVm.getId()); - List securityGroupResponse = new ArrayList(); - for (SecurityGroupVO grp : securityGroups) { - SecurityGroupResponse resp = new SecurityGroupResponse(); - resp.setId(grp.getId()); - resp.setName(grp.getName()); - resp.setDescription(grp.getDescription()); - resp.setObjectName("securitygroup"); - securityGroupResponse.add(resp); - } - userVmResponse.setSecurityGroupList(securityGroupResponse); - } - } - - if (details.contains(VMDetails.all) || details.contains(VMDetails.nics)) { - List nicProfiles = ApiDBUtils.getNics(userVm); - List nicResponses = new ArrayList(); - for (NicProfile singleNicProfile : nicProfiles) { - NicResponse nicResponse = new NicResponse(); - nicResponse.setId(singleNicProfile.getId()); - nicResponse.setIpaddress(singleNicProfile.getIp4Address()); - nicResponse.setGateway(singleNicProfile.getGateway()); - nicResponse.setNetmask(singleNicProfile.getNetmask()); - nicResponse.setNetworkid(singleNicProfile.getNetworkId()); - if (acct.getType() == Account.ACCOUNT_TYPE_ADMIN) { - if (singleNicProfile.getBroadCastUri() != null) { - nicResponse.setBroadcastUri(singleNicProfile.getBroadCastUri().toString()); - } - if (singleNicProfile.getIsolationUri() != null) { - nicResponse.setIsolationUri(singleNicProfile.getIsolationUri().toString()); - } - } - - // Long networkId = singleNicProfile.getNetworkId(); - Network network = networks.get(singleNicProfile.getNetworkId()); - if (network == null) { - network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); - networks.put(singleNicProfile.getNetworkId(), network); - } - - nicResponse.setTrafficType(network.getTrafficType().toString()); - nicResponse.setType(network.getGuestType().toString()); - nicResponse.setIsDefault(singleNicProfile.isDefaultNic()); - nicResponse.setObjectName("nic"); - nicResponses.add(nicResponse); - } - userVmResponse.setNics(nicResponses); - } - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVm.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - userVmResponse.setTags(tagResponses); - - IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(userVm.getId()); - if (ip != null) { - userVmResponse.setPublicIpId(ip.getId()); - userVmResponse.setPublicIp(ip.getAddress().addr()); - } - - userVmResponse.setObjectName(objectName); - vmResponses.add(userVmResponse); - } - - return vmResponses; - } - - @Override - public List createUserVmResponse(String objectName, UserVm... userVms) { - Account caller = UserContext.current().getCaller(); - boolean caller_is_admin = ((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)); - - Hashtable vmDataList = new Hashtable(); - // Initialise the vmdatalist with the input data - for (UserVm userVm : userVms) { - UserVmData userVmData = newUserVmData(userVm); - vmDataList.put(userVm.getId(), userVmData); - } - - vmDataList = ApiDBUtils.listVmDetails(vmDataList); - - // initialize vmresponse from vmdatalist - List vmResponses = new ArrayList(); - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - for (UserVmData uvd : vmDataList.values()) { - UserVmResponse userVmResponse = newUserVmResponse(uvd, caller_is_admin); - - // stats calculation - String cpuUsed = null; - // VmStats vmStats = ApiDBUtils.getVmStatistics(userVmResponse.getId()); - VmStats vmStats = ApiDBUtils.getVmStatistics(uvd.getId()); - if (vmStats != null) { - float cpuUtil = (float) vmStats.getCPUUtilization(); - cpuUsed = decimalFormat.format(cpuUtil) + "%"; - userVmResponse.setCpuUsed(cpuUsed); - - Double networkKbRead = Double.valueOf(vmStats.getNetworkReadKBs()); - userVmResponse.setNetworkKbsRead(networkKbRead.longValue()); - - Double networkKbWrite = Double.valueOf(vmStats.getNetworkWriteKBs()); - userVmResponse.setNetworkKbsWrite(networkKbWrite.longValue()); - } - userVmResponse.setObjectName(objectName); - - vmResponses.add(userVmResponse); - } - return vmResponses; - } - - @Override - public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) { - Account caller = UserContext.current().getCaller(); - Map serviceOfferings = new HashMap(); - - DomainRouterResponse routerResponse = new DomainRouterResponse(); - routerResponse.setId(router.getId()); - routerResponse.setZoneId(router.getDataCenterIdToDeployIn()); - routerResponse.setName(router.getHostName()); - routerResponse.setTemplateId(router.getTemplateId()); - routerResponse.setCreated(router.getCreated()); - routerResponse.setState(router.getState()); - routerResponse.setIsRedundantRouter(router.getIsRedundantRouter()); - routerResponse.setRedundantState(router.getRedundantState().toString()); - - if (caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { - if (router.getHostId() != null) { - routerResponse.setHostId(router.getHostId()); - routerResponse.setHostName(ApiDBUtils.findHostById(router.getHostId()).getName()); - } - routerResponse.setPodId(router.getPodIdToDeployIn()); - List nicProfiles = ApiDBUtils.getNics(router); - for (NicProfile singleNicProfile : nicProfiles) { - Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); - if (network != null) { - if (network.getTrafficType() == TrafficType.Public) { - routerResponse.setPublicIp(singleNicProfile.getIp4Address()); - routerResponse.setPublicMacAddress(singleNicProfile.getMacAddress()); - routerResponse.setPublicNetmask(singleNicProfile.getNetmask()); - routerResponse.setGateway(singleNicProfile.getGateway()); - routerResponse.setPublicNetworkId(singleNicProfile.getNetworkId()); - } else if (network.getTrafficType() == TrafficType.Control) { - routerResponse.setLinkLocalIp(singleNicProfile.getIp4Address()); - routerResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress()); - routerResponse.setLinkLocalNetmask(singleNicProfile.getNetmask()); - routerResponse.setLinkLocalNetworkId(singleNicProfile.getNetworkId()); - } else if (network.getTrafficType() == TrafficType.Guest) { - routerResponse.setGuestIpAddress(singleNicProfile.getIp4Address()); - routerResponse.setGuestMacAddress(singleNicProfile.getMacAddress()); - routerResponse.setGuestNetmask(singleNicProfile.getNetmask()); - routerResponse.setGuestNetworkId(singleNicProfile.getNetworkId()); - routerResponse.setNetworkDomain(network.getNetworkDomain()); - } - } - } - } - - // Service Offering Info - ServiceOffering offering = serviceOfferings.get(router.getServiceOfferingId()); - - if (offering == null) { - offering = ApiDBUtils.findServiceOfferingById(router.getServiceOfferingId()); - serviceOfferings.put(offering.getId(), offering); - } - routerResponse.setServiceOfferingId(offering.getId()); - routerResponse.setServiceOfferingName(offering.getName()); - - populateOwner(routerResponse, router); - - DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterIdToDeployIn()); - if (zone != null) { - routerResponse.setZoneName(zone.getName()); - routerResponse.setDns1(zone.getDns1()); - routerResponse.setDns2(zone.getDns2()); - } - - routerResponse.setVpcId(router.getVpcId()); - - routerResponse.setObjectName("domainrouter"); - return routerResponse; - } - - @Override - public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { - SystemVmResponse vmResponse = new SystemVmResponse(); - if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy) { - // SystemVm vm = (SystemVm) systemVM; - vmResponse.setId(vm.getId()); - vmResponse.setObjectId(vm.getId()); - vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); - vmResponse.setZoneId(vm.getDataCenterIdToDeployIn()); - - vmResponse.setName(vm.getHostName()); - vmResponse.setPodId(vm.getPodIdToDeployIn()); - vmResponse.setTemplateId(vm.getTemplateId()); - vmResponse.setCreated(vm.getCreated()); - - if (vm.getHostId() != null) { - vmResponse.setHostId(vm.getHostId()); - vmResponse.setHostName(ApiDBUtils.findHostById(vm.getHostId()).getName()); - } - - if (vm.getState() != null) { - vmResponse.setState(vm.getState().toString()); - } - - // for console proxies, add the active sessions - if (vm.getType() == Type.ConsoleProxy) { - ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId()); - // proxy can be already destroyed - if (proxy != null) { - vmResponse.setActiveViewerSessions(proxy.getActiveSession()); - } - } - - DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterIdToDeployIn()); - if (zone != null) { - vmResponse.setZoneName(zone.getName()); - vmResponse.setDns1(zone.getDns1()); - vmResponse.setDns2(zone.getDns2()); - } - - List nicProfiles = ApiDBUtils.getNics(vm); - for (NicProfile singleNicProfile : nicProfiles) { - Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); - if (network != null) { - if (network.getTrafficType() == TrafficType.Management) { - vmResponse.setPrivateIp(singleNicProfile.getIp4Address()); - vmResponse.setPrivateMacAddress(singleNicProfile.getMacAddress()); - vmResponse.setPrivateNetmask(singleNicProfile.getNetmask()); - } else if (network.getTrafficType() == TrafficType.Control) { - vmResponse.setLinkLocalIp(singleNicProfile.getIp4Address()); - vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress()); - vmResponse.setLinkLocalNetmask(singleNicProfile.getNetmask()); - } else if (network.getTrafficType() == TrafficType.Public || network.getTrafficType() == TrafficType.Guest) { - /*In basic zone, public ip has TrafficType.Guest*/ - vmResponse.setPublicIp(singleNicProfile.getIp4Address()); - vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress()); - vmResponse.setPublicNetmask(singleNicProfile.getNetmask()); - vmResponse.setGateway(singleNicProfile.getGateway()); - } - } - } - } - vmResponse.setObjectName("systemvm"); - return vmResponse; - } - - @Override - public Host findHostById(Long hostId) { - return ApiDBUtils.findHostById(hostId); - } - - @Override - public User findUserById(Long userId) { - return ApiDBUtils.findUserById(userId); - } - - @Override - public UserVm findUserVmById(Long vmId) { - return ApiDBUtils.findUserVmById(vmId); - - } - - @Override - public VolumeVO findVolumeById(Long volumeId) { - return ApiDBUtils.findVolumeById(volumeId); - } - - @Override - public Account findAccountByNameDomain(String accountName, Long domainId) { - return ApiDBUtils.findAccountByNameDomain(accountName, domainId); - } - - @Override - public VirtualMachineTemplate findTemplateById(Long templateId) { - return ApiDBUtils.findTemplateById(templateId); - } - - @Override - public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) { - VpnUsersResponse vpnResponse = new VpnUsersResponse(); - vpnResponse.setId(vpnUser.getId()); - vpnResponse.setUserName(vpnUser.getUsername()); - - populateOwner(vpnResponse, vpnUser); - - vpnResponse.setObjectName("vpnuser"); - return vpnResponse; - } - - @Override - public RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn) { - RemoteAccessVpnResponse vpnResponse = new RemoteAccessVpnResponse(); - vpnResponse.setPublicIpId(vpn.getServerAddressId()); - vpnResponse.setPublicIp(ApiDBUtils.findIpAddressById(vpn.getServerAddressId()).getAddress().addr()); - vpnResponse.setIpRange(vpn.getIpRange()); - vpnResponse.setPresharedKey(vpn.getIpsecPresharedKey()); - vpnResponse.setDomainId(vpn.getDomainId()); - - populateOwner(vpnResponse, vpn); - - vpnResponse.setState(vpn.getState().toString()); - vpnResponse.setObjectName("remoteaccessvpn"); - - return vpnResponse; - } - - @Override - public TemplateResponse createIsoResponse(VirtualMachineTemplate result) { - TemplateResponse response = new TemplateResponse(); - response.setId(result.getId()); - response.setName(result.getName()); - response.setDisplayText(result.getDisplayText()); - response.setPublic(result.isPublicTemplate()); - response.setCreated(result.getCreated()); - response.setFormat(result.getFormat()); - response.setOsTypeId(result.getGuestOSId()); - response.setOsTypeName(ApiDBUtils.findGuestOSById(result.getGuestOSId()).getDisplayName()); - response.setDetails(result.getDetails()); - Account caller = UserContext.current().getCaller(); - - if (result.getFormat() == ImageFormat.ISO) { // Templates are always bootable - response.setBootable(result.isBootable()); - } else { - response.setHypervisor(result.getHypervisorType().toString());// hypervisors are associated with templates - } - - // add account ID and name - Account owner = ApiDBUtils.findAccountById(result.getAccountId()); - populateAccount(response, owner.getId()); - populateDomain(response, owner.getDomainId()); - - //set tag information - List tags = null; - if (result.getFormat() == ImageFormat.ISO) { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, result.getId()); - } else { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, result.getId()); - } - - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("iso"); - return response; - } - - @Override - public List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly) { - if (zoneId == null || zoneId == -1) { - List responses = new ArrayList(); - List dcs = new ArrayList(); - responses = createSwiftTemplateResponses(templateId); - if (!responses.isEmpty()) { - return responses; - } - dcs.addAll(ApiDBUtils.listZones()); - for (DataCenterVO dc : dcs) { - responses.addAll(createTemplateResponses(templateId, dc.getId(), readyOnly)); - } - return responses; - } else { - return createTemplateResponses(templateId, zoneId.longValue(), readyOnly); - } - } - - private List createSwiftTemplateResponses(long templateId) { - VirtualMachineTemplate template = findTemplateById(templateId); - List responses = new ArrayList(); - VMTemplateSwiftVO templateSwiftRef = ApiDBUtils.findTemplateSwiftRef(templateId); - if (templateSwiftRef == null) { - return responses; - } - - TemplateResponse templateResponse = new TemplateResponse(); - templateResponse.setId(template.getId()); - templateResponse.setName(template.getName()); - templateResponse.setDisplayText(template.getDisplayText()); - templateResponse.setPublic(template.isPublicTemplate()); - templateResponse.setCreated(templateSwiftRef.getCreated()); - - templateResponse.setReady(true); - templateResponse.setFeatured(template.isFeatured()); - templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); - templateResponse.setPasswordEnabled(template.getEnablePassword()); - templateResponse.setCrossZones(template.isCrossZones()); - templateResponse.setFormat(template.getFormat()); - templateResponse.setDetails(template.getDetails()); - if (template.getTemplateType() != null) { - templateResponse.setTemplateType(template.getTemplateType().toString()); - } - - templateResponse.setHypervisor(template.getHypervisorType().toString()); - - GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); - if (os != null) { - templateResponse.setOsTypeId(os.getId()); - templateResponse.setOsTypeName(os.getDisplayName()); - } else { - templateResponse.setOsTypeId(-1L); - templateResponse.setOsTypeName(""); - } - - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); - populateAccount(templateResponse, account.getId()); - populateDomain(templateResponse, account.getDomainId()); - - Account caller = UserContext.current().getCaller(); - boolean isAdmin = false; - if (BaseCmd.isAdmin(caller.getType())) { - isAdmin = true; - } - - // If the user is an Admin, add the template download status - if (isAdmin || caller.getId() == template.getAccountId()) { - // add download status - templateResponse.setStatus("Successfully Installed"); - } - - Long templateSize = templateSwiftRef.getSize(); - if (templateSize > 0) { - templateResponse.setSize(templateSize); - } - - templateResponse.setChecksum(template.getChecksum()); - templateResponse.setSourceTemplateId(template.getSourceTemplateId()); - - templateResponse.setChecksum(template.getChecksum()); - - templateResponse.setTemplateTag(template.getTemplateTag()); - - templateResponse.setObjectName("template"); - responses.add(templateResponse); - return responses; - } - - @Override - public List createTemplateResponses(long templateId, long zoneId, boolean readyOnly) { - VirtualMachineTemplate template = findTemplateById(templateId); - List responses = new ArrayList(); - VMTemplateHostVO templateHostRef = ApiDBUtils.findTemplateHostRef(templateId, zoneId, readyOnly); - if (templateHostRef == null) { - return responses; - } - - HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); - if (host.getType() == Host.Type.LocalSecondaryStorage && host.getStatus() != com.cloud.host.Status.Up) { - return responses; - } - - TemplateResponse templateResponse = new TemplateResponse(); - templateResponse.setId(template.getId()); - templateResponse.setName(template.getName()); - templateResponse.setDisplayText(template.getDisplayText()); - templateResponse.setPublic(template.isPublicTemplate()); - templateResponse.setCreated(templateHostRef.getCreated()); - - templateResponse.setReady(templateHostRef.getDownloadState() == Status.DOWNLOADED); - templateResponse.setFeatured(template.isFeatured()); - templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); - templateResponse.setPasswordEnabled(template.getEnablePassword()); - templateResponse.setCrossZones(template.isCrossZones()); - templateResponse.setFormat(template.getFormat()); - if (template.getTemplateType() != null) { - templateResponse.setTemplateType(template.getTemplateType().toString()); - } - - templateResponse.setHypervisor(template.getHypervisorType().toString()); - templateResponse.setDetails(template.getDetails()); - - GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); - if (os != null) { - templateResponse.setOsTypeId(os.getId()); - templateResponse.setOsTypeName(os.getDisplayName()); - } else { - templateResponse.setOsTypeId(-1L); - templateResponse.setOsTypeName(""); - } - - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); - populateAccount(templateResponse, account.getId()); - populateDomain(templateResponse, account.getDomainId()); - - DataCenterVO datacenter = ApiDBUtils.findZoneById(zoneId); - - // Add the zone ID - templateResponse.setZoneId(zoneId); - templateResponse.setZoneName(datacenter.getName()); - - boolean isAdmin = false; - Account caller = UserContext.current().getCaller(); - if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { - isAdmin = true; - } - - // If the user is an Admin, add the template download status - if (isAdmin || caller.getId() == template.getAccountId()) { - // add download status - if (templateHostRef.getDownloadState() != Status.DOWNLOADED) { - String templateStatus = "Processing"; - if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { - if (templateHostRef.getDownloadPercent() == 100) { - templateStatus = "Installing Template"; - } else { - templateStatus = templateHostRef.getDownloadPercent() + "% Downloaded"; - } - } else { - templateStatus = templateHostRef.getErrorString(); - } - templateResponse.setStatus(templateStatus); - } else if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { - templateResponse.setStatus("Download Complete"); - } else { - templateResponse.setStatus("Successfully Installed"); - } - } - - Long templateSize = templateHostRef.getSize(); - if (templateSize > 0) { - templateResponse.setSize(templateSize); - } - - templateResponse.setChecksum(template.getChecksum()); - templateResponse.setSourceTemplateId(template.getSourceTemplateId()); - - templateResponse.setChecksum(template.getChecksum()); - - templateResponse.setTemplateTag(template.getTemplateTag()); - - //set tag information - List tags = null; - if (template.getFormat() == ImageFormat.ISO) { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, template.getId()); - } else { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, template.getId()); - } - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - templateResponse.setTags(tagResponses); - - templateResponse.setObjectName("template"); - responses.add(templateResponse); - return responses; - } - - @Override - public List createIsoResponses(long isoId, Long zoneId, boolean readyOnly) { - - List isoResponses = new ArrayList(); - VirtualMachineTemplate iso = findTemplateById(isoId); - if (iso.getTemplateType() == TemplateType.PERHOST) { - TemplateResponse isoResponse = new TemplateResponse(); - isoResponse.setId(iso.getId()); - isoResponse.setName(iso.getName()); - isoResponse.setDisplayText(iso.getDisplayText()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); - isoResponse.setReady(true); - isoResponse.setBootable(iso.isBootable()); - isoResponse.setFeatured(iso.isFeatured()); - isoResponse.setCrossZones(iso.isCrossZones()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setCreated(iso.getCreated()); - isoResponse.setChecksum(iso.getChecksum()); - isoResponse.setPasswordEnabled(false); - isoResponse.setDetails(iso.getDetails()); - - // add account ID and name - Account owner = ApiDBUtils.findAccountById(iso.getAccountId()); - populateAccount(isoResponse, owner.getId()); - populateDomain(isoResponse, owner.getDomainId()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - isoResponse.setTags(tagResponses); - - isoResponse.setObjectName("iso"); - isoResponses.add(isoResponse); - return isoResponses; - } else { - if (zoneId == null || zoneId == -1) { - isoResponses = createSwiftIsoResponses(iso); - if (!isoResponses.isEmpty()) { - return isoResponses; - } - List dcs = new ArrayList(); - dcs.addAll(ApiDBUtils.listZones()); - for (DataCenterVO dc : dcs) { - isoResponses.addAll(createIsoResponses(iso, dc.getId(), readyOnly)); - } - return isoResponses; - } else { - return createIsoResponses(iso, zoneId, readyOnly); - } - } - } - - private List createSwiftIsoResponses(VirtualMachineTemplate iso) { - long isoId = iso.getId(); - List isoResponses = new ArrayList(); - VMTemplateSwiftVO isoSwift = ApiDBUtils.findTemplateSwiftRef(isoId); - if (isoSwift == null) { - return isoResponses; - } - TemplateResponse isoResponse = new TemplateResponse(); - isoResponse.setId(iso.getId()); - isoResponse.setName(iso.getName()); - isoResponse.setDisplayText(iso.getDisplayText()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); - isoResponse.setCreated(isoSwift.getCreated()); - isoResponse.setReady(true); - isoResponse.setBootable(iso.isBootable()); - isoResponse.setFeatured(iso.isFeatured()); - isoResponse.setCrossZones(iso.isCrossZones()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setChecksum(iso.getChecksum()); - isoResponse.setDetails(iso.getDetails()); - - // TODO: implement - GuestOS os = ApiDBUtils.findGuestOSById(iso.getGuestOSId()); - if (os != null) { - isoResponse.setOsTypeId(os.getId()); - isoResponse.setOsTypeName(os.getDisplayName()); - } else { - isoResponse.setOsTypeId(-1L); - isoResponse.setOsTypeName(""); - } - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId()); - populateAccount(isoResponse, account.getId()); - populateDomain(isoResponse, account.getDomainId()); - boolean isAdmin = false; - if ((account == null) || BaseCmd.isAdmin(account.getType())) { - isAdmin = true; - } - - // If the user is an admin, add the template download status - if (isAdmin || account.getId() == iso.getAccountId()) { - // add download status - isoResponse.setStatus("Successfully Installed"); - } - Long isoSize = isoSwift.getSize(); - if (isoSize > 0) { - isoResponse.setSize(isoSize); - } - isoResponse.setObjectName("iso"); - isoResponses.add(isoResponse); - return isoResponses; - } - - @Override - public List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly) { - long isoId = iso.getId(); - List isoResponses = new ArrayList(); - VMTemplateHostVO isoHost = ApiDBUtils.findTemplateHostRef(isoId, zoneId, readyOnly); - if (isoHost == null) { - return isoResponses; - } - TemplateResponse isoResponse = new TemplateResponse(); - isoResponse.setId(iso.getId()); - isoResponse.setName(iso.getName()); - isoResponse.setDisplayText(iso.getDisplayText()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); - isoResponse.setCreated(isoHost.getCreated()); - isoResponse.setReady(isoHost.getDownloadState() == Status.DOWNLOADED); - isoResponse.setBootable(iso.isBootable()); - isoResponse.setFeatured(iso.isFeatured()); - isoResponse.setCrossZones(iso.isCrossZones()); - isoResponse.setPublic(iso.isPublicTemplate()); - isoResponse.setChecksum(iso.getChecksum()); - isoResponse.setDetails(iso.getDetails()); - - // TODO: implement - GuestOS os = ApiDBUtils.findGuestOSById(iso.getGuestOSId()); - if (os != null) { - isoResponse.setOsTypeId(os.getId()); - isoResponse.setOsTypeName(os.getDisplayName()); - } else { - isoResponse.setOsTypeId(-1L); - isoResponse.setOsTypeName(""); - } - - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId()); - populateAccount(isoResponse, account.getId()); - populateDomain(isoResponse, account.getDomainId()); - - Account caller = UserContext.current().getCaller(); - boolean isAdmin = false; - if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { - isAdmin = true; - } - // Add the zone ID - DataCenterVO datacenter = ApiDBUtils.findZoneById(zoneId); - isoResponse.setZoneId(zoneId); - isoResponse.setZoneName(datacenter.getName()); - - // If the user is an admin, add the template download status - if (isAdmin || caller.getId() == iso.getAccountId()) { - // add download status - if (isoHost.getDownloadState() != Status.DOWNLOADED) { - String isoStatus = "Processing"; - if (isoHost.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { - isoStatus = "Download Complete"; - } else if (isoHost.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { - if (isoHost.getDownloadPercent() == 100) { - isoStatus = "Installing ISO"; - } else { - isoStatus = isoHost.getDownloadPercent() + "% Downloaded"; - } - } else { - isoStatus = isoHost.getErrorString(); - } - isoResponse.setStatus(isoStatus); - } else { - isoResponse.setStatus("Successfully Installed"); - } - } - - Long isoSize = isoHost.getSize(); - if (isoSize > 0) { - isoResponse.setSize(isoSize); - } - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); - - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - isoResponse.setTags(tagResponses); - - isoResponse.setObjectName("iso"); - isoResponses.add(isoResponse); - return isoResponses; - } - - @Override - public ListResponse createSecurityGroupResponses( - List networkGroups) { - List groupResultObjs = SecurityGroupResultObject - .transposeNetworkGroups(networkGroups); - - ListResponse response = new ListResponse(); - List netGrpResponses = new ArrayList(); - for (SecurityGroupResultObject networkGroup : groupResultObjs) { - SecurityGroupResponse netGrpResponse = new SecurityGroupResponse(); - netGrpResponse.setId(networkGroup.getId()); - netGrpResponse.setName(networkGroup.getName()); - netGrpResponse.setDescription(networkGroup.getDescription()); - - populateOwner(netGrpResponse, networkGroup); - - List securityGroupRules = networkGroup - .getSecurityGroupRules(); - if ((securityGroupRules != null) && !securityGroupRules.isEmpty()) { - List ingressRulesResponse = new ArrayList(); - List egressRulesResponse = new ArrayList(); - for (SecurityGroupRuleResultObject securityGroupRule : securityGroupRules) { - SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); - ruleData.setRuleId(securityGroupRule.getId()); - ruleData.setProtocol(securityGroupRule.getProtocol()); - - if ("icmp".equalsIgnoreCase(securityGroupRule.getProtocol())) { - ruleData.setIcmpType(securityGroupRule.getStartPort()); - ruleData.setIcmpCode(securityGroupRule.getEndPort()); - } else { - ruleData.setStartPort(securityGroupRule.getStartPort()); - ruleData.setEndPort(securityGroupRule.getEndPort()); - } - - if (securityGroupRule.getAllowedSecurityGroup() != null) { - ruleData.setSecurityGroupName(securityGroupRule - .getAllowedSecurityGroup()); - ruleData.setAccountName(securityGroupRule - .getAllowedSecGroupAcct()); - } else { - ruleData.setCidr(securityGroupRule - .getAllowedSourceIpCidr()); - } - - if (securityGroupRule.getRuleType() == SecurityRuleType.IngressRule) { - ruleData.setObjectName("ingressrule"); - ingressRulesResponse.add(ruleData); - } else { - ruleData.setObjectName("egressrule"); - egressRulesResponse.add(ruleData); - } - } - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, networkGroup.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - netGrpResponse.setTags(tagResponses); - - netGrpResponse - .setSecurityGroupIngressRules(ingressRulesResponse); - netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); - } - netGrpResponse.setObjectName("securitygroup"); - netGrpResponses.add(netGrpResponse); - } - - response.setResponses(netGrpResponses); - return response; - } - - @Override - public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) { - SecurityGroupResponse response = new SecurityGroupResponse(); - - populateOwner(response, group); - - response.setDescription(group.getDescription()); - response.setId(group.getId()); - response.setName(group.getName()); - - response.setObjectName("securitygroup"); - return response; - - } - - @Override - public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode) { - UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId); - ExtractResponse response = new ExtractResponse(); - response.setObjectName("template"); - response.setId(id); - response.setName(ApiDBUtils.findTemplateById(id).getName()); - if (zoneId != null) { - response.setZoneId(zoneId); - response.setZoneName(ApiDBUtils.findZoneById(zoneId).getName()); - } - response.setMode(mode); - response.setUploadId(uploadId); - response.setState(uploadInfo.getUploadState().toString()); - response.setAccountId(accountId); - response.setUrl(uploadInfo.getUploadUrl()); - return response; - - } - - @Override - public String toSerializedString(CreateCmdResponse response, String responseType) { - return ApiResponseSerializer.toSerializedString(response, responseType); - } - - @Override - public AsyncJobResponse createAsyncJobResponse(AsyncJob job) { - AsyncJobResponse jobResponse = new AsyncJobResponse(); - jobResponse.setAccountId(job.getAccountId()); - jobResponse.setUserId(job.getUserId()); - jobResponse.setCmd(job.getCmd()); - jobResponse.setCreated(job.getCreated()); - jobResponse.setJobId(job.getId()); - jobResponse.setJobStatus(job.getStatus()); - jobResponse.setJobProcStatus(job.getProcessStatus()); - - if (job.getInstanceType() != null && job.getInstanceId() != null) { - jobResponse.setJobInstanceType(job.getInstanceType().toString()); - jobResponse.setJobInstanceId(job.getInstanceId()); - } - jobResponse.setJobResultCode(job.getResultCode()); - - boolean savedValue = SerializationContext.current().getUuidTranslation(); - SerializationContext.current().setUuidTranslation(false); - - 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) { - jobResponse.setJobResultType("text"); - } else { - jobResponse.setJobResultType("object"); - } - } - - jobResponse.setObjectName("asyncjobs"); - return jobResponse; - } - - @Override - public List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly) { - VolumeVO volume = null; - if (snapshotId != null) { - Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId); - volume = findVolumeById(snapshot.getVolumeId()); - } else { - volume = findVolumeById(volumeId); - } - return createTemplateResponses(templateId, volume.getDataCenterId(), readyOnly); - } - - @Override - public List createTemplateResponses(long templateId, Long vmId) { - UserVm vm = findUserVmById(vmId); - Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()); - Host host = findHostById(hostId); - return createTemplateResponses(templateId, host.getDataCenterId(), true); - } - - @Override - public EventResponse createEventResponse(Event event) { - EventResponse responseEvent = new EventResponse(); - responseEvent.setCreated(event.getCreateDate()); - responseEvent.setDescription(event.getDescription()); - responseEvent.setEventType(event.getType()); - responseEvent.setId(event.getId()); - responseEvent.setLevel(event.getLevel()); - responseEvent.setParentId(event.getStartId()); - responseEvent.setState(event.getState()); - - populateOwner(responseEvent, event); - - User user = ApiDBUtils.findUserById(event.getUserId()); - if (user != null) { - responseEvent.setUsername(user.getUsername()); - } - - responseEvent.setObjectName("event"); - return responseEvent; - } - - private List sumCapacities(List hostCapacities) { - Map totalCapacityMap = new HashMap(); - Map usedCapacityMap = new HashMap(); - - Set poolIdsToIgnore = new HashSet(); - Criteria c = new Criteria(); - // TODO: implement - List allStoragePools = ApiDBUtils.searchForStoragePools(c); - for (StoragePoolVO pool : allStoragePools) { - StoragePoolType poolType = pool.getPoolType(); - if (!(poolType.isShared())) {// All the non shared storages shouldn't show up in the capacity calculation - poolIdsToIgnore.add(pool.getId()); - } - } - - float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); - - // collect all the capacity types, sum allocated/used and sum total...get one capacity number for each - for (Capacity capacity : hostCapacities) { - - // check if zone exist - DataCenter zone = ApiDBUtils.findZoneById(capacity.getDataCenterId()); - if (zone == null) { - continue; - } - - short capacityType = capacity.getCapacityType(); - - // If local storage then ignore - if ((capacityType == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED || capacityType == Capacity.CAPACITY_TYPE_STORAGE) - && poolIdsToIgnore.contains(capacity.getHostOrPoolId())) { - continue; - } - - String key = capacity.getCapacityType() + "_" + capacity.getDataCenterId(); - String keyForPodTotal = key + "_-1"; - - boolean sumPodCapacity = false; - if (capacity.getPodId() != null) { - key += "_" + capacity.getPodId(); - sumPodCapacity = true; - } - - Long totalCapacity = totalCapacityMap.get(key); - Long usedCapacity = usedCapacityMap.get(key); - - // reset overprovisioning factor to 1 - float overprovisioningFactor = 1; - if (capacityType == Capacity.CAPACITY_TYPE_CPU) { - overprovisioningFactor = cpuOverprovisioningFactor; - } - - if (totalCapacity == null) { - totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)); - } else { - totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)) + totalCapacity; - } - - if (usedCapacity == null) { - usedCapacity = new Long(capacity.getUsedCapacity()); - } else { - usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity); - } - - if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved - // Capacity - // accounts -// for - // stopped -// vms - // that -// have been - // stopped -// within - // an -// interval - usedCapacity += capacity.getReservedCapacity(); - } - - totalCapacityMap.put(key, totalCapacity); - usedCapacityMap.put(key, usedCapacity); - - if (sumPodCapacity) { - totalCapacity = totalCapacityMap.get(keyForPodTotal); - usedCapacity = usedCapacityMap.get(keyForPodTotal); - - overprovisioningFactor = 1; - if (capacityType == Capacity.CAPACITY_TYPE_CPU) { - overprovisioningFactor = cpuOverprovisioningFactor; - } - - if (totalCapacity == null) { - totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)); - } else { - totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)) + totalCapacity; - } - - if (usedCapacity == null) { - usedCapacity = new Long(capacity.getUsedCapacity()); - } else { - usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity); - } - - if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved - // Capacity - // accounts - // for - // stopped - // vms -// that - // have -// been - // stopped - // within -// an - // interval - usedCapacity += capacity.getReservedCapacity(); - } - - totalCapacityMap.put(keyForPodTotal, totalCapacity); - usedCapacityMap.put(keyForPodTotal, usedCapacity); - } - } - - List summedCapacities = new ArrayList(); - for (String key : totalCapacityMap.keySet()) { - CapacityVO summedCapacity = new CapacityVO(); - - StringTokenizer st = new StringTokenizer(key, "_"); - summedCapacity.setCapacityType(Short.parseShort(st.nextToken())); - summedCapacity.setDataCenterId(Long.parseLong(st.nextToken())); - if (st.hasMoreTokens()) { - summedCapacity.setPodId(Long.parseLong(st.nextToken())); - } - - summedCapacity.setTotalCapacity(totalCapacityMap.get(key)); - summedCapacity.setUsedCapacity(usedCapacityMap.get(key)); - - summedCapacities.add(summedCapacity); - } - return summedCapacities; - } - - @Override - public List createCapacityResponse(List result, DecimalFormat format) { - List capacityResponses = new ArrayList(); - - for (Capacity summedCapacity : result) { - CapacityResponse capacityResponse = new CapacityResponse(); - capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity()); - capacityResponse.setCapacityType(summedCapacity.getCapacityType()); - capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity()); - if (summedCapacity.getPodId() != null) { - capacityResponse.setPodId(summedCapacity.getPodId()); - HostPodVO pod = ApiDBUtils.findPodById(summedCapacity.getPodId()); - if (pod != null) { - capacityResponse.setPodName(pod.getName()); - } - } - if (summedCapacity.getClusterId() != null) { - capacityResponse.setClusterId(summedCapacity.getClusterId()); - ClusterVO cluster = ApiDBUtils.findClusterById(summedCapacity.getClusterId()); - if (cluster != null) { - capacityResponse.setClusterName(cluster.getName()); - if (summedCapacity.getPodId() == null) { - long podId = cluster.getPodId(); - capacityResponse.setPodId(podId); - capacityResponse.setPodName(ApiDBUtils.findPodById(podId).getName()); - } - } - } - capacityResponse.setZoneId(summedCapacity.getDataCenterId()); - capacityResponse.setZoneName(ApiDBUtils.findZoneById(summedCapacity.getDataCenterId()).getName()); - if (summedCapacity.getUsedPercentage() != null){ - capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f)); - } else if (summedCapacity.getTotalCapacity() != 0) { - capacityResponse.setPercentUsed(format.format((float) summedCapacity.getUsedCapacity() / (float) summedCapacity.getTotalCapacity() * 100f)); - } else { - capacityResponse.setPercentUsed(format.format(0L)); - } - - capacityResponse.setObjectName("capacity"); - capacityResponses.add(capacityResponse); - } - - return capacityResponses; - } - - @Override - public TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin) { - Long templateOwnerDomain = null; - VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id); - Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId()); - if (isAdmin) { - // FIXME: we have just template id and need to get template owner from that - if (templateOwner != null) { - templateOwnerDomain = templateOwner.getDomainId(); - } - } - - TemplatePermissionsResponse response = new TemplatePermissionsResponse(); - response.setId(template.getId()); - response.setPublicTemplate(template.isPublicTemplate()); - if (isAdmin && (templateOwnerDomain != null)) { - response.setDomainId(templateOwnerDomain); - } - - // Set accounts - List projectIds = new ArrayList(); - List regularAccounts = new ArrayList(); - for (String accountName : accountNames) { - Account account = ApiDBUtils.findAccountByNameDomain(accountName, templateOwner.getDomainId()); - if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) { - regularAccounts.add(accountName); - } else { - // convert account to projectIds - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); - - if (project.getUuid() != null && !project.getUuid().isEmpty()) - projectIds.add(project.getUuid()); - else - projectIds.add(String.valueOf(project.getId())); - } - } - - if (!projectIds.isEmpty()) { - response.setProjectIds(projectIds); - } - - if (!regularAccounts.isEmpty()) { - response.setAccountNames(regularAccounts); - } - - response.setObjectName("templatepermission"); - return response; - } - - @Override - public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) { - AsyncJob result = ApiDBUtils._asyncMgr.queryAsyncJobResult(cmd); - return createAsyncJobResponse(result); - } - - @Override - public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { - SecurityGroupResponse response = new SecurityGroupResponse(); - Map securiytGroupAccounts = new HashMap(); - Map allowedSecurityGroups = new HashMap(); - Map allowedSecuriytGroupAccounts = new HashMap(); - - if ((securityRules != null) && !securityRules.isEmpty()) { - SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(securityRules.get(0).getSecurityGroupId()); - response.setId(securityGroup.getId()); - response.setName(securityGroup.getName()); - response.setDescription(securityGroup.getDescription()); - - Account account = securiytGroupAccounts.get(securityGroup.getAccountId()); - - if (account == null) { - account = ApiDBUtils.findAccountById(securityGroup.getAccountId()); - securiytGroupAccounts.put(securityGroup.getAccountId(), account); - } - - populateAccount(response, account.getId()); - populateDomain(response, account.getDomainId()); - - List egressResponses = new ArrayList(); - List ingressResponses = new ArrayList(); - for (SecurityRule securityRule : securityRules) { - SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse(); - - securityGroupData.setRuleId(securityRule.getId()); - securityGroupData.setProtocol(securityRule.getProtocol()); - if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) { - securityGroupData.setIcmpType(securityRule.getStartPort()); - securityGroupData.setIcmpCode(securityRule.getEndPort()); - } else { - securityGroupData.setStartPort(securityRule.getStartPort()); - securityGroupData.setEndPort(securityRule.getEndPort()); - } - - Long allowedSecurityGroupId = securityRule.getAllowedNetworkId(); - if (allowedSecurityGroupId != null) { - SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); - if (allowedSecurityGroup == null) { - allowedSecurityGroup = ApiDBUtils.findSecurityGroupById(allowedSecurityGroupId); - allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); - } - - securityGroupData.setSecurityGroupName(allowedSecurityGroup.getName()); - - Account allowedAccount = allowedSecuriytGroupAccounts.get(allowedSecurityGroup.getAccountId()); - if (allowedAccount == null) { - allowedAccount = ApiDBUtils.findAccountById(allowedSecurityGroup.getAccountId()); - allowedSecuriytGroupAccounts.put(allowedAccount.getId(), allowedAccount); - } - - securityGroupData.setAccountName(allowedAccount.getAccountName()); - } else { - securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr()); - } - if (securityRule.getRuleType() == SecurityRuleType.IngressRule) { - securityGroupData.setObjectName("ingressrule"); - ingressResponses.add(securityGroupData); - } else { - securityGroupData.setObjectName("egressrule"); - egressResponses.add(securityGroupData); - } - - } - response.setSecurityGroupIngressRules(ingressResponses); - response.setSecurityGroupEgressRules(egressResponses); - response.setObjectName("securitygroup"); - - } - return response; - } - - @Override - public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) { - NetworkOfferingResponse response = new NetworkOfferingResponse(); - response.setId(offering.getId()); - response.setName(offering.getName()); - response.setDisplayText(offering.getDisplayText()); - response.setTags(offering.getTags()); - response.setTrafficType(offering.getTrafficType().toString()); - response.setIsDefault(offering.isDefault()); - response.setSpecifyVlan(offering.getSpecifyVlan()); - response.setConserveMode(offering.isConserveMode()); - response.setSpecifyIpRanges(offering.getSpecifyIpRanges()); - response.setAvailability(offering.getAvailability().toString()); - response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId())); - if (offering.getServiceOfferingId() != null) { - response.setServiceOfferingId(offering.getServiceOfferingId()); - } else { - response.setServiceOfferingId(ApiDBUtils.findDefaultRouterServiceOffering()); - } - if (offering.getGuestType() != null) { - response.setGuestIpType(offering.getGuestType().toString()); - } - - response.setState(offering.getState().name()); - - Map> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId()); - List serviceResponses = new ArrayList(); - for (Service service : serviceProviderMap.keySet()) { - ServiceResponse svcRsp = new ServiceResponse(); - // skip gateway service - if (service == Service.Gateway) { - continue; - } - svcRsp.setName(service.getName()); - List providers = new ArrayList(); - for (Provider provider : serviceProviderMap.get(service)) { - if (provider != null) { - ProviderResponse providerRsp = new ProviderResponse(); - providerRsp.setName(provider.getName()); - providers.add(providerRsp); - } - } - svcRsp.setProviders(providers); - - if (Service.Lb == service) { - List lbCapResponse = new ArrayList(); - - CapabilityResponse lbIsoaltion = new CapabilityResponse(); - lbIsoaltion.setName(Capability.SupportedLBIsolation.getName()); - lbIsoaltion.setValue(offering.getDedicatedLB() ? "dedicated" : "shared"); - lbCapResponse.add(lbIsoaltion); - - CapabilityResponse eLb = new CapabilityResponse(); - eLb.setName(Capability.ElasticLb.getName()); - eLb.setValue(offering.getElasticLb() ? "true" : "false"); - lbCapResponse.add(eLb); - - svcRsp.setCapabilities(lbCapResponse); - } else if (Service.SourceNat == service) { - List capabilities = new ArrayList(); - CapabilityResponse sharedSourceNat = new CapabilityResponse(); - sharedSourceNat.setName(Capability.SupportedSourceNatTypes.getName()); - sharedSourceNat.setValue(offering.getSharedSourceNat() ? "perzone" : "peraccount"); - capabilities.add(sharedSourceNat); - - CapabilityResponse redundantRouter = new CapabilityResponse(); - redundantRouter.setName(Capability.RedundantRouter.getName()); - redundantRouter.setValue(offering.getRedundantRouter() ? "true" : "false"); - capabilities.add(redundantRouter); - - svcRsp.setCapabilities(capabilities); - } else if (service == Service.StaticNat) { - List staticNatCapResponse = new ArrayList(); - - CapabilityResponse eIp = new CapabilityResponse(); - eIp.setName(Capability.ElasticIp.getName()); - eIp.setValue(offering.getElasticLb() ? "true" : "false"); - staticNatCapResponse.add(eIp); - - svcRsp.setCapabilities(staticNatCapResponse); - } - - serviceResponses.add(svcRsp); - } - response.setForVpc(ApiDBUtils.isOfferingForVpc(offering)); - - response.setServices(serviceResponses); - response.setObjectName("networkoffering"); - return response; - } - - @Override - public NetworkResponse createNetworkResponse(Network network) { - // need to get network profile in order to retrieve dns information from there - NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId()); - NetworkResponse response = new NetworkResponse(); - response.setId(network.getId()); - response.setName(network.getName()); - response.setDisplaytext(network.getDisplayText()); - if (network.getBroadcastDomainType() != null) { - response.setBroadcastDomainType(network.getBroadcastDomainType().toString()); - } - - if (network.getTrafficType() != null) { - response.setTrafficType(network.getTrafficType().name()); - } - - if (network.getGuestType() != null) { - response.setType(network.getGuestType().toString()); - } - - response.setGateway(network.getGateway()); - - // FIXME - either set netmask or cidr - response.setCidr(network.getCidr()); - if (network.getCidr() != null) { - response.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); - } - - if (network.getBroadcastUri() != null) { - String broadcastUri = network.getBroadcastUri().toString(); - response.setBroadcastUri(broadcastUri); - String vlan="N/A"; - if (broadcastUri.startsWith("vlan")) { - vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); - } - response.setVlan(vlan); - } - - DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId()); - response.setZoneId(network.getDataCenterId()); - response.setZoneName(zone.getName()); - response.setPhysicalNetworkId(network.getPhysicalNetworkId()); - - // populate network offering information - NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId()); - if (networkOffering != null) { - response.setNetworkOfferingId(networkOffering.getId()); - response.setNetworkOfferingName(networkOffering.getName()); - response.setNetworkOfferingDisplayText(networkOffering.getDisplayText()); - response.setIsSystem(networkOffering.isSystemOnly()); - response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString()); - } - - if (network.getAclType() != null) { - response.setAclType(network.getAclType().toString()); - } - response.setState(network.getState().toString()); - response.setRestartRequired(network.isRestartRequired()); - response.setRelated(network.getRelated()); - response.setNetworkDomain(network.getNetworkDomain()); - - response.setDns1(profile.getDns1()); - response.setDns2(profile.getDns2()); - // populate capability - Map> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId()); - List serviceResponses = new ArrayList(); - if (serviceCapabilitiesMap != null) { - for (Service service : serviceCapabilitiesMap.keySet()) { - ServiceResponse serviceResponse = new ServiceResponse(); - // skip gateway service - if (service == Service.Gateway) { - continue; - } - serviceResponse.setName(service.getName()); - - // set list of capabilities for the service - List capabilityResponses = new ArrayList(); - Map serviceCapabilities = serviceCapabilitiesMap.get(service); - if (serviceCapabilities != null) { - for (Capability capability : serviceCapabilities.keySet()) { - CapabilityResponse capabilityResponse = new CapabilityResponse(); - String capabilityValue = serviceCapabilities.get(capability); - capabilityResponse.setName(capability.getName()); - capabilityResponse.setValue(capabilityValue); - capabilityResponse.setObjectName("capability"); - capabilityResponses.add(capabilityResponse); - } - serviceResponse.setCapabilities(capabilityResponses); - } - - serviceResponse.setObjectName("service"); - serviceResponses.add(serviceResponse); - } - } - response.setServices(serviceResponses); - - if (network.getAclType() == null || network.getAclType() == ACLType.Account) { - populateOwner(response, network); - } else { - // get domain from network_domain table - Pair domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId()); - response.setDomainId(domainNetworkDetails.first()); - response.setSubdomainAccess(domainNetworkDetails.second()); - } - - Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId()); - if (dedicatedDomainId != null) { - Domain domain = ApiDBUtils.findDomainById(dedicatedDomainId); - response.setDomainId(dedicatedDomainId); - response.setDomainName(domain.getName()); - } - - response.setSpecifyIpRanges(network.getSpecifyIpRanges()); - response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); - response.setVpcId(network.getVpcId()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Network, network.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("network"); - return response; - } - - @Override - public Long getSecurityGroupId(String groupName, long accountId) { - SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId); - if (sg == null) { - return null; - } else { - return sg.getId(); - } - } - - @Override - public ProjectResponse createProjectResponse(Project project) { - ProjectResponse response = new ProjectResponse(); - response.setId(project.getId()); - response.setName(project.getName()); - response.setDisplaytext(project.getDisplayText()); - response.setState(project.getState().toString()); - - Domain domain = ApiDBUtils.findDomainById(project.getDomainId()); - response.setDomainId(domain.getId()); - response.setDomain(domain.getName()); - - response.setOwner(ApiDBUtils.getProjectOwner(project.getId()).getAccountName()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Project, project.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("project"); - return response; - } - - @Override - public FirewallResponse createFirewallResponse(FirewallRule fwRule) { - FirewallResponse response = new FirewallResponse(); - - response.setId(fwRule.getId()); - response.setProtocol(fwRule.getProtocol()); - if (fwRule.getSourcePortStart() != null) { - response.setStartPort(Integer.toString(fwRule.getSourcePortStart())); - } - - if (fwRule.getSourcePortEnd() != null) { - response.setEndPort(Integer.toString(fwRule.getSourcePortEnd())); - } - - List cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId()); - response.setCidrList(StringUtils.join(cidrs, ",")); - - IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); - response.setPublicIpAddressId(ip.getId()); - response.setPublicIpAddress(ip.getAddress().addr()); - - FirewallRule.State state = fwRule.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - - response.setIcmpCode(fwRule.getIcmpCode()); - response.setIcmpType(fwRule.getIcmpType()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.FirewallRule, fwRule.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setState(stateToSet); - response.setObjectName("firewallrule"); - return response; - } - - @Override - public NetworkACLResponse createNetworkACLResponse(FirewallRule networkACL) { - NetworkACLResponse response = new NetworkACLResponse(); - - response.setId(networkACL.getId()); - response.setProtocol(networkACL.getProtocol()); - if (networkACL.getSourcePortStart() != null) { - response.setStartPort(Integer.toString(networkACL.getSourcePortStart())); - } - - if (networkACL.getSourcePortEnd() != null) { - response.setEndPort(Integer.toString(networkACL.getSourcePortEnd())); - } - - List cidrs = ApiDBUtils.findFirewallSourceCidrs(networkACL.getId()); - response.setCidrList(StringUtils.join(cidrs, ",")); - - response.setTrafficType(networkACL.getTrafficType().toString()); - - FirewallRule.State state = networkACL.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - - response.setIcmpCode(networkACL.getIcmpCode()); - response.setIcmpType(networkACL.getIcmpType()); - - response.setState(stateToSet); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("networkacl"); - return response; - } - - public UserVmData newUserVmData(UserVm userVm) { - UserVmData userVmData = new UserVmData(); - userVmData.setId(userVm.getId()); - userVmData.setName(userVm.getHostName()); - userVmData.setCreated(userVm.getCreated()); - userVmData.setGuestOsId(userVm.getGuestOSId()); - userVmData.setHaEnable(userVm.isHaEnabled()); - if (userVm.getState() != null) { - userVmData.setState(userVm.getState().toString()); - } - if (userVm.getDisplayName() != null) { - userVmData.setDisplayName(userVm.getDisplayName()); - } else { - userVmData.setDisplayName(userVm.getHostName()); - } - userVmData.setInstanceName(userVm.getInstanceName()); - - userVmData.setDomainId(userVm.getDomainId()); - - if (userVm.getHypervisorType() != null) { - userVmData.setHypervisor(userVm.getHypervisorType().toString()); - } - - if (userVm.getPassword() != null) { - userVmData.setPassword(userVm.getPassword()); - } - return userVmData; - } - - public UserVmResponse newUserVmResponse(UserVmData userVmData, boolean caller_is_admin) { - UserVmResponse userVmResponse = new UserVmResponse(); - - userVmResponse.setHypervisor(userVmData.getHypervisor()); - userVmResponse.setId(userVmData.getId()); - userVmResponse.setName(userVmData.getName()); - - userVmResponse.setDisplayName(userVmData.getDisplayName()); - - populateAccount(userVmResponse, userVmData.getAccountId()); - populateDomain(userVmResponse, userVmData.getDomainId()); - - userVmResponse.setCreated(userVmData.getCreated()); - userVmResponse.setState(userVmData.getState()); - userVmResponse.setHaEnable(userVmData.getHaEnable()); - userVmResponse.setGroupId(userVmData.getGroupId()); - userVmResponse.setGroup(userVmData.getGroup()); - userVmResponse.setZoneId(userVmData.getZoneId()); - userVmResponse.setZoneName(userVmData.getZoneName()); - if (caller_is_admin) { - userVmResponse.setInstanceName(userVmData.getInstanceName()); - userVmResponse.setHostId(userVmData.getHostId()); - userVmResponse.setHostName(userVmData.getHostName()); - } - userVmResponse.setTemplateId(userVmData.getTemplateId()); - userVmResponse.setTemplateName(userVmData.getTemplateName()); - userVmResponse.setTemplateDisplayText(userVmData.getTemplateDisplayText()); - userVmResponse.setPasswordEnabled(userVmData.getPasswordEnabled()); - userVmResponse.setIsoId(userVmData.getIsoId()); - userVmResponse.setIsoName(userVmData.getIsoName()); - userVmResponse.setIsoDisplayText(userVmData.getIsoDisplayText()); - userVmResponse.setServiceOfferingId(userVmData.getServiceOfferingId()); - userVmResponse.setServiceOfferingName(userVmData.getServiceOfferingName()); - userVmResponse.setCpuNumber(userVmData.getCpuNumber()); - userVmResponse.setCpuSpeed(userVmData.getCpuSpeed()); - userVmResponse.setMemory(userVmData.getMemory()); - userVmResponse.setCpuUsed(userVmData.getCpuUsed()); - userVmResponse.setNetworkKbsRead(userVmData.getNetworkKbsRead()); - userVmResponse.setNetworkKbsWrite(userVmData.getNetworkKbsWrite()); - userVmResponse.setGuestOsId(userVmData.getGuestOsId()); - userVmResponse.setRootDeviceId(userVmData.getRootDeviceId()); - userVmResponse.setRootDeviceType(userVmData.getRootDeviceType()); - userVmResponse.setPassword(userVmData.getPassword()); - userVmResponse.setJobId(userVmData.getJobId()); - userVmResponse.setJobStatus(userVmData.getJobStatus()); - userVmResponse.setForVirtualNetwork(userVmData.getForVirtualNetwork()); - - Set securityGroupResponse = new HashSet(); - for (SecurityGroupData sgd : userVmData.getSecurityGroupList()) { - if (sgd.getId() != null) { - SecurityGroupResponse sgr = new SecurityGroupResponse(); - sgr.setId(sgd.getId()); - sgr.setName(sgd.getName()); - sgr.setDescription(sgd.getDescription()); - - Account account = ApiDBUtils.findAccountByNameDomain(sgd.getAccountName(), sgd.getDomainId()); - if (account != null) { - populateAccount(sgr, account.getId()); - populateDomain(sgr, account.getDomainId()); - } - - sgr.setObjectName(sgd.getObjectName()); - securityGroupResponse.add(sgr); - } - } - userVmResponse.setSecurityGroupList(new ArrayList(securityGroupResponse)); - - Set nicResponses = new HashSet(); - for (NicData nd : userVmData.getNics()) { - NicResponse nr = new NicResponse(); - nr.setId(nd.getId()); - nr.setNetworkid(nd.getNetworkid()); - nr.setNetmask(nd.getNetmask()); - nr.setGateway(nd.getGateway()); - nr.setIpaddress(nd.getIpaddress()); - nr.setIsolationUri(nd.getIsolationUri()); - nr.setBroadcastUri(nd.getBroadcastUri()); - nr.setTrafficType(nd.getTrafficType()); - nr.setType(nd.getType()); - nr.setIsDefault(nd.getIsDefault()); - nr.setMacAddress(nd.getMacAddress()); - nr.setObjectName(nd.getObjectName()); - nicResponses.add(nr); - } - userVmResponse.setNics(new ArrayList(nicResponses)); - userVmResponse.setPublicIpId(userVmData.getPublicIpId()); - userVmResponse.setPublicIp(userVmData.getPublicIp()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVmData.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - userVmResponse.setTags(tagResponses); - - return userVmResponse; - } - - @Override - public HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities) { - HypervisorCapabilitiesResponse hpvCapabilitiesResponse = new HypervisorCapabilitiesResponse(); - hpvCapabilitiesResponse.setId(hpvCapabilities.getId()); - hpvCapabilitiesResponse.setHypervisor(hpvCapabilities.getHypervisorType()); - hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion()); - hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled()); - hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit()); - return hpvCapabilitiesResponse; - } - - private void populateOwner(ControlledEntityResponse response, ControlledEntity object) { - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(object.getAccountId()); - - if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); - response.setProjectId(project.getId()); - response.setProjectName(project.getName()); - } else { - response.setAccountName(account.getAccountName()); - } - - Domain domain = ApiDBUtils.findDomainById(object.getDomainId()); - response.setDomainId(domain.getId()); - response.setDomainName(domain.getName()); - } - - private void populateAccount(ControlledEntityResponse response, long accountId) { - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(accountId); - if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); - response.setProjectId(project.getId()); - response.setProjectName(project.getName()); - } else { - response.setAccountName(account.getAccountName()); - } - } - - private void populateDomain(ControlledEntityResponse response, long domainId) { - Domain domain = ApiDBUtils.findDomainById(domainId); - - response.setDomainId(domain.getId()); - response.setDomainName(domain.getName()); - } - - @Override - public ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount) { - Account account = ApiDBUtils.findAccountById(projectAccount.getAccountId()); - ProjectAccountResponse projectAccountResponse = new ProjectAccountResponse(); - - long projectId = projectAccount.getProjectId(); - projectAccountResponse.setProjectId(projectId); - projectAccountResponse.setProjectName(ApiDBUtils.findProjectById(projectId).getName()); - - projectAccountResponse.setId(account.getId()); - projectAccountResponse.setAccountName(account.getAccountName()); - projectAccountResponse.setAccountType(account.getType()); - projectAccountResponse.setRole(projectAccount.getAccountRole().toString()); - populateDomain(projectAccountResponse, account.getDomainId()); - - // add all the users for an account as part of the response obj - List usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId()); - List userResponseList = new ArrayList(); - for (UserVO user : usersForAccount) { - UserResponse userResponse = createUserResponse(user); - userResponseList.add(userResponse); - } - - projectAccountResponse.setUsers(userResponseList); - projectAccountResponse.setObjectName("projectaccount"); - - return projectAccountResponse; - } - - @Override - public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) { - ProjectInvitationResponse response = new ProjectInvitationResponse(); - response.setId(invite.getId()); - response.setProjectId(invite.getProjectId()); - response.setProjectName(ApiDBUtils.findProjectById(invite.getProjectId()).getName()); - response.setInvitationState(invite.getState().toString()); - - if (invite.getForAccountId() != null) { - Account account = ApiDBUtils.findAccountById(invite.getForAccountId()); - response.setAccountName(account.getAccountName()); - - } else { - response.setEmail(invite.getEmail()); - } - - populateDomain(response, invite.getInDomainId()); - - response.setObjectName("projectinvitation"); - return response; - } - - @Override - public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) { - SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse(); - vmResponse.setId(vm.getId()); - vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); - vmResponse.setName(vm.getHostName()); - if (vm.getHostId() != null) { - vmResponse.setHostId(vm.getHostId()); - } - if (vm.getState() != null) { - vmResponse.setState(vm.getState().toString()); - } - if (vm.getType() == Type.DomainRouter) { - VirtualRouter router = (VirtualRouter) vm; - if (router.getRole() != null) { - vmResponse.setRole(router.getRole().toString()); - } - } - vmResponse.setObjectName("systemvminstance"); - return vmResponse; - } - - @Override - public PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result) { - PhysicalNetworkResponse response = new PhysicalNetworkResponse(); - - response.setZoneId(result.getDataCenterId()); - response.setNetworkSpeed(result.getSpeed()); - response.setVlan(result.getVnet()); - response.setDomainId(result.getDomainId()); - response.setId(result.getUuid()); - if (result.getBroadcastDomainRange() != null) { - response.setBroadcastDomainRange(result.getBroadcastDomainRange().toString()); - } - response.setIsolationMethods(result.getIsolationMethods()); - response.setTags(result.getTags()); - if (result.getState() != null) { - response.setState(result.getState().toString()); - } - - response.setName(result.getName()); - - response.setObjectName("physicalnetwork"); - return response; - } - - @Override - public ServiceResponse createNetworkServiceResponse(Service service) { - ServiceResponse response = new ServiceResponse(); - response.setName(service.getName()); - - // set list of capabilities required for the service - List capabilityResponses = new ArrayList(); - Capability[] capabilities = service.getCapabilities(); - for (Capability cap : capabilities) { - CapabilityResponse capabilityResponse = new CapabilityResponse(); - capabilityResponse.setName(cap.getName()); - capabilityResponse.setObjectName("capability"); - if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || - cap.getName().equals(Capability.SupportedSourceNatTypes.getName()) || - cap.getName().equals(Capability.RedundantRouter.getName())) { - capabilityResponse.setCanChoose(true); - } else { - capabilityResponse.setCanChoose(false); - } - capabilityResponses.add(capabilityResponse); - } - response.setCapabilities(capabilityResponses); - - // set list of providers providing this service - List serviceProviders = ApiDBUtils.getProvidersForService(service); - List serviceProvidersResponses = new ArrayList(); - for (Network.Provider serviceProvider : serviceProviders) { - // return only Virtual Router/JuniperSRX as a provider for the firewall - if (service == Service.Firewall && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX)) { - continue; - } - - ProviderResponse serviceProviderResponse = createServiceProviderResponse(serviceProvider); - serviceProvidersResponses.add(serviceProviderResponse); - } - response.setProviders(serviceProvidersResponses); - - response.setObjectName("networkservice"); - return response; - - } - - private ProviderResponse createServiceProviderResponse(Provider serviceProvider) { - ProviderResponse response = new ProviderResponse(); - response.setName(serviceProvider.getName()); - boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider); - response.setCanEnableIndividualServices(canEnableIndividualServices); - return response; - } - - @Override - public ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result) { - ProviderResponse response = new ProviderResponse(); - response.setId(result.getUuid()); - response.setName(result.getProviderName()); - response.setPhysicalNetworkId(result.getPhysicalNetworkId()); - response.setDestinationPhysicalNetworkId(result.getDestinationPhysicalNetworkId()); - response.setState(result.getState().toString()); - - // set enabled services - List services = new ArrayList(); - for (Service service : result.getEnabledServices()) { - services.add(service.getName()); - } - response.setServices(services); - - response.setObjectName("networkserviceprovider"); - return response; - } - - @Override - public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result) { - TrafficTypeResponse response = new TrafficTypeResponse(); - response.setId(result.getUuid()); - response.setPhysicalNetworkId(result.getPhysicalNetworkId()); - response.setTrafficType(result.getTrafficType().toString()); - response.setXenLabel(result.getXenNetworkLabel()); - response.setKvmLabel(result.getKvmNetworkLabel()); - response.setVmwareLabel(result.getVmwareNetworkLabel()); - - response.setObjectName("traffictype"); - return response; - } - - @Override - public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) { - VirtualRouterProviderResponse response = new VirtualRouterProviderResponse(); - response.setId(result.getId()); - response.setNspId(result.getNspId()); - response.setEnabled(result.isEnabled()); - - response.setObjectName("virtualrouterelement"); - return response; - } - - @Override - public LBStickinessResponse createLBStickinessPolicyResponse( - StickinessPolicy stickinessPolicy, LoadBalancer lb) { - LBStickinessResponse spResponse = new LBStickinessResponse(); - - spResponse.setlbRuleId(lb.getId()); - Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId()); - if (accountTemp != null) { - spResponse.setAccountName(accountTemp.getAccountName()); - spResponse.setDomainId(accountTemp.getDomainId()); - spResponse.setDomainName(ApiDBUtils.findDomainById( - accountTemp.getDomainId()).getName()); - } - - List responses = new ArrayList(); - LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse( - stickinessPolicy); - responses.add(ruleResponse); - - spResponse.setRules(responses); - - spResponse.setObjectName("stickinesspolicies"); - return spResponse; - } - - @Override - public LBStickinessResponse createLBStickinessPolicyResponse( - List stickinessPolicies, LoadBalancer lb) { - LBStickinessResponse spResponse = new LBStickinessResponse(); - - if (lb == null) - return spResponse; - spResponse.setlbRuleId(lb.getId()); - Account account = ApiDBUtils.findAccountById(lb.getAccountId()); - if (account != null) { - spResponse.setAccountName(account.getAccountName()); - spResponse.setDomainId(account.getDomainId()); - spResponse.setDomainName(ApiDBUtils.findDomainById( - account.getDomainId()).getName()); - } - - List responses = new ArrayList(); - for (StickinessPolicy stickinessPolicy : stickinessPolicies) { - LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy); - responses.add(ruleResponse); - } - spResponse.setRules(responses); - - spResponse.setObjectName("stickinesspolicies"); - return spResponse; - } - - @Override - public LDAPConfigResponse createLDAPConfigResponse(String hostname, - Integer port, Boolean useSSL, String queryFilter, - String searchBase, String bindDN) { - LDAPConfigResponse lr = new LDAPConfigResponse(); - lr.setHostname(hostname); - lr.setPort(port.toString()); - lr.setUseSSL(useSSL.toString()); - lr.setQueryFilter(queryFilter); - lr.setBindDN(bindDN); - lr.setSearchBase(searchBase); - lr.setObjectName("ldapconfig"); - return lr; - } - - @Override - public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) { - StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse(); - response.setUuid(result.getUuid()); - response.setVlan(result.getVlan()); - response.setEndIp(result.getEndIp()); - response.setStartIp(result.getStartIp()); - response.setPodUuid(result.getPodUuid()); - response.setZoneUuid(result.getZoneUuid()); - response.setNetworkUuid(result.getNetworkUuid()); - response.setNetmask(result.getNetmask()); - response.setGateway(result.getGateway()); - 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())); - Long accountId = resourceTag.getAccountId(); - Long domainId = resourceTag.getDomainId(); - if (accountId != null) { - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId()); - - if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); - response.setProjectId(project.getId()); - response.setProjectName(project.getName()); - } else { - response.setAccountName(account.getAccountName()); - } - } - - if (domainId != null) { - response.setDomainId(domainId); - response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); - } - - response.setCustomer(resourceTag.getCustomer()); - } - - response.setObjectName("tag"); - - return response; - } - - @Override - public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { - VpcOfferingResponse response = new VpcOfferingResponse(); - response.setId(offering.getId()); - response.setName(offering.getName()); - response.setDisplayText(offering.getDisplayText()); - response.setIsDefault(offering.isDefault()); - response.setState(offering.getState().name()); - - Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); - List serviceResponses = new ArrayList(); - for (Service service : serviceProviderMap.keySet()) { - ServiceResponse svcRsp = new ServiceResponse(); - // skip gateway service - if (service == Service.Gateway) { - continue; - } - svcRsp.setName(service.getName()); - List providers = new ArrayList(); - for (Provider provider : serviceProviderMap.get(service)) { - if (provider != null) { - ProviderResponse providerRsp = new ProviderResponse(); - providerRsp.setName(provider.getName()); - providers.add(providerRsp); - } - } - svcRsp.setProviders(providers); - - serviceResponses.add(svcRsp); - } - response.setServices(serviceResponses); - response.setObjectName("vpcoffering"); - return response; - } - - - @Override - public VpcResponse createVpcResponse(Vpc vpc) { - VpcResponse response = new VpcResponse(); - response.setId(vpc.getId()); - response.setName(vpc.getName()); - response.setDisplayText(vpc.getDisplayText()); - response.setState(vpc.getState().name()); - response.setVpcOfferingId(vpc.getVpcOfferingId()); - response.setCidr(vpc.getCidr()); - response.setRestartRequired(vpc.isRestartRequired()); - response.setNetworkDomain(vpc.getNetworkDomain()); - - Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId()); - List serviceResponses = new ArrayList(); - for (Service service : serviceProviderMap.keySet()) { - ServiceResponse svcRsp = new ServiceResponse(); - // skip gateway service - if (service == Service.Gateway) { - continue; - } - svcRsp.setName(service.getName()); - List providers = new ArrayList(); - for (Provider provider : serviceProviderMap.get(service)) { - if (provider != null) { - ProviderResponse providerRsp = new ProviderResponse(); - providerRsp.setName(provider.getName()); - providers.add(providerRsp); - } - } - svcRsp.setProviders(providers); - - serviceResponses.add(svcRsp); - } - - List networkResponses = new ArrayList(); - List networks = ApiDBUtils.listVpcNetworks(vpc.getId()); - for (Network network : networks) { - NetworkResponse ntwkRsp = createNetworkResponse(network); - networkResponses.add(ntwkRsp); - } - - DataCenter zone = ApiDBUtils.findZoneById(vpc.getZoneId()); - response.setZoneId(vpc.getZoneId()); - response.setZoneName(zone.getName()); - - response.setNetworks(networkResponses); - response.setServices(serviceResponses); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Vpc, vpc.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("vpc"); - return response; - } - - @Override - public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) { - PrivateGatewayResponse response = new PrivateGatewayResponse(); - response.setId(result.getId()); - response.setVlan(result.getVlanTag()); - response.setGateway(result.getGateway()); - response.setNetmask(result.getNetmask()); - response.setVpcId(result.getVpcId()); - response.setZoneId(result.getZoneId()); - DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId()); - response.setZoneName(zone.getName()); - response.setAddress(result.getIp4Address()); - response.setPhysicalNetworkId(result.getPhysicalNetworkId()); - - populateAccount(response, result.getAccountId()); - populateDomain(response, result.getDomainId()); - response.setState(result.getState().toString()); - - response.setObjectName("privategateway"); - - return response; - } - - @Override - public StaticRouteResponse createStaticRouteResponse(StaticRoute result) { - StaticRouteResponse response = new StaticRouteResponse(); - response.setId(result.getId()); - response.setVpcId(result.getVpcId()); - response.setCidr(result.getCidr()); - - StaticRoute.State state = result.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; - } - response.setState(stateToSet); - populateAccount(response, result.getAccountId()); - populateDomain(response, result.getDomainId()); - - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.StaticRoute, result.getId()); - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - response.setObjectName("staticroute"); - - return response; - } - - @Override - public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) { - Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse(); - response.setId(result.getId()); - response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString()); - response.setVpcId(result.getVpcId()); - response.setRemoved(result.getRemoved()); - response.setObjectName("vpngateway"); - - populateAccount(response, result.getAccountId()); - populateDomain(response, result.getDomainId()); - - return response; - } - - @Override - public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) { - Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse(); - response.setId(result.getId()); - response.setGatewayIp(result.getGatewayIp()); - response.setGuestCidrList(result.getGuestCidrList()); - response.setIpsecPsk(result.getIpsecPsk()); - response.setRemoved(result.getRemoved()); - response.setObjectName("vpncustomergateway"); - - populateAccount(response, result.getAccountId()); - populateDomain(response, result.getDomainId()); - - return response; - } - - @Override - public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) { - Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse(); - response.setId(result.getId()); - - response.setVpnGatewayId(result.getVpnGatewayId()); - Long vpnGatewayId = result.getVpnGatewayId(); - if(vpnGatewayId != null) { - Site2SiteVpnGatewayVO vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId); - - long ipId = vpnGateway.getAddrId(); - IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId); - response.setIp(ipObj.getAddress().addr()); - } - - response.setCustomerGatewayId(result.getCustomerGatewayId()); - Long customerGatewayId = result.getCustomerGatewayId(); - if(customerGatewayId != null) { - Site2SiteCustomerGatewayVO customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId); - response.setGatewayIp(customerGateway.getGatewayIp()); - response.setGuestCidrList(customerGateway.getGuestCidrList()); - response.setIpsecPsk(customerGateway.getIpsecPsk()); - response.setIkePolicy(customerGateway.getIkePolicy()); - response.setEspPolicy(customerGateway.getEspPolicy()); - response.setLifetime(customerGateway.getLifetime()); - } - - populateAccount(response, result.getAccountId()); - populateDomain(response, result.getDomainId()); - - response.setState(result.getState().toString()); - response.setCreated(result.getCreated()); - response.setRemoved(result.getRemoved()); - response.setObjectName("vpnconnection"); - return response; - } -} +// 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.api; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import org.apache.log4j.Logger; + +import com.cloud.acl.ControlledEntity; +import com.cloud.acl.ControlledEntity.ACLType; +import com.cloud.api.ApiConstants.HostDetails; +import com.cloud.api.ApiConstants.VMDetails; +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; +import com.cloud.api.response.DomainRouterResponse; +import com.cloud.api.response.EventResponse; +import com.cloud.api.response.ExtractResponse; +import com.cloud.api.response.FirewallResponse; +import com.cloud.api.response.FirewallRuleResponse; +import com.cloud.api.response.HostResponse; +import com.cloud.api.response.HypervisorCapabilitiesResponse; +import com.cloud.api.response.IPAddressResponse; +import com.cloud.api.response.InstanceGroupResponse; +import com.cloud.api.response.IpForwardingRuleResponse; +import com.cloud.api.response.LBStickinessPolicyResponse; +import com.cloud.api.response.LBStickinessResponse; +import com.cloud.api.response.LDAPConfigResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.LoadBalancerResponse; +import com.cloud.api.response.NetworkACLResponse; +import com.cloud.api.response.NetworkOfferingResponse; +import com.cloud.api.response.NetworkResponse; +import com.cloud.api.response.NicResponse; +import com.cloud.api.response.PhysicalNetworkResponse; +import com.cloud.api.response.PodResponse; +import com.cloud.api.response.PrivateGatewayResponse; +import com.cloud.api.response.ProjectAccountResponse; +import com.cloud.api.response.ProjectInvitationResponse; +import com.cloud.api.response.ProjectResponse; +import com.cloud.api.response.ProviderResponse; +import com.cloud.api.response.RemoteAccessVpnResponse; +import com.cloud.api.response.ResourceCountResponse; +import com.cloud.api.response.ResourceLimitResponse; +import com.cloud.api.response.ResourceTagResponse; +import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.api.response.SecurityGroupResultObject; +import com.cloud.api.response.SecurityGroupRuleResponse; +import com.cloud.api.response.SecurityGroupRuleResultObject; +import com.cloud.api.response.ServiceOfferingResponse; +import com.cloud.api.response.ServiceResponse; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; +import com.cloud.api.response.SnapshotPolicyResponse; +import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; +import com.cloud.api.response.StorageNetworkIpRangeResponse; +import com.cloud.api.response.StoragePoolResponse; +import com.cloud.api.response.SwiftResponse; +import com.cloud.api.response.SystemVmInstanceResponse; +import com.cloud.api.response.SystemVmResponse; +import com.cloud.api.response.TemplatePermissionsResponse; +import com.cloud.api.response.TemplateResponse; +import com.cloud.api.response.TrafficTypeResponse; +import com.cloud.api.response.UserResponse; +import com.cloud.api.response.UserVmResponse; +import com.cloud.api.response.VirtualRouterProviderResponse; +import com.cloud.api.response.VlanIpRangeResponse; +import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; +import com.cloud.api.response.VpnUsersResponse; +import com.cloud.api.response.ZoneResponse; +import com.cloud.async.AsyncJob; +import com.cloud.capacity.Capacity; +import com.cloud.capacity.CapacityVO; +import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; +import com.cloud.configuration.Configuration; +import com.cloud.configuration.Resource.ResourceOwnerType; +import com.cloud.configuration.Resource.ResourceType; +import com.cloud.configuration.ResourceCount; +import com.cloud.configuration.ResourceLimit; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; +import com.cloud.dc.StorageNetworkIpRange; +import com.cloud.dc.Vlan; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; +import com.cloud.domain.Domain; +import com.cloud.event.Event; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.Host; +import com.cloud.host.HostStats; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.HypervisorCapabilities; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkProfile; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkTrafficType; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +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; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.security.SecurityGroup; +import com.cloud.network.security.SecurityGroupRules; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.network.security.SecurityRule; +import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.org.Cluster; +import com.cloud.projects.Project; +import com.cloud.projects.ProjectAccount; +import com.cloud.projects.ProjectInvitation; +import com.cloud.server.Criteria; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOS; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.Snapshot; +import com.cloud.storage.Storage; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.StorageStats; +import com.cloud.storage.Swift; +import com.cloud.storage.UploadVO; +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateSwiftVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.snapshot.SnapshotPolicy; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.test.PodZoneConfig; +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.user.UserContext; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.UserVO; +import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.ConsoleProxyVO; +import com.cloud.vm.InstanceGroup; +import com.cloud.vm.InstanceGroupVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VmStats; +import com.cloud.vm.dao.UserVmData; +import com.cloud.vm.dao.UserVmData.NicData; +import com.cloud.vm.dao.UserVmData.SecurityGroupData; + +public class ApiResponseHelper implements ResponseGenerator { + + public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class); + private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##"); + + @Override + public UserResponse createUserResponse(User user) { + UserResponse userResponse = new UserResponse(); + Account account = ApiDBUtils.findAccountById(user.getAccountId()); + userResponse.setAccountName(account.getAccountName()); + userResponse.setAccountType(account.getType()); + userResponse.setCreated(user.getCreated()); + userResponse.setDomainId(account.getDomainId()); + userResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName()); + userResponse.setEmail(user.getEmail()); + userResponse.setFirstname(user.getFirstname()); + userResponse.setId(user.getId()); + userResponse.setLastname(user.getLastname()); + userResponse.setState(user.getState().toString()); + userResponse.setTimezone(user.getTimezone()); + userResponse.setUsername(user.getUsername()); + userResponse.setApiKey(user.getApiKey()); + userResponse.setSecretKey(user.getSecretKey()); + userResponse.setObjectName("user"); + + return userResponse; + } + + // this method is used for response generation via createAccount (which creates an account + user) + @Override + public AccountResponse createUserAccountResponse(UserAccount user) { + return createAccountResponse(ApiDBUtils.findAccountById(user.getAccountId())); + } + + @Override + public AccountResponse createAccountResponse(Account account) { + boolean accountIsAdmin = (account.getType() == Account.ACCOUNT_TYPE_ADMIN); + AccountResponse accountResponse = new AccountResponse(); + accountResponse.setId(account.getId()); + accountResponse.setName(account.getAccountName()); + accountResponse.setAccountType(account.getType()); + accountResponse.setDomainId(account.getDomainId()); + accountResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName()); + accountResponse.setState(account.getState().toString()); + accountResponse.setNetworkDomain(account.getNetworkDomain()); + accountResponse.setDefaultZone(account.getDefaultZoneId()); + + // get network stat + List stats = ApiDBUtils.listUserStatsBy(account.getId()); + if (stats == null) { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal error searching for user stats"); + } + + Long bytesSent = 0L; + Long bytesReceived = 0L; + for (UserStatisticsVO stat : stats) { + Long rx = stat.getNetBytesReceived() + stat.getCurrentBytesReceived(); + Long tx = stat.getNetBytesSent() + stat.getCurrentBytesSent(); + bytesReceived = bytesReceived + Long.valueOf(rx); + bytesSent = bytesSent + Long.valueOf(tx); + } + accountResponse.setBytesReceived(bytesReceived); + accountResponse.setBytesSent(bytesSent); + + // Get resource limits and counts + + Long vmLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.user_vm, account.getId()); + String vmLimitDisplay = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit); + Long vmTotal = ApiDBUtils.getResourceCount(ResourceType.user_vm, account.getId()); + String vmAvail = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit - vmTotal); + accountResponse.setVmLimit(vmLimitDisplay); + accountResponse.setVmTotal(vmTotal); + accountResponse.setVmAvailable(vmAvail); + + Long ipLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.public_ip, account.getId()); + String ipLimitDisplay = (accountIsAdmin || ipLimit == -1) ? "Unlimited" : String.valueOf(ipLimit); + Long ipTotal = ApiDBUtils.getResourceCount(ResourceType.public_ip, account.getId()); + + Long ips = ipLimit - ipTotal; + // check how many free ips are left, and if it's less than max allowed number of ips from account - use this + // value + Long ipsLeft = ApiDBUtils.countFreePublicIps(); + boolean unlimited = true; + if (ips.longValue() > ipsLeft.longValue()) { + ips = ipsLeft; + unlimited = false; + } + + String ipAvail = ((accountIsAdmin || ipLimit == -1) && unlimited) ? "Unlimited" : String.valueOf(ips); + + accountResponse.setIpLimit(ipLimitDisplay); + accountResponse.setIpTotal(ipTotal); + accountResponse.setIpAvailable(ipAvail); + + Long volumeLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.volume, account.getId()); + String volumeLimitDisplay = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit); + Long volumeTotal = ApiDBUtils.getResourceCount(ResourceType.volume, account.getId()); + String volumeAvail = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit - volumeTotal); + accountResponse.setVolumeLimit(volumeLimitDisplay); + accountResponse.setVolumeTotal(volumeTotal); + accountResponse.setVolumeAvailable(volumeAvail); + + Long snapshotLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.snapshot, account.getId()); + String snapshotLimitDisplay = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit); + Long snapshotTotal = ApiDBUtils.getResourceCount(ResourceType.snapshot, account.getId()); + String snapshotAvail = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit - snapshotTotal); + accountResponse.setSnapshotLimit(snapshotLimitDisplay); + accountResponse.setSnapshotTotal(snapshotTotal); + accountResponse.setSnapshotAvailable(snapshotAvail); + + Long templateLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.template, account.getId()); + String templateLimitDisplay = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit); + Long templateTotal = ApiDBUtils.getResourceCount(ResourceType.template, account.getId()); + String templateAvail = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit - templateTotal); + accountResponse.setTemplateLimit(templateLimitDisplay); + accountResponse.setTemplateTotal(templateTotal); + accountResponse.setTemplateAvailable(templateAvail); + + // Get stopped and running VMs + int vmStopped = 0; + int vmRunning = 0; + + List permittedAccounts = new ArrayList(); + permittedAccounts.add(account.getId()); + + List virtualMachines = ApiDBUtils.searchForUserVMs(new Criteria(), permittedAccounts); + + // get Running/Stopped VMs + for (Iterator iter = virtualMachines.iterator(); iter.hasNext();) { + // count how many stopped/running vms we have + UserVm vm = iter.next(); + + if (vm.getState() == State.Stopped) { + vmStopped++; + } else if (vm.getState() == State.Running) { + vmRunning++; + } + } + + accountResponse.setVmStopped(vmStopped); + accountResponse.setVmRunning(vmRunning); + accountResponse.setObjectName("account"); + + //get resource limits for projects + Long projectLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.project, account.getId()); + String projectLimitDisplay = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit); + Long projectTotal = ApiDBUtils.getResourceCount(ResourceType.project, account.getId()); + String projectAvail = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal); + accountResponse.setProjectLimit(projectLimitDisplay); + accountResponse.setProjectTotal(projectTotal); + accountResponse.setProjectAvailable(projectAvail); + + //get resource limits for networks + Long networkLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.network, account.getId()); + String networkLimitDisplay = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit); + Long networkTotal = ApiDBUtils.getResourceCount(ResourceType.network, account.getId()); + String networkAvail = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal); + accountResponse.setNetworkLimit(networkLimitDisplay); + accountResponse.setNetworkTotal(networkTotal); + accountResponse.setNetworkAvailable(networkAvail); + + // adding all the users for an account as part of the response obj + List usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId()); + List userResponseList = new ArrayList(); + for (UserVO user : usersForAccount) { + UserResponse userResponse = createUserResponse(user); + userResponseList.add(userResponse); + } + + accountResponse.setUsers(userResponseList); + accountResponse.setDetails(ApiDBUtils.getAccountDetails(account.getId())); + return accountResponse; + } + + @Override + public UserResponse createUserResponse(UserAccount user) { + UserResponse userResponse = new UserResponse(); + userResponse.setAccountName(user.getAccountName()); + userResponse.setAccountType(user.getType()); + userResponse.setCreated(user.getCreated()); + userResponse.setDomainId(user.getDomainId()); + userResponse.setDomainName(ApiDBUtils.findDomainById(user.getDomainId()).getName()); + userResponse.setEmail(user.getEmail()); + userResponse.setFirstname(user.getFirstname()); + userResponse.setId(user.getId()); + userResponse.setLastname(user.getLastname()); + userResponse.setState(user.getState()); + userResponse.setTimezone(user.getTimezone()); + userResponse.setUsername(user.getUsername()); + userResponse.setApiKey(user.getApiKey()); + userResponse.setSecretKey(user.getSecretKey()); + userResponse.setAccountId((user.getAccountId())); + userResponse.setObjectName("user"); + + return userResponse; + } + + @Override + public DomainResponse createDomainResponse(Domain domain) { + DomainResponse domainResponse = new DomainResponse(); + domainResponse.setDomainName(domain.getName()); + domainResponse.setId(domain.getId()); + domainResponse.setLevel(domain.getLevel()); + domainResponse.setNetworkDomain(domain.getNetworkDomain()); + domainResponse.setParentDomainId(domain.getParent()); + StringBuilder domainPath = new StringBuilder("ROOT"); + (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1); + domainResponse.setPath(domainPath.toString()); + if (domain.getParent() != null) { + domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName()); + } + if (domain.getChildCount() > 0) { + domainResponse.setHasChild(true); + } + domainResponse.setObjectName("domain"); + return domainResponse; + } + + @Override + public DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering) { + DiskOfferingResponse diskOfferingResponse = new DiskOfferingResponse(); + diskOfferingResponse.setId(offering.getId()); + diskOfferingResponse.setName(offering.getName()); + diskOfferingResponse.setDisplayText(offering.getDisplayText()); + diskOfferingResponse.setCreated(offering.getCreated()); + diskOfferingResponse.setDiskSize(offering.getDiskSize() / (1024 * 1024 * 1024)); + if (offering.getDomainId() != null) { + diskOfferingResponse.setDomain(ApiDBUtils.findDomainById(offering.getDomainId()).getName()); + diskOfferingResponse.setDomainId(offering.getDomainId()); + } + diskOfferingResponse.setTags(offering.getTags()); + diskOfferingResponse.setCustomized(offering.isCustomized()); + diskOfferingResponse.setObjectName("diskoffering"); + return diskOfferingResponse; + } + + @Override + public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) { + ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse(); + if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) { + populateDomain(resourceLimitResponse, limit.getOwnerId()); + } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) { + Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId()); + populateAccount(resourceLimitResponse, limit.getOwnerId()); + populateDomain(resourceLimitResponse, accountTemp.getDomainId()); + } + resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); + resourceLimitResponse.setMax(limit.getMax()); + resourceLimitResponse.setObjectName("resourcelimit"); + + return resourceLimitResponse; + } + + @Override + public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) { + ResourceCountResponse resourceCountResponse = new ResourceCountResponse(); + + if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) { + Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId()); + if (accountTemp != null) { + populateAccount(resourceCountResponse, accountTemp.getId()); + populateDomain(resourceCountResponse, accountTemp.getDomainId()); + } + } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) { + populateDomain(resourceCountResponse, resourceCount.getOwnerId()); + } + + resourceCountResponse.setResourceType(Integer.valueOf(resourceCount.getType().getOrdinal()).toString()); + resourceCountResponse.setResourceCount(resourceCount.getCount()); + resourceCountResponse.setObjectName("resourcecount"); + return resourceCountResponse; + } + + @Override + public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) { + ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse(); + offeringResponse.setId(offering.getId()); + offeringResponse.setName(offering.getName()); + offeringResponse.setIsSystemOffering(offering.getSystemUse()); + offeringResponse.setDefaultUse(offering.getDefaultUse()); + offeringResponse.setSystemVmType(offering.getSystemVmType()); + offeringResponse.setDisplayText(offering.getDisplayText()); + offeringResponse.setCpuNumber(offering.getCpu()); + offeringResponse.setCpuSpeed(offering.getSpeed()); + offeringResponse.setMemory(offering.getRamSize()); + offeringResponse.setCreated(offering.getCreated()); + offeringResponse.setStorageType(offering.getUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString()); + offeringResponse.setOfferHa(offering.getOfferHA()); + offeringResponse.setLimitCpuUse(offering.getLimitCpuUse()); + offeringResponse.setTags(offering.getTags()); + if (offering.getDomainId() != null) { + offeringResponse.setDomain(ApiDBUtils.findDomainById(offering.getDomainId()).getName()); + offeringResponse.setDomainId(offering.getDomainId()); + } + offeringResponse.setNetworkRate(offering.getRateMbps()); + offeringResponse.setHostTag(offering.getHostTag()); + offeringResponse.setObjectName("serviceoffering"); + + return offeringResponse; + } + + @Override + public ConfigurationResponse createConfigurationResponse(Configuration cfg) { + ConfigurationResponse cfgResponse = new ConfigurationResponse(); + cfgResponse.setCategory(cfg.getCategory()); + cfgResponse.setDescription(cfg.getDescription()); + cfgResponse.setName(cfg.getName()); + cfgResponse.setValue(cfg.getValue()); + cfgResponse.setObjectName("configuration"); + + return cfgResponse; + } + + @Override + public SnapshotResponse createSnapshotResponse(Snapshot snapshot) { + SnapshotResponse snapshotResponse = new SnapshotResponse(); + snapshotResponse.setId(snapshot.getId()); + + populateOwner(snapshotResponse, snapshot); + + VolumeVO volume = findVolumeById(snapshot.getVolumeId()); + String snapshotTypeStr = snapshot.getType().name(); + snapshotResponse.setSnapshotType(snapshotTypeStr); + snapshotResponse.setVolumeId(snapshot.getVolumeId()); + if (volume != null) { + snapshotResponse.setVolumeName(volume.getName()); + snapshotResponse.setVolumeType(volume.getVolumeType().name()); + } + snapshotResponse.setCreated(snapshot.getCreated()); + 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(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + snapshotResponse.setTags(tagResponses); + + snapshotResponse.setObjectName("snapshot"); + return snapshotResponse; + } + + @Override + public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) { + SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse(); + policyResponse.setId(policy.getId()); + policyResponse.setVolumeId(policy.getVolumeId()); + policyResponse.setSchedule(policy.getSchedule()); + policyResponse.setIntervalType(policy.getInterval()); + policyResponse.setMaxSnaps(policy.getMaxSnaps()); + policyResponse.setTimezone(policy.getTimezone()); + policyResponse.setObjectName("snapshotpolicy"); + + return policyResponse; + } + + @Override + public HostResponse createHostResponse(Host host) { + return createHostResponse(host, EnumSet.of(HostDetails.all)); + } + + @Override + public HostResponse createHostResponse(Host host, EnumSet details) { + HostResponse hostResponse = new HostResponse(); + hostResponse.setId(host.getId()); + hostResponse.setCapabilities(host.getCapabilities()); + hostResponse.setClusterId(host.getClusterId()); + hostResponse.setCpuNumber(host.getCpus()); + hostResponse.setZoneId(host.getDataCenterId()); + hostResponse.setDisconnectedOn(host.getDisconnectedOn()); + hostResponse.setHypervisor(host.getHypervisorType()); + hostResponse.setHostType(host.getType()); + hostResponse.setLastPinged(new Date(host.getLastPinged())); + hostResponse.setManagementServerId(host.getManagementServerId()); + hostResponse.setName(host.getName()); + hostResponse.setPodId(host.getPodId()); + hostResponse.setRemoved(host.getRemoved()); + hostResponse.setCpuSpeed(host.getSpeed()); + hostResponse.setState(host.getStatus()); + hostResponse.setIpAddress(host.getPrivateIpAddress()); + hostResponse.setVersion(host.getVersion()); + hostResponse.setCreated(host.getCreated()); + + if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity) + || details.contains(HostDetails.stats) || details.contains(HostDetails.events)) { + + GuestOSCategoryVO guestOSCategory = ApiDBUtils.getHostGuestOSCategory(host.getId()); + if (guestOSCategory != null) { + hostResponse.setOsCategoryId(guestOSCategory.getId()); + hostResponse.setOsCategoryName(guestOSCategory.getName()); + } + hostResponse.setZoneName(ApiDBUtils.findZoneById(host.getDataCenterId()).getName()); + + if (host.getPodId() != null) { + HostPodVO pod = ApiDBUtils.findPodById(host.getPodId()); + if (pod != null) { + hostResponse.setPodName(pod.getName()); + } + } + + if (host.getClusterId() != null) { + ClusterVO cluster = ApiDBUtils.findClusterById(host.getClusterId()); + hostResponse.setClusterName(cluster.getName()); + hostResponse.setClusterType(cluster.getClusterType().toString()); + } + } + + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + if (host.getType() == Host.Type.Routing) { + if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)) { + // set allocated capacities + Long mem = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_MEMORY); + Long cpu = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_CPU); + + hostResponse.setMemoryAllocated(mem); + 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)) { + hostResponse.setHaHost(true); + } else { + hostResponse.setHaHost(false); + } + } else { + hostResponse.setHaHost(false); + } + + hostResponse.setHypervisorVersion(host.getHypervisorVersion()); + + String cpuAlloc = decimalFormat.format(((float) cpu / (float) (host.getCpus() * host.getSpeed())) * 100f) + "%"; + hostResponse.setCpuAllocated(cpuAlloc); + String cpuWithOverprovisioning = new Float(host.getCpus() * host.getSpeed() * ApiDBUtils.getCpuOverprovisioningFactor()).toString(); + hostResponse.setCpuWithOverprovisioning(cpuWithOverprovisioning); + } + + if (details.contains(HostDetails.all) || details.contains(HostDetails.stats)) { + // set CPU/RAM/Network stats + String cpuUsed = null; + HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId()); + if (hostStats != null) { + float cpuUtil = (float) hostStats.getCpuUtilization(); + cpuUsed = decimalFormat.format(cpuUtil) + "%"; + hostResponse.setCpuUsed(cpuUsed); + hostResponse.setMemoryUsed((new Double(hostStats.getUsedMemory())).longValue()); + hostResponse.setNetworkKbsRead((new Double(hostStats.getNetworkReadKBs())).longValue()); + hostResponse.setNetworkKbsWrite((new Double(hostStats.getNetworkWriteKBs())).longValue()); + + } + } + + } else if (host.getType() == Host.Type.SecondaryStorage) { + StorageStats secStorageStats = ApiDBUtils.getSecondaryStorageStatistics(host.getId()); + if (secStorageStats != null) { + hostResponse.setDiskSizeTotal(secStorageStats.getCapacityBytes()); + hostResponse.setDiskSizeAllocated(secStorageStats.getByteUsed()); + } + } + + hostResponse.setLocalStorageActive(ApiDBUtils.isLocalStorageActiveOnHost(host)); + + if (details.contains(HostDetails.all) || details.contains(HostDetails.events)) { + Set possibleEvents = host.getStatus().getPossibleEvents(); + if ((possibleEvents != null) && !possibleEvents.isEmpty()) { + String events = ""; + Iterator iter = possibleEvents.iterator(); + while (iter.hasNext()) { + com.cloud.host.Status.Event event = iter.next(); + events += event.toString(); + if (iter.hasNext()) { + events += "; "; + } + } + hostResponse.setEvents(events); + } + } + + hostResponse.setResourceState(host.getResourceState().toString()); + hostResponse.setObjectName("host"); + + return hostResponse; + } + + @Override + public SwiftResponse createSwiftResponse(Swift swift) { + SwiftResponse swiftResponse = new SwiftResponse(); + swiftResponse.setId(swift.getId()); + swiftResponse.setUrl(swift.getUrl()); + swiftResponse.setAccount(swift.getAccount()); + swiftResponse.setUsername(swift.getUserName()); + swiftResponse.setObjectName("swift"); + return swiftResponse; + } + + @Override + public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) { + Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId()); + + VlanIpRangeResponse vlanResponse = new VlanIpRangeResponse(); + vlanResponse.setId(vlan.getId()); + vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork)); + vlanResponse.setVlan(vlan.getVlanTag()); + vlanResponse.setZoneId(vlan.getDataCenterId()); + + if (podId != null) { + HostPodVO pod = ApiDBUtils.findPodById(podId); + vlanResponse.setPodId(podId); + if (pod != null) { + vlanResponse.setPodName(pod.getName()); + } + } + + vlanResponse.setGateway(vlan.getVlanGateway()); + vlanResponse.setNetmask(vlan.getVlanNetmask()); + + // get start ip and end ip of corresponding vlan + String ipRange = vlan.getIpRange(); + String[] range = ipRange.split("-"); + vlanResponse.setStartIp(range[0]); + vlanResponse.setEndIp(range[1]); + + vlanResponse.setNetworkId(vlan.getNetworkId()); + Account owner = ApiDBUtils.getVlanAccount(vlan.getId()); + if (owner != null) { + populateAccount(vlanResponse, owner.getId()); + populateDomain(vlanResponse, owner.getDomainId()); + } + + vlanResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId()); + + vlanResponse.setObjectName("vlan"); + return vlanResponse; + } + + @Override + public IPAddressResponse createIPAddressResponse(IpAddress ipAddr) { + VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId()); + boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork); + long zoneId = ipAddr.getDataCenterId(); + + IPAddressResponse ipResponse = new IPAddressResponse(); + ipResponse.setId(ipAddr.getId()); + ipResponse.setIpAddress(ipAddr.getAddress().toString()); + if (ipAddr.getAllocatedTime() != null) { + ipResponse.setAllocated(ipAddr.getAllocatedTime()); + } + ipResponse.setZoneId(zoneId); + ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddr.getDataCenterId()).getName()); + ipResponse.setSourceNat(ipAddr.isSourceNat()); + ipResponse.setIsSystem(ipAddr.getSystem()); + + // get account information + if (ipAddr.getAllocatedToAccountId() != null) { + populateOwner(ipResponse, ipAddr); + } + + ipResponse.setForVirtualNetwork(forVirtualNetworks); + ipResponse.setStaticNat(ipAddr.isOneToOneNat()); + + if (ipAddr.getAssociatedWithVmId() != null) { + UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId()); + ipResponse.setVirtualMachineId(vm.getId()); + ipResponse.setVirtualMachineName(vm.getHostName()); + if (vm.getDisplayName() != null) { + ipResponse.setVirtualMachineDisplayName(vm.getDisplayName()); + } else { + ipResponse.setVirtualMachineDisplayName(vm.getHostName()); + } + } + + ipResponse.setAssociatedNetworkId(ipAddr.getAssociatedWithNetworkId()); + ipResponse.setVpcId(ipAddr.getVpcId()); + + // Network id the ip is associated with (if associated networkId is null, try to get this information from vlan) + Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId()); + + // Network id the ip belongs to + Long networkId; + if (vlanNetworkId != null) { + networkId = vlanNetworkId; + } else { + networkId = ApiDBUtils.getPublicNetworkIdByZone(zoneId); + } + + ipResponse.setNetworkId(networkId); + ipResponse.setState(ipAddr.getState().toString()); + ipResponse.setPhysicalNetworkId(ipAddr.getPhysicalNetworkId()); + + // show this info to admin only + Account account = UserContext.current().getCaller(); + if ((account == null) || account.getType() == Account.ACCOUNT_TYPE_ADMIN) { + ipResponse.setVlanId(ipAddr.getVlanId()); + ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); + } + + if (ipAddr.getSystem()) { + if (ipAddr.isOneToOneNat()) { + ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString()); + } else { + ipResponse.setPurpose(IpAddress.Purpose.Lb.toString()); + } + } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + ipResponse.setTags(tagResponses); + + ipResponse.setObjectName("ipaddress"); + return ipResponse; + } + + @Override + public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer) { + LoadBalancerResponse lbResponse = new LoadBalancerResponse(); + lbResponse.setId(loadBalancer.getId()); + lbResponse.setName(loadBalancer.getName()); + lbResponse.setDescription(loadBalancer.getDescription()); + List cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId()); + lbResponse.setCidrList(StringUtils.join(cidrs, ",")); + + IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId()); + lbResponse.setPublicIpId(publicIp.getId()); + lbResponse.setPublicIp(publicIp.getAddress().addr()); + lbResponse.setPublicPort(Integer.toString(loadBalancer.getSourcePortStart())); + lbResponse.setPrivatePort(Integer.toString(loadBalancer.getDefaultPortStart())); + lbResponse.setAlgorithm(loadBalancer.getAlgorithm()); + FirewallRule.State state = loadBalancer.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + lbResponse.setState(stateToSet); + populateOwner(lbResponse, loadBalancer); + lbResponse.setZoneId(publicIp.getDataCenterId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, loadBalancer.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + lbResponse.setTags(tagResponses); + + lbResponse.setObjectName("loadbalancer"); + return lbResponse; + } + + @Override + public PodResponse createPodResponse(Pod pod, Boolean showCapacities) { + String[] ipRange = new String[2]; + if (pod.getDescription() != null && pod.getDescription().length() > 0) { + ipRange = pod.getDescription().split("-"); + } else { + ipRange[0] = pod.getDescription(); + } + + PodResponse podResponse = new PodResponse(); + podResponse.setId(pod.getId()); + podResponse.setName(pod.getName()); + podResponse.setZoneId(pod.getDataCenterId()); + podResponse.setZoneName(PodZoneConfig.getZoneName(pod.getDataCenterId())); + podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize())); + podResponse.setStartIp(ipRange[0]); + podResponse.setEndIp(((ipRange.length > 1) && (ipRange[1] != null)) ? ipRange[1] : ""); + podResponse.setGateway(pod.getGateway()); + podResponse.setAllocationState(pod.getAllocationState().toString()); + if (showCapacities != null && showCapacities) { + List capacities = ApiDBUtils.getCapacityByClusterPodZone(null, pod.getId(), null); + Set capacityResponses = new HashSet(); + float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); + + for (SummedCapacity capacity : capacities) { + CapacityResponse capacityResponse = new CapacityResponse(); + capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { + capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); + } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { + List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null); + capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); + } else { + capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); + } + if (capacityResponse.getCapacityTotal() != 0) { + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + } else { + capacityResponse.setPercentUsed(s_percentFormat.format(0L)); + } + capacityResponses.add(capacityResponse); + } + // Do it for stats as well. + capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId())); + podResponse.setCapacitites(new ArrayList(capacityResponses)); + } + podResponse.setObjectName("pod"); + return podResponse; + } + + @Override + public ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities) { + Account account = UserContext.current().getCaller(); + ZoneResponse zoneResponse = new ZoneResponse(); + zoneResponse.setId(dataCenter.getId()); + zoneResponse.setName(dataCenter.getName()); + zoneResponse.setSecurityGroupsEnabled(ApiDBUtils.isSecurityGroupEnabledInZone(dataCenter.getId())); + + if ((dataCenter.getDescription() != null) && !dataCenter.getDescription().equalsIgnoreCase("null")) { + zoneResponse.setDescription(dataCenter.getDescription()); + } + + if ((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) { + zoneResponse.setDns1(dataCenter.getDns1()); + zoneResponse.setDns2(dataCenter.getDns2()); + zoneResponse.setInternalDns1(dataCenter.getInternalDns1()); + zoneResponse.setInternalDns2(dataCenter.getInternalDns2()); + // FIXME zoneResponse.setVlan(dataCenter.get.getVnet()); + zoneResponse.setGuestCidrAddress(dataCenter.getGuestNetworkCidr()); + } + + if (showCapacities != null && showCapacities) { + List capacities = ApiDBUtils.getCapacityByClusterPodZone(dataCenter.getId(), null, null); + Set capacityResponses = new HashSet(); + float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); + + for (SummedCapacity capacity : capacities) { + CapacityResponse capacityResponse = new CapacityResponse(); + capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { + capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); + } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { + List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(dataCenter.getId(), null, null); + capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); + } else { + capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); + } + if (capacityResponse.getCapacityTotal() != 0) { + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + } else { + capacityResponse.setPercentUsed(s_percentFormat.format(0L)); + } + capacityResponses.add(capacityResponse); + } + // Do it for stats as well. + capacityResponses.addAll(getStatsCapacityresponse(null, null, null, dataCenter.getId())); + + zoneResponse.setCapacitites(new ArrayList(capacityResponses)); + } + + // set network domain info + zoneResponse.setDomain(dataCenter.getDomain()); + + // set domain info + Long domainId = dataCenter.getDomainId(); + if (domainId != null) { + Domain domain = ApiDBUtils.findDomainById(domainId); + zoneResponse.setDomainId(domain.getId()); + zoneResponse.setDomainName(domain.getName()); + } + + zoneResponse.setType(dataCenter.getNetworkType().toString()); + zoneResponse.setAllocationState(dataCenter.getAllocationState().toString()); + zoneResponse.setZoneToken(dataCenter.getZoneToken()); + zoneResponse.setDhcpProvider(dataCenter.getDhcpProvider()); + zoneResponse.setObjectName("zone"); + return zoneResponse; + } + + private List getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) { + List capacities = new ArrayList(); + capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId)); + if (clusterId == null && podId == null) { + capacities.add(ApiDBUtils.getSecondaryStorageUsedStats(poolId, zoneId)); + } + + List capacityResponses = new ArrayList(); + for (CapacityVO capacity : capacities) { + CapacityResponse capacityResponse = new CapacityResponse(); + capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); + if (capacityResponse.getCapacityTotal() != 0) { + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + } else { + capacityResponse.setPercentUsed(s_percentFormat.format(0L)); + } + capacityResponses.add(capacityResponse); + } + + return capacityResponses; + } + + @Override + public VolumeResponse createVolumeResponse(Volume volume) { + VolumeResponse volResponse = new VolumeResponse(); + volResponse.setId(volume.getId()); + + if (volume.getName() != null) { + volResponse.setName(volume.getName()); + } else { + volResponse.setName(""); + } + + volResponse.setZoneId(volume.getDataCenterId()); + volResponse.setZoneName(ApiDBUtils.findZoneById(volume.getDataCenterId()).getName()); + + volResponse.setVolumeType(volume.getVolumeType().toString()); + volResponse.setDeviceId(volume.getDeviceId()); + + Long instanceId = volume.getInstanceId(); + if (instanceId != null && volume.getState() != Volume.State.Destroy) { + VMInstanceVO vm = ApiDBUtils.findVMInstanceById(instanceId); + if (vm != null) { + volResponse.setVirtualMachineId(vm.getId()); + volResponse.setVirtualMachineName(vm.getHostName()); + UserVm userVm = ApiDBUtils.findUserVmById(vm.getId()); + if (userVm != null) { + if (userVm.getDisplayName() != null) { + volResponse.setVirtualMachineDisplayName(userVm.getDisplayName()); + } else { + volResponse.setVirtualMachineDisplayName(userVm.getHostName()); + } + volResponse.setVirtualMachineState(vm.getState().toString()); + } else { + s_logger.error("User Vm with Id: " + instanceId + " does not exist for volume " + volume.getId()); + } + } else { + s_logger.error("Vm with Id: " + instanceId + " does not exist for volume " + volume.getId()); + } + } + + // Show the virtual size of the volume + volResponse.setSize(volume.getSize()); + + volResponse.setCreated(volume.getCreated()); + volResponse.setState(volume.getState().toString()); + if(volume.getState() == Volume.State.UploadOp){ + com.cloud.storage.VolumeHostVO volumeHostRef = ApiDBUtils.findVolumeHostRef(volume.getId(), volume.getDataCenterId()); + volResponse.setSize(volumeHostRef.getSize()); + 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()); + if (volumeHostRef.getDownloadState() != Status.DOWNLOADED) { + String volumeStatus = "Processing"; + if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { + if (volumeHostRef.getDownloadPercent() == 100) { + volumeStatus = "Checking Volume"; + } else { + volumeStatus = volumeHostRef.getDownloadPercent() + "% Uploaded"; + } + volResponse.setState("Uploading"); + } else { + volumeStatus = volumeHostRef.getErrorString(); + if(volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.NOT_DOWNLOADED){ + volResponse.setState("UploadNotStarted"); + }else { + volResponse.setState("UploadError"); + } + } + volResponse.setStatus(volumeStatus); + } else if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { + volResponse.setStatus("Upload Complete"); + volResponse.setState("Uploaded"); + } else { + volResponse.setStatus("Successfully Installed"); + } + } + + populateOwner(volResponse, volume); + + String storageType; + try { + if (volume.getPoolId() == null) { + if (volume.getState() == Volume.State.Allocated || volume.getState() == Volume.State.UploadOp) { + /* set it as shared, so the UI can attach it to VM */ + storageType = "shared"; + } else { + storageType = "unknown"; + } + } else { + storageType = ApiDBUtils.volumeIsOnSharedStorage(volume.getId()) ? ServiceOffering.StorageType.shared.toString() : ServiceOffering.StorageType.local.toString(); + } + } catch (InvalidParameterValueException e) { + s_logger.error(e.getMessage(), e); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Volume " + volume.getName() + " does not have a valid ID"); + } + + volResponse.setStorageType(storageType); + if (volume.getVolumeType().equals(Volume.Type.ROOT)) { + volResponse.setServiceOfferingId(volume.getDiskOfferingId()); + } else { + volResponse.setDiskOfferingId(volume.getDiskOfferingId()); + } + + DiskOfferingVO diskOffering = ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId()); + if (volume.getVolumeType().equals(Volume.Type.ROOT)) { + volResponse.setServiceOfferingName(diskOffering.getName()); + volResponse.setServiceOfferingDisplayText(diskOffering.getDisplayText()); + } else { + volResponse.setDiskOfferingName(diskOffering.getName()); + volResponse.setDiskOfferingDisplayText(diskOffering.getDisplayText()); + } + + Long poolId = volume.getPoolId(); + String poolName = (poolId == null) ? "none" : ApiDBUtils.findStoragePoolById(poolId).getName(); + volResponse.setStoragePoolName(poolName); + // volResponse.setSourceId(volume.getSourceId()); + // if (volume.getSourceType() != null) { + // volResponse.setSourceType(volume.getSourceType().toString()); + // } + + // return hypervisor for ROOT and Resource domain only + Account caller = UserContext.current().getCaller(); + if ((caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) && volume.getState() != Volume.State.UploadOp) { + volResponse.setHypervisor(ApiDBUtils.getVolumeHyperType(volume.getId()).toString()); + } + + volResponse.setAttached(volume.getAttached()); + 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; + } + } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Volume, volume.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + volResponse.setTags(tagResponses); + + volResponse.setExtractable(isExtractable); + volResponse.setObjectName("volume"); + return volResponse; + } + + @Override + public InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group) { + InstanceGroupResponse groupResponse = new InstanceGroupResponse(); + groupResponse.setId(group.getId()); + groupResponse.setName(group.getName()); + groupResponse.setCreated(group.getCreated()); + + populateOwner(groupResponse, group); + + groupResponse.setObjectName("instancegroup"); + return groupResponse; + } + + @Override + public StoragePoolResponse createStoragePoolResponse(StoragePool pool) { + StoragePoolResponse poolResponse = new StoragePoolResponse(); + poolResponse.setId(pool.getId()); + poolResponse.setName(pool.getName()); + poolResponse.setState(pool.getStatus()); + poolResponse.setPath(pool.getPath()); + poolResponse.setIpAddress(pool.getHostAddress()); + poolResponse.setZoneId(pool.getDataCenterId()); + poolResponse.setZoneName(ApiDBUtils.findZoneById(pool.getDataCenterId()).getName()); + if (pool.getPoolType() != null) { + poolResponse.setType(pool.getPoolType().toString()); + } + if (pool.getPodId() != null) { + poolResponse.setPodId(pool.getPodId()); + HostPodVO pod = ApiDBUtils.findPodById(pool.getPodId()); + if (pod != null) { + poolResponse.setPodName(pod.getName()); + } + } + if (pool.getCreated() != null) { + poolResponse.setCreated(pool.getCreated()); + } + + StorageStats stats = ApiDBUtils.getStoragePoolStatistics(pool.getId()); + long allocatedSize = ApiDBUtils.getStorageCapacitybyPool(pool.getId(), Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED); + poolResponse.setDiskSizeTotal(pool.getCapacityBytes()); + poolResponse.setDiskSizeAllocated(allocatedSize); + + if (stats != null) { + Long used = stats.getByteUsed(); + poolResponse.setDiskSizeUsed(used); + } + + if (pool.getClusterId() != null) { + ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId()); + poolResponse.setClusterId(cluster.getId()); + poolResponse.setClusterName(cluster.getName()); + } + poolResponse.setTags(ApiDBUtils.getStoragePoolTags(pool.getId())); + poolResponse.setObjectName("storagepool"); + return poolResponse; + } + + @Override + public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) { + ClusterResponse clusterResponse = new ClusterResponse(); + clusterResponse.setId(cluster.getId()); + clusterResponse.setName(cluster.getName()); + clusterResponse.setPodId(cluster.getPodId()); + clusterResponse.setZoneId(cluster.getDataCenterId()); + clusterResponse.setHypervisorType(cluster.getHypervisorType().toString()); + clusterResponse.setClusterType(cluster.getClusterType().toString()); + clusterResponse.setAllocationState(cluster.getAllocationState().toString()); + clusterResponse.setManagedState(cluster.getManagedState().toString()); + HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId()); + if (pod != null) { + clusterResponse.setPodName(pod.getName()); + } + DataCenterVO zone = ApiDBUtils.findZoneById(cluster.getDataCenterId()); + clusterResponse.setZoneName(zone.getName()); + if (showCapacities != null && showCapacities) { + List capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId()); + Set capacityResponses = new HashSet(); + float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); + + for (SummedCapacity capacity : capacities) { + CapacityResponse capacityResponse = new CapacityResponse(); + capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + + if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { + capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * cpuOverprovisioningFactor))); + } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { + List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId()); + capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); + } else { + capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); + } + if (capacityResponse.getCapacityTotal() != 0) { + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + } else { + capacityResponse.setPercentUsed(s_percentFormat.format(0L)); + } + capacityResponses.add(capacityResponse); + } + // Do it for stats as well. + capacityResponses.addAll(getStatsCapacityresponse(null, cluster.getId(), pod.getId(), pod.getDataCenterId())); + clusterResponse.setCapacitites(new ArrayList(capacityResponses)); + } + clusterResponse.setObjectName("cluster"); + return clusterResponse; + } + + @Override + public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule) { + FirewallRuleResponse response = new FirewallRuleResponse(); + response.setId(fwRule.getId()); + response.setPrivateStartPort(Integer.toString(fwRule.getDestinationPortStart())); + response.setPrivateEndPort(Integer.toString(fwRule.getDestinationPortEnd())); + response.setProtocol(fwRule.getProtocol()); + response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart())); + response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd())); + List cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId()); + response.setCidrList(StringUtils.join(cidrs, ",")); + + IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); + response.setPublicIpAddressId(ip.getId()); + response.setPublicIpAddress(ip.getAddress().addr()); + + if (ip != null && fwRule.getDestinationIpAddress() != null) { + UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId()); + if (vm != null) { + response.setVirtualMachineId(vm.getId()); + response.setVirtualMachineName(vm.getHostName()); + + if (vm.getDisplayName() != null) { + response.setVirtualMachineDisplayName(vm.getDisplayName()); + } else { + response.setVirtualMachineDisplayName(vm.getHostName()); + } + } + } + FirewallRule.State state = fwRule.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setState(stateToSet); + response.setObjectName("portforwardingrule"); + return response; + } + + @Override + public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule) { + IpForwardingRuleResponse response = new IpForwardingRuleResponse(); + response.setId(fwRule.getId()); + response.setProtocol(fwRule.getProtocol()); + + IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); + response.setPublicIpAddressId(ip.getId()); + response.setPublicIpAddress(ip.getAddress().addr()); + + if (ip != null && fwRule.getDestIpAddress() != null) { + UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId()); + if (vm != null) {// vm might be destroyed + response.setVirtualMachineId(vm.getId()); + response.setVirtualMachineName(vm.getHostName()); + if (vm.getDisplayName() != null) { + response.setVirtualMachineDisplayName(vm.getDisplayName()); + } else { + response.setVirtualMachineDisplayName(vm.getHostName()); + } + } + } + FirewallRule.State state = fwRule.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + + response.setStartPort(fwRule.getSourcePortStart()); + response.setEndPort(fwRule.getSourcePortEnd()); + response.setProtocol(fwRule.getProtocol()); + response.setState(stateToSet); + response.setObjectName("ipforwardingrule"); + return response; + } + + @Override + public List createUserVmResponse(String objectName, EnumSet details, UserVm... userVms) { + Account caller = UserContext.current().getCaller(); + Map dataCenters = new HashMap(); + Map hosts = new HashMap(); + Map templates = new HashMap(); + Map serviceOfferings = new HashMap(); + Map networks = new HashMap(); + + List vmResponses = new ArrayList(); + + for (UserVm userVm : userVms) { + UserVmResponse userVmResponse = new UserVmResponse(); + Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId())); + if (acct != null) { + userVmResponse.setAccountName(acct.getAccountName()); + userVmResponse.setDomainId(acct.getDomainId()); + userVmResponse.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName()); + } + + userVmResponse.setId(userVm.getId()); + userVmResponse.setName(userVm.getHostName()); + userVmResponse.setCreated(userVm.getCreated()); + + userVmResponse.setHaEnable(userVm.isHaEnabled()); + + if (userVm.getDisplayName() != null) { + userVmResponse.setDisplayName(userVm.getDisplayName()); + } else { + userVmResponse.setDisplayName(userVm.getHostName()); + } + + if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { + userVmResponse.setInstanceName(userVm.getInstanceName()); + } + + if (userVm.getPassword() != null) { + userVmResponse.setPassword(userVm.getPassword()); + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.group)) { + InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId()); + if (group != null) { + userVmResponse.setGroup(group.getName()); + userVmResponse.setGroupId(group.getId()); + } + + } + + // Data Center Info + DataCenter zone = dataCenters.get(userVm.getDataCenterIdToDeployIn()); + if (zone == null) { + zone = ApiDBUtils.findZoneById(userVm.getDataCenterIdToDeployIn()); + dataCenters.put(zone.getId(), zone); + } + + userVmResponse.setZoneId(zone.getId()); + userVmResponse.setZoneName(zone.getName()); + + // if user is an admin, display host id + if (((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)) && (userVm.getHostId() != null)) { + Host host = hosts.get(userVm.getHostId()); + + if (host == null) { + host = ApiDBUtils.findHostById(userVm.getHostId()); + hosts.put(host.getId(), host); + } + + userVmResponse.setHostId(host.getId()); + userVmResponse.setHostName(host.getName()); + } + + if (userVm.getState() != null) { + if (userVm.getHostId() != null) { + Host host = hosts.get(userVm.getHostId()); + + if (host == null) { + host = ApiDBUtils.findHostById(userVm.getHostId()); + hosts.put(host.getId(), host); + } + if (host.getStatus() != com.cloud.host.Status.Up) { + userVmResponse.setState(VirtualMachine.State.Unknown.toString()); + } else { + userVmResponse.setState(userVm.getState().toString()); + } + } else { + userVmResponse.setState(userVm.getState().toString()); + } + } + + 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()); + if (template == null) { + template = ApiDBUtils.findTemplateById(userVm.getTemplateId()); + if (template != null) { + templates.put(template.getId(), template); + } + } + + if (template != null) { + userVmResponse.setTemplateId(userVm.getTemplateId()); + userVmResponse.setTemplateName(template.getName()); + userVmResponse.setTemplateDisplayText(template.getDisplayText()); + userVmResponse.setPasswordEnabled(template.getEnablePassword()); + } else { + userVmResponse.setTemplateId(-1L); + userVmResponse.setTemplateName("ISO Boot"); + userVmResponse.setTemplateDisplayText("ISO Boot"); + userVmResponse.setPasswordEnabled(false); + } + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.iso)) { + // ISO Info + VMTemplateVO iso = templates.get(userVm.getIsoId()); + if (iso == null) { + iso = ApiDBUtils.findTemplateById(userVm.getIsoId()); + if (iso != null) { + templates.put(iso.getId(), iso); + } + } + + if (iso != null) { + userVmResponse.setIsoId(iso.getId()); + userVmResponse.setIsoName(iso.getName()); + } + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) { + // Service Offering Info + ServiceOffering offering = serviceOfferings.get(userVm.getServiceOfferingId()); + + if (offering == null) { + offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId()); + serviceOfferings.put(offering.getId(), offering); + } + + userVmResponse.setServiceOfferingId(offering.getId()); + userVmResponse.setServiceOfferingName(offering.getName()); + userVmResponse.setCpuNumber(offering.getCpu()); + userVmResponse.setCpuSpeed(offering.getSpeed()); + userVmResponse.setMemory(offering.getRamSize()); + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.volume)) { + VolumeVO rootVolume = ApiDBUtils.findRootVolume(userVm.getId()); + if (rootVolume != null) { + userVmResponse.setRootDeviceId(rootVolume.getDeviceId()); + String rootDeviceType = "Not created"; + if (rootVolume.getPoolId() != null) { + StoragePoolVO storagePool = ApiDBUtils.findStoragePoolById(rootVolume.getPoolId()); + rootDeviceType = storagePool.getPoolType().toString(); + } + userVmResponse.setRootDeviceType(rootDeviceType); + } + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.stats)) { + // stats calculation + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + String cpuUsed = null; + VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId()); + if (vmStats != null) { + float cpuUtil = (float) vmStats.getCPUUtilization(); + cpuUsed = decimalFormat.format(cpuUtil) + "%"; + userVmResponse.setCpuUsed(cpuUsed); + + Double networkKbRead = Double.valueOf(vmStats.getNetworkReadKBs()); + userVmResponse.setNetworkKbsRead(networkKbRead.longValue()); + + Double networkKbWrite = Double.valueOf(vmStats.getNetworkWriteKBs()); + userVmResponse.setNetworkKbsWrite(networkKbWrite.longValue()); + } + } + + userVmResponse.setGuestOsId(userVm.getGuestOSId()); + + if (details.contains(VMDetails.all) || details.contains(VMDetails.secgrp)) { + // security groups - list only when zone is security group enabled + if (zone.isSecurityGroupEnabled()) { + List securityGroups = ApiDBUtils.getSecurityGroupsForVm(userVm.getId()); + List securityGroupResponse = new ArrayList(); + for (SecurityGroupVO grp : securityGroups) { + SecurityGroupResponse resp = new SecurityGroupResponse(); + resp.setId(grp.getId()); + resp.setName(grp.getName()); + resp.setDescription(grp.getDescription()); + resp.setObjectName("securitygroup"); + securityGroupResponse.add(resp); + } + userVmResponse.setSecurityGroupList(securityGroupResponse); + } + } + + if (details.contains(VMDetails.all) || details.contains(VMDetails.nics)) { + List nicProfiles = ApiDBUtils.getNics(userVm); + List nicResponses = new ArrayList(); + for (NicProfile singleNicProfile : nicProfiles) { + NicResponse nicResponse = new NicResponse(); + nicResponse.setId(singleNicProfile.getId()); + nicResponse.setIpaddress(singleNicProfile.getIp4Address()); + nicResponse.setGateway(singleNicProfile.getGateway()); + nicResponse.setNetmask(singleNicProfile.getNetmask()); + nicResponse.setNetworkid(singleNicProfile.getNetworkId()); + if (acct.getType() == Account.ACCOUNT_TYPE_ADMIN) { + if (singleNicProfile.getBroadCastUri() != null) { + nicResponse.setBroadcastUri(singleNicProfile.getBroadCastUri().toString()); + } + if (singleNicProfile.getIsolationUri() != null) { + nicResponse.setIsolationUri(singleNicProfile.getIsolationUri().toString()); + } + } + + // Long networkId = singleNicProfile.getNetworkId(); + Network network = networks.get(singleNicProfile.getNetworkId()); + if (network == null) { + network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); + networks.put(singleNicProfile.getNetworkId(), network); + } + + nicResponse.setTrafficType(network.getTrafficType().toString()); + nicResponse.setType(network.getGuestType().toString()); + nicResponse.setIsDefault(singleNicProfile.isDefaultNic()); + nicResponse.setObjectName("nic"); + nicResponses.add(nicResponse); + } + userVmResponse.setNics(nicResponses); + } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVm.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + userVmResponse.setTags(tagResponses); + + IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(userVm.getId()); + if (ip != null) { + userVmResponse.setPublicIpId(ip.getId()); + userVmResponse.setPublicIp(ip.getAddress().addr()); + } + + userVmResponse.setObjectName(objectName); + vmResponses.add(userVmResponse); + } + + return vmResponses; + } + + @Override + public List createUserVmResponse(String objectName, UserVm... userVms) { + Account caller = UserContext.current().getCaller(); + boolean caller_is_admin = ((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)); + + Hashtable vmDataList = new Hashtable(); + // Initialise the vmdatalist with the input data + for (UserVm userVm : userVms) { + UserVmData userVmData = newUserVmData(userVm); + vmDataList.put(userVm.getId(), userVmData); + } + + vmDataList = ApiDBUtils.listVmDetails(vmDataList); + + // initialize vmresponse from vmdatalist + List vmResponses = new ArrayList(); + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + for (UserVmData uvd : vmDataList.values()) { + UserVmResponse userVmResponse = newUserVmResponse(uvd, caller_is_admin); + + // stats calculation + String cpuUsed = null; + // VmStats vmStats = ApiDBUtils.getVmStatistics(userVmResponse.getId()); + VmStats vmStats = ApiDBUtils.getVmStatistics(uvd.getId()); + if (vmStats != null) { + float cpuUtil = (float) vmStats.getCPUUtilization(); + cpuUsed = decimalFormat.format(cpuUtil) + "%"; + userVmResponse.setCpuUsed(cpuUsed); + + Double networkKbRead = Double.valueOf(vmStats.getNetworkReadKBs()); + userVmResponse.setNetworkKbsRead(networkKbRead.longValue()); + + Double networkKbWrite = Double.valueOf(vmStats.getNetworkWriteKBs()); + userVmResponse.setNetworkKbsWrite(networkKbWrite.longValue()); + } + userVmResponse.setObjectName(objectName); + + vmResponses.add(userVmResponse); + } + return vmResponses; + } + + @Override + public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) { + Account caller = UserContext.current().getCaller(); + Map serviceOfferings = new HashMap(); + + DomainRouterResponse routerResponse = new DomainRouterResponse(); + routerResponse.setId(router.getId()); + routerResponse.setZoneId(router.getDataCenterIdToDeployIn()); + routerResponse.setName(router.getHostName()); + routerResponse.setTemplateId(router.getTemplateId()); + routerResponse.setCreated(router.getCreated()); + routerResponse.setState(router.getState()); + routerResponse.setIsRedundantRouter(router.getIsRedundantRouter()); + routerResponse.setRedundantState(router.getRedundantState().toString()); + + if (caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { + if (router.getHostId() != null) { + routerResponse.setHostId(router.getHostId()); + routerResponse.setHostName(ApiDBUtils.findHostById(router.getHostId()).getName()); + } + routerResponse.setPodId(router.getPodIdToDeployIn()); + List nicProfiles = ApiDBUtils.getNics(router); + for (NicProfile singleNicProfile : nicProfiles) { + Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); + if (network != null) { + if (network.getTrafficType() == TrafficType.Public) { + routerResponse.setPublicIp(singleNicProfile.getIp4Address()); + routerResponse.setPublicMacAddress(singleNicProfile.getMacAddress()); + routerResponse.setPublicNetmask(singleNicProfile.getNetmask()); + routerResponse.setGateway(singleNicProfile.getGateway()); + routerResponse.setPublicNetworkId(singleNicProfile.getNetworkId()); + } else if (network.getTrafficType() == TrafficType.Control) { + routerResponse.setLinkLocalIp(singleNicProfile.getIp4Address()); + routerResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress()); + routerResponse.setLinkLocalNetmask(singleNicProfile.getNetmask()); + routerResponse.setLinkLocalNetworkId(singleNicProfile.getNetworkId()); + } else if (network.getTrafficType() == TrafficType.Guest) { + routerResponse.setGuestIpAddress(singleNicProfile.getIp4Address()); + routerResponse.setGuestMacAddress(singleNicProfile.getMacAddress()); + routerResponse.setGuestNetmask(singleNicProfile.getNetmask()); + routerResponse.setGuestNetworkId(singleNicProfile.getNetworkId()); + routerResponse.setNetworkDomain(network.getNetworkDomain()); + } + } + } + } + + // Service Offering Info + ServiceOffering offering = serviceOfferings.get(router.getServiceOfferingId()); + + if (offering == null) { + offering = ApiDBUtils.findServiceOfferingById(router.getServiceOfferingId()); + serviceOfferings.put(offering.getId(), offering); + } + routerResponse.setServiceOfferingId(offering.getId()); + routerResponse.setServiceOfferingName(offering.getName()); + + populateOwner(routerResponse, router); + + DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterIdToDeployIn()); + if (zone != null) { + routerResponse.setZoneName(zone.getName()); + routerResponse.setDns1(zone.getDns1()); + routerResponse.setDns2(zone.getDns2()); + } + + routerResponse.setVpcId(router.getVpcId()); + + routerResponse.setObjectName("domainrouter"); + return routerResponse; + } + + @Override + public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { + SystemVmResponse vmResponse = new SystemVmResponse(); + if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy) { + // SystemVm vm = (SystemVm) systemVM; + vmResponse.setId(vm.getId()); + vmResponse.setObjectId(vm.getId()); + vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); + vmResponse.setZoneId(vm.getDataCenterIdToDeployIn()); + + vmResponse.setName(vm.getHostName()); + vmResponse.setPodId(vm.getPodIdToDeployIn()); + vmResponse.setTemplateId(vm.getTemplateId()); + vmResponse.setCreated(vm.getCreated()); + + if (vm.getHostId() != null) { + vmResponse.setHostId(vm.getHostId()); + vmResponse.setHostName(ApiDBUtils.findHostById(vm.getHostId()).getName()); + } + + if (vm.getState() != null) { + vmResponse.setState(vm.getState().toString()); + } + + // for console proxies, add the active sessions + if (vm.getType() == Type.ConsoleProxy) { + ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId()); + // proxy can be already destroyed + if (proxy != null) { + vmResponse.setActiveViewerSessions(proxy.getActiveSession()); + } + } + + DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterIdToDeployIn()); + if (zone != null) { + vmResponse.setZoneName(zone.getName()); + vmResponse.setDns1(zone.getDns1()); + vmResponse.setDns2(zone.getDns2()); + } + + List nicProfiles = ApiDBUtils.getNics(vm); + for (NicProfile singleNicProfile : nicProfiles) { + Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId()); + if (network != null) { + if (network.getTrafficType() == TrafficType.Management) { + vmResponse.setPrivateIp(singleNicProfile.getIp4Address()); + vmResponse.setPrivateMacAddress(singleNicProfile.getMacAddress()); + vmResponse.setPrivateNetmask(singleNicProfile.getNetmask()); + } else if (network.getTrafficType() == TrafficType.Control) { + vmResponse.setLinkLocalIp(singleNicProfile.getIp4Address()); + vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress()); + vmResponse.setLinkLocalNetmask(singleNicProfile.getNetmask()); + } else if (network.getTrafficType() == TrafficType.Public || network.getTrafficType() == TrafficType.Guest) { + /*In basic zone, public ip has TrafficType.Guest*/ + vmResponse.setPublicIp(singleNicProfile.getIp4Address()); + vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress()); + vmResponse.setPublicNetmask(singleNicProfile.getNetmask()); + vmResponse.setGateway(singleNicProfile.getGateway()); + } + } + } + } + vmResponse.setObjectName("systemvm"); + return vmResponse; + } + + @Override + public Host findHostById(Long hostId) { + return ApiDBUtils.findHostById(hostId); + } + + @Override + public User findUserById(Long userId) { + return ApiDBUtils.findUserById(userId); + } + + @Override + public UserVm findUserVmById(Long vmId) { + return ApiDBUtils.findUserVmById(vmId); + + } + + @Override + public VolumeVO findVolumeById(Long volumeId) { + return ApiDBUtils.findVolumeById(volumeId); + } + + @Override + public Account findAccountByNameDomain(String accountName, Long domainId) { + return ApiDBUtils.findAccountByNameDomain(accountName, domainId); + } + + @Override + public VirtualMachineTemplate findTemplateById(Long templateId) { + return ApiDBUtils.findTemplateById(templateId); + } + + @Override + public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) { + VpnUsersResponse vpnResponse = new VpnUsersResponse(); + vpnResponse.setId(vpnUser.getId()); + vpnResponse.setUserName(vpnUser.getUsername()); + + populateOwner(vpnResponse, vpnUser); + + vpnResponse.setObjectName("vpnuser"); + return vpnResponse; + } + + @Override + public RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn) { + RemoteAccessVpnResponse vpnResponse = new RemoteAccessVpnResponse(); + vpnResponse.setPublicIpId(vpn.getServerAddressId()); + vpnResponse.setPublicIp(ApiDBUtils.findIpAddressById(vpn.getServerAddressId()).getAddress().addr()); + vpnResponse.setIpRange(vpn.getIpRange()); + vpnResponse.setPresharedKey(vpn.getIpsecPresharedKey()); + vpnResponse.setDomainId(vpn.getDomainId()); + + populateOwner(vpnResponse, vpn); + + vpnResponse.setState(vpn.getState().toString()); + vpnResponse.setObjectName("remoteaccessvpn"); + + return vpnResponse; + } + + @Override + public TemplateResponse createIsoResponse(VirtualMachineTemplate result) { + TemplateResponse response = new TemplateResponse(); + response.setId(result.getId()); + response.setName(result.getName()); + response.setDisplayText(result.getDisplayText()); + response.setPublic(result.isPublicTemplate()); + response.setCreated(result.getCreated()); + response.setFormat(result.getFormat()); + response.setOsTypeId(result.getGuestOSId()); + response.setOsTypeName(ApiDBUtils.findGuestOSById(result.getGuestOSId()).getDisplayName()); + response.setDetails(result.getDetails()); + Account caller = UserContext.current().getCaller(); + + if (result.getFormat() == ImageFormat.ISO) { // Templates are always bootable + response.setBootable(result.isBootable()); + } else { + response.setHypervisor(result.getHypervisorType().toString());// hypervisors are associated with templates + } + + // add account ID and name + Account owner = ApiDBUtils.findAccountById(result.getAccountId()); + populateAccount(response, owner.getId()); + populateDomain(response, owner.getDomainId()); + + //set tag information + List tags = null; + if (result.getFormat() == ImageFormat.ISO) { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, result.getId()); + } else { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, result.getId()); + } + + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setObjectName("iso"); + return response; + } + + @Override + public List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly) { + if (zoneId == null || zoneId == -1) { + List responses = new ArrayList(); + List dcs = new ArrayList(); + responses = createSwiftTemplateResponses(templateId); + if (!responses.isEmpty()) { + return responses; + } + dcs.addAll(ApiDBUtils.listZones()); + for (DataCenterVO dc : dcs) { + responses.addAll(createTemplateResponses(templateId, dc.getId(), readyOnly)); + } + return responses; + } else { + return createTemplateResponses(templateId, zoneId.longValue(), readyOnly); + } + } + + private List createSwiftTemplateResponses(long templateId) { + VirtualMachineTemplate template = findTemplateById(templateId); + List responses = new ArrayList(); + VMTemplateSwiftVO templateSwiftRef = ApiDBUtils.findTemplateSwiftRef(templateId); + if (templateSwiftRef == null) { + return responses; + } + + TemplateResponse templateResponse = new TemplateResponse(); + templateResponse.setId(template.getId()); + templateResponse.setName(template.getName()); + templateResponse.setDisplayText(template.getDisplayText()); + templateResponse.setPublic(template.isPublicTemplate()); + templateResponse.setCreated(templateSwiftRef.getCreated()); + + templateResponse.setReady(true); + templateResponse.setFeatured(template.isFeatured()); + templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); + templateResponse.setPasswordEnabled(template.getEnablePassword()); + templateResponse.setCrossZones(template.isCrossZones()); + templateResponse.setFormat(template.getFormat()); + templateResponse.setDetails(template.getDetails()); + if (template.getTemplateType() != null) { + templateResponse.setTemplateType(template.getTemplateType().toString()); + } + + templateResponse.setHypervisor(template.getHypervisorType().toString()); + + GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); + if (os != null) { + templateResponse.setOsTypeId(os.getId()); + templateResponse.setOsTypeName(os.getDisplayName()); + } else { + templateResponse.setOsTypeId(-1L); + templateResponse.setOsTypeName(""); + } + + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); + populateAccount(templateResponse, account.getId()); + populateDomain(templateResponse, account.getDomainId()); + + Account caller = UserContext.current().getCaller(); + boolean isAdmin = false; + if (BaseCmd.isAdmin(caller.getType())) { + isAdmin = true; + } + + // If the user is an Admin, add the template download status + if (isAdmin || caller.getId() == template.getAccountId()) { + // add download status + templateResponse.setStatus("Successfully Installed"); + } + + Long templateSize = templateSwiftRef.getSize(); + if (templateSize > 0) { + templateResponse.setSize(templateSize); + } + + templateResponse.setChecksum(template.getChecksum()); + templateResponse.setSourceTemplateId(template.getSourceTemplateId()); + + templateResponse.setChecksum(template.getChecksum()); + + templateResponse.setTemplateTag(template.getTemplateTag()); + + templateResponse.setObjectName("template"); + responses.add(templateResponse); + return responses; + } + + @Override + public List createTemplateResponses(long templateId, long zoneId, boolean readyOnly) { + VirtualMachineTemplate template = findTemplateById(templateId); + List responses = new ArrayList(); + VMTemplateHostVO templateHostRef = ApiDBUtils.findTemplateHostRef(templateId, zoneId, readyOnly); + if (templateHostRef == null) { + return responses; + } + + HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); + if (host.getType() == Host.Type.LocalSecondaryStorage && host.getStatus() != com.cloud.host.Status.Up) { + return responses; + } + + TemplateResponse templateResponse = new TemplateResponse(); + templateResponse.setId(template.getId()); + templateResponse.setName(template.getName()); + templateResponse.setDisplayText(template.getDisplayText()); + templateResponse.setPublic(template.isPublicTemplate()); + templateResponse.setCreated(templateHostRef.getCreated()); + + templateResponse.setReady(templateHostRef.getDownloadState() == Status.DOWNLOADED); + templateResponse.setFeatured(template.isFeatured()); + templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); + templateResponse.setPasswordEnabled(template.getEnablePassword()); + templateResponse.setCrossZones(template.isCrossZones()); + templateResponse.setFormat(template.getFormat()); + if (template.getTemplateType() != null) { + templateResponse.setTemplateType(template.getTemplateType().toString()); + } + + templateResponse.setHypervisor(template.getHypervisorType().toString()); + templateResponse.setDetails(template.getDetails()); + + GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); + if (os != null) { + templateResponse.setOsTypeId(os.getId()); + templateResponse.setOsTypeName(os.getDisplayName()); + } else { + templateResponse.setOsTypeId(-1L); + templateResponse.setOsTypeName(""); + } + + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); + populateAccount(templateResponse, account.getId()); + populateDomain(templateResponse, account.getDomainId()); + + DataCenterVO datacenter = ApiDBUtils.findZoneById(zoneId); + + // Add the zone ID + templateResponse.setZoneId(zoneId); + templateResponse.setZoneName(datacenter.getName()); + + boolean isAdmin = false; + Account caller = UserContext.current().getCaller(); + if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { + isAdmin = true; + } + + // If the user is an Admin, add the template download status + if (isAdmin || caller.getId() == template.getAccountId()) { + // add download status + if (templateHostRef.getDownloadState() != Status.DOWNLOADED) { + String templateStatus = "Processing"; + if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { + if (templateHostRef.getDownloadPercent() == 100) { + templateStatus = "Installing Template"; + } else { + templateStatus = templateHostRef.getDownloadPercent() + "% Downloaded"; + } + } else { + templateStatus = templateHostRef.getErrorString(); + } + templateResponse.setStatus(templateStatus); + } else if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { + templateResponse.setStatus("Download Complete"); + } else { + templateResponse.setStatus("Successfully Installed"); + } + } + + Long templateSize = templateHostRef.getSize(); + if (templateSize > 0) { + templateResponse.setSize(templateSize); + } + + templateResponse.setChecksum(template.getChecksum()); + templateResponse.setSourceTemplateId(template.getSourceTemplateId()); + + templateResponse.setChecksum(template.getChecksum()); + + templateResponse.setTemplateTag(template.getTemplateTag()); + + //set tag information + List tags = null; + if (template.getFormat() == ImageFormat.ISO) { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, template.getId()); + } else { + tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, template.getId()); + } + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + templateResponse.setTags(tagResponses); + + templateResponse.setObjectName("template"); + responses.add(templateResponse); + return responses; + } + + @Override + public List createIsoResponses(long isoId, Long zoneId, boolean readyOnly) { + + List isoResponses = new ArrayList(); + VirtualMachineTemplate iso = findTemplateById(isoId); + if (iso.getTemplateType() == TemplateType.PERHOST) { + TemplateResponse isoResponse = new TemplateResponse(); + isoResponse.setId(iso.getId()); + isoResponse.setName(iso.getName()); + isoResponse.setDisplayText(iso.getDisplayText()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); + isoResponse.setReady(true); + isoResponse.setBootable(iso.isBootable()); + isoResponse.setFeatured(iso.isFeatured()); + isoResponse.setCrossZones(iso.isCrossZones()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setCreated(iso.getCreated()); + isoResponse.setChecksum(iso.getChecksum()); + isoResponse.setPasswordEnabled(false); + isoResponse.setDetails(iso.getDetails()); + + // add account ID and name + Account owner = ApiDBUtils.findAccountById(iso.getAccountId()); + populateAccount(isoResponse, owner.getId()); + populateDomain(isoResponse, owner.getDomainId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + isoResponse.setTags(tagResponses); + + isoResponse.setObjectName("iso"); + isoResponses.add(isoResponse); + return isoResponses; + } else { + if (zoneId == null || zoneId == -1) { + isoResponses = createSwiftIsoResponses(iso); + if (!isoResponses.isEmpty()) { + return isoResponses; + } + List dcs = new ArrayList(); + dcs.addAll(ApiDBUtils.listZones()); + for (DataCenterVO dc : dcs) { + isoResponses.addAll(createIsoResponses(iso, dc.getId(), readyOnly)); + } + return isoResponses; + } else { + return createIsoResponses(iso, zoneId, readyOnly); + } + } + } + + private List createSwiftIsoResponses(VirtualMachineTemplate iso) { + long isoId = iso.getId(); + List isoResponses = new ArrayList(); + VMTemplateSwiftVO isoSwift = ApiDBUtils.findTemplateSwiftRef(isoId); + if (isoSwift == null) { + return isoResponses; + } + TemplateResponse isoResponse = new TemplateResponse(); + isoResponse.setId(iso.getId()); + isoResponse.setName(iso.getName()); + isoResponse.setDisplayText(iso.getDisplayText()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); + isoResponse.setCreated(isoSwift.getCreated()); + isoResponse.setReady(true); + isoResponse.setBootable(iso.isBootable()); + isoResponse.setFeatured(iso.isFeatured()); + isoResponse.setCrossZones(iso.isCrossZones()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setChecksum(iso.getChecksum()); + isoResponse.setDetails(iso.getDetails()); + + // TODO: implement + GuestOS os = ApiDBUtils.findGuestOSById(iso.getGuestOSId()); + if (os != null) { + isoResponse.setOsTypeId(os.getId()); + isoResponse.setOsTypeName(os.getDisplayName()); + } else { + isoResponse.setOsTypeId(-1L); + isoResponse.setOsTypeName(""); + } + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId()); + populateAccount(isoResponse, account.getId()); + populateDomain(isoResponse, account.getDomainId()); + boolean isAdmin = false; + if ((account == null) || BaseCmd.isAdmin(account.getType())) { + isAdmin = true; + } + + // If the user is an admin, add the template download status + if (isAdmin || account.getId() == iso.getAccountId()) { + // add download status + isoResponse.setStatus("Successfully Installed"); + } + Long isoSize = isoSwift.getSize(); + if (isoSize > 0) { + isoResponse.setSize(isoSize); + } + isoResponse.setObjectName("iso"); + isoResponses.add(isoResponse); + return isoResponses; + } + + @Override + public List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly) { + long isoId = iso.getId(); + List isoResponses = new ArrayList(); + VMTemplateHostVO isoHost = ApiDBUtils.findTemplateHostRef(isoId, zoneId, readyOnly); + if (isoHost == null) { + return isoResponses; + } + TemplateResponse isoResponse = new TemplateResponse(); + isoResponse.setId(iso.getId()); + isoResponse.setName(iso.getName()); + isoResponse.setDisplayText(iso.getDisplayText()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); + isoResponse.setCreated(isoHost.getCreated()); + isoResponse.setReady(isoHost.getDownloadState() == Status.DOWNLOADED); + isoResponse.setBootable(iso.isBootable()); + isoResponse.setFeatured(iso.isFeatured()); + isoResponse.setCrossZones(iso.isCrossZones()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setChecksum(iso.getChecksum()); + isoResponse.setDetails(iso.getDetails()); + + // TODO: implement + GuestOS os = ApiDBUtils.findGuestOSById(iso.getGuestOSId()); + if (os != null) { + isoResponse.setOsTypeId(os.getId()); + isoResponse.setOsTypeName(os.getDisplayName()); + } else { + isoResponse.setOsTypeId(-1L); + isoResponse.setOsTypeName(""); + } + + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId()); + populateAccount(isoResponse, account.getId()); + populateDomain(isoResponse, account.getDomainId()); + + Account caller = UserContext.current().getCaller(); + boolean isAdmin = false; + if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { + isAdmin = true; + } + // Add the zone ID + DataCenterVO datacenter = ApiDBUtils.findZoneById(zoneId); + isoResponse.setZoneId(zoneId); + isoResponse.setZoneName(datacenter.getName()); + + // If the user is an admin, add the template download status + if (isAdmin || caller.getId() == iso.getAccountId()) { + // add download status + if (isoHost.getDownloadState() != Status.DOWNLOADED) { + String isoStatus = "Processing"; + if (isoHost.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { + isoStatus = "Download Complete"; + } else if (isoHost.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { + if (isoHost.getDownloadPercent() == 100) { + isoStatus = "Installing ISO"; + } else { + isoStatus = isoHost.getDownloadPercent() + "% Downloaded"; + } + } else { + isoStatus = isoHost.getErrorString(); + } + isoResponse.setStatus(isoStatus); + } else { + isoResponse.setStatus("Successfully Installed"); + } + } + + Long isoSize = isoHost.getSize(); + if (isoSize > 0) { + isoResponse.setSize(isoSize); + } + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + isoResponse.setTags(tagResponses); + + isoResponse.setObjectName("iso"); + isoResponses.add(isoResponse); + return isoResponses; + } + + @Override + public ListResponse createSecurityGroupResponses( + List networkGroups) { + List groupResultObjs = SecurityGroupResultObject + .transposeNetworkGroups(networkGroups); + + ListResponse response = new ListResponse(); + List netGrpResponses = new ArrayList(); + for (SecurityGroupResultObject networkGroup : groupResultObjs) { + SecurityGroupResponse netGrpResponse = new SecurityGroupResponse(); + netGrpResponse.setId(networkGroup.getId()); + netGrpResponse.setName(networkGroup.getName()); + netGrpResponse.setDescription(networkGroup.getDescription()); + + populateOwner(netGrpResponse, networkGroup); + + List securityGroupRules = networkGroup + .getSecurityGroupRules(); + if ((securityGroupRules != null) && !securityGroupRules.isEmpty()) { + List ingressRulesResponse = new ArrayList(); + List egressRulesResponse = new ArrayList(); + for (SecurityGroupRuleResultObject securityGroupRule : securityGroupRules) { + SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); + ruleData.setRuleId(securityGroupRule.getId()); + ruleData.setProtocol(securityGroupRule.getProtocol()); + + if ("icmp".equalsIgnoreCase(securityGroupRule.getProtocol())) { + ruleData.setIcmpType(securityGroupRule.getStartPort()); + ruleData.setIcmpCode(securityGroupRule.getEndPort()); + } else { + ruleData.setStartPort(securityGroupRule.getStartPort()); + ruleData.setEndPort(securityGroupRule.getEndPort()); + } + + if (securityGroupRule.getAllowedSecurityGroup() != null) { + ruleData.setSecurityGroupName(securityGroupRule + .getAllowedSecurityGroup()); + ruleData.setAccountName(securityGroupRule + .getAllowedSecGroupAcct()); + } else { + ruleData.setCidr(securityGroupRule + .getAllowedSourceIpCidr()); + } + + if (securityGroupRule.getRuleType() == SecurityRuleType.IngressRule) { + ruleData.setObjectName("ingressrule"); + ingressRulesResponse.add(ruleData); + } else { + ruleData.setObjectName("egressrule"); + egressRulesResponse.add(ruleData); + } + } + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, networkGroup.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + netGrpResponse.setTags(tagResponses); + + netGrpResponse + .setSecurityGroupIngressRules(ingressRulesResponse); + netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); + } + netGrpResponse.setObjectName("securitygroup"); + netGrpResponses.add(netGrpResponse); + } + + response.setResponses(netGrpResponses); + return response; + } + + @Override + public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) { + SecurityGroupResponse response = new SecurityGroupResponse(); + + populateOwner(response, group); + + response.setDescription(group.getDescription()); + response.setId(group.getId()); + response.setName(group.getName()); + + response.setObjectName("securitygroup"); + return response; + + } + + @Override + public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode) { + UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId); + ExtractResponse response = new ExtractResponse(); + response.setObjectName("template"); + response.setId(id); + response.setName(ApiDBUtils.findTemplateById(id).getName()); + if (zoneId != null) { + response.setZoneId(zoneId); + response.setZoneName(ApiDBUtils.findZoneById(zoneId).getName()); + } + response.setMode(mode); + response.setUploadId(uploadId); + response.setState(uploadInfo.getUploadState().toString()); + response.setAccountId(accountId); + response.setUrl(uploadInfo.getUploadUrl()); + return response; + + } + + @Override + public String toSerializedString(CreateCmdResponse response, String responseType) { + return ApiResponseSerializer.toSerializedString(response, responseType); + } + + @Override + public AsyncJobResponse createAsyncJobResponse(AsyncJob job) { + AsyncJobResponse jobResponse = new AsyncJobResponse(); + jobResponse.setAccountId(job.getAccountId()); + jobResponse.setUserId(job.getUserId()); + jobResponse.setCmd(job.getCmd()); + jobResponse.setCreated(job.getCreated()); + jobResponse.setJobId(job.getId()); + jobResponse.setJobStatus(job.getStatus()); + jobResponse.setJobProcStatus(job.getProcessStatus()); + + if (job.getInstanceType() != null && job.getInstanceId() != null) { + jobResponse.setJobInstanceType(job.getInstanceType().toString()); + jobResponse.setJobInstanceId(job.getInstanceId()); + } + jobResponse.setJobResultCode(job.getResultCode()); + + boolean savedValue = SerializationContext.current().getUuidTranslation(); + SerializationContext.current().setUuidTranslation(false); + + 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) { + jobResponse.setJobResultType("text"); + } else { + jobResponse.setJobResultType("object"); + } + } + + jobResponse.setObjectName("asyncjobs"); + return jobResponse; + } + + @Override + public List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly) { + VolumeVO volume = null; + if (snapshotId != null) { + Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId); + volume = findVolumeById(snapshot.getVolumeId()); + } else { + volume = findVolumeById(volumeId); + } + return createTemplateResponses(templateId, volume.getDataCenterId(), readyOnly); + } + + @Override + public List createTemplateResponses(long templateId, Long vmId) { + UserVm vm = findUserVmById(vmId); + Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()); + Host host = findHostById(hostId); + return createTemplateResponses(templateId, host.getDataCenterId(), true); + } + + @Override + public EventResponse createEventResponse(Event event) { + EventResponse responseEvent = new EventResponse(); + responseEvent.setCreated(event.getCreateDate()); + responseEvent.setDescription(event.getDescription()); + responseEvent.setEventType(event.getType()); + responseEvent.setId(event.getId()); + responseEvent.setLevel(event.getLevel()); + responseEvent.setParentId(event.getStartId()); + responseEvent.setState(event.getState()); + + populateOwner(responseEvent, event); + + User user = ApiDBUtils.findUserById(event.getUserId()); + if (user != null) { + responseEvent.setUsername(user.getUsername()); + } + + responseEvent.setObjectName("event"); + return responseEvent; + } + + private List sumCapacities(List hostCapacities) { + Map totalCapacityMap = new HashMap(); + Map usedCapacityMap = new HashMap(); + + Set poolIdsToIgnore = new HashSet(); + Criteria c = new Criteria(); + // TODO: implement + List allStoragePools = ApiDBUtils.searchForStoragePools(c); + for (StoragePoolVO pool : allStoragePools) { + StoragePoolType poolType = pool.getPoolType(); + if (!(poolType.isShared())) {// All the non shared storages shouldn't show up in the capacity calculation + poolIdsToIgnore.add(pool.getId()); + } + } + + float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); + + // collect all the capacity types, sum allocated/used and sum total...get one capacity number for each + for (Capacity capacity : hostCapacities) { + + // check if zone exist + DataCenter zone = ApiDBUtils.findZoneById(capacity.getDataCenterId()); + if (zone == null) { + continue; + } + + short capacityType = capacity.getCapacityType(); + + // If local storage then ignore + if ((capacityType == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED || capacityType == Capacity.CAPACITY_TYPE_STORAGE) + && poolIdsToIgnore.contains(capacity.getHostOrPoolId())) { + continue; + } + + String key = capacity.getCapacityType() + "_" + capacity.getDataCenterId(); + String keyForPodTotal = key + "_-1"; + + boolean sumPodCapacity = false; + if (capacity.getPodId() != null) { + key += "_" + capacity.getPodId(); + sumPodCapacity = true; + } + + Long totalCapacity = totalCapacityMap.get(key); + Long usedCapacity = usedCapacityMap.get(key); + + // reset overprovisioning factor to 1 + float overprovisioningFactor = 1; + if (capacityType == Capacity.CAPACITY_TYPE_CPU) { + overprovisioningFactor = cpuOverprovisioningFactor; + } + + if (totalCapacity == null) { + totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)); + } else { + totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)) + totalCapacity; + } + + if (usedCapacity == null) { + usedCapacity = new Long(capacity.getUsedCapacity()); + } else { + usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity); + } + + if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved + // Capacity + // accounts +// for + // stopped +// vms + // that +// have been + // stopped +// within + // an +// interval + usedCapacity += capacity.getReservedCapacity(); + } + + totalCapacityMap.put(key, totalCapacity); + usedCapacityMap.put(key, usedCapacity); + + if (sumPodCapacity) { + totalCapacity = totalCapacityMap.get(keyForPodTotal); + usedCapacity = usedCapacityMap.get(keyForPodTotal); + + overprovisioningFactor = 1; + if (capacityType == Capacity.CAPACITY_TYPE_CPU) { + overprovisioningFactor = cpuOverprovisioningFactor; + } + + if (totalCapacity == null) { + totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)); + } else { + totalCapacity = new Long((long) (capacity.getTotalCapacity() * overprovisioningFactor)) + totalCapacity; + } + + if (usedCapacity == null) { + usedCapacity = new Long(capacity.getUsedCapacity()); + } else { + usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity); + } + + if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved + // Capacity + // accounts + // for + // stopped + // vms +// that + // have +// been + // stopped + // within +// an + // interval + usedCapacity += capacity.getReservedCapacity(); + } + + totalCapacityMap.put(keyForPodTotal, totalCapacity); + usedCapacityMap.put(keyForPodTotal, usedCapacity); + } + } + + List summedCapacities = new ArrayList(); + for (String key : totalCapacityMap.keySet()) { + CapacityVO summedCapacity = new CapacityVO(); + + StringTokenizer st = new StringTokenizer(key, "_"); + summedCapacity.setCapacityType(Short.parseShort(st.nextToken())); + summedCapacity.setDataCenterId(Long.parseLong(st.nextToken())); + if (st.hasMoreTokens()) { + summedCapacity.setPodId(Long.parseLong(st.nextToken())); + } + + summedCapacity.setTotalCapacity(totalCapacityMap.get(key)); + summedCapacity.setUsedCapacity(usedCapacityMap.get(key)); + + summedCapacities.add(summedCapacity); + } + return summedCapacities; + } + + @Override + public List createCapacityResponse(List result, DecimalFormat format) { + List capacityResponses = new ArrayList(); + + for (Capacity summedCapacity : result) { + CapacityResponse capacityResponse = new CapacityResponse(); + capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity()); + capacityResponse.setCapacityType(summedCapacity.getCapacityType()); + capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity()); + if (summedCapacity.getPodId() != null) { + capacityResponse.setPodId(summedCapacity.getPodId()); + HostPodVO pod = ApiDBUtils.findPodById(summedCapacity.getPodId()); + if (pod != null) { + capacityResponse.setPodName(pod.getName()); + } + } + if (summedCapacity.getClusterId() != null) { + capacityResponse.setClusterId(summedCapacity.getClusterId()); + ClusterVO cluster = ApiDBUtils.findClusterById(summedCapacity.getClusterId()); + if (cluster != null) { + capacityResponse.setClusterName(cluster.getName()); + if (summedCapacity.getPodId() == null) { + long podId = cluster.getPodId(); + capacityResponse.setPodId(podId); + capacityResponse.setPodName(ApiDBUtils.findPodById(podId).getName()); + } + } + } + capacityResponse.setZoneId(summedCapacity.getDataCenterId()); + capacityResponse.setZoneName(ApiDBUtils.findZoneById(summedCapacity.getDataCenterId()).getName()); + if (summedCapacity.getUsedPercentage() != null){ + capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f)); + } else if (summedCapacity.getTotalCapacity() != 0) { + capacityResponse.setPercentUsed(format.format((float) summedCapacity.getUsedCapacity() / (float) summedCapacity.getTotalCapacity() * 100f)); + } else { + capacityResponse.setPercentUsed(format.format(0L)); + } + + capacityResponse.setObjectName("capacity"); + capacityResponses.add(capacityResponse); + } + + return capacityResponses; + } + + @Override + public TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin) { + Long templateOwnerDomain = null; + VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id); + Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId()); + if (isAdmin) { + // FIXME: we have just template id and need to get template owner from that + if (templateOwner != null) { + templateOwnerDomain = templateOwner.getDomainId(); + } + } + + TemplatePermissionsResponse response = new TemplatePermissionsResponse(); + response.setId(template.getId()); + response.setPublicTemplate(template.isPublicTemplate()); + if (isAdmin && (templateOwnerDomain != null)) { + response.setDomainId(templateOwnerDomain); + } + + // Set accounts + List projectIds = new ArrayList(); + List regularAccounts = new ArrayList(); + for (String accountName : accountNames) { + Account account = ApiDBUtils.findAccountByNameDomain(accountName, templateOwner.getDomainId()); + if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) { + regularAccounts.add(accountName); + } else { + // convert account to projectIds + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + + if (project.getUuid() != null && !project.getUuid().isEmpty()) + projectIds.add(project.getUuid()); + else + projectIds.add(String.valueOf(project.getId())); + } + } + + if (!projectIds.isEmpty()) { + response.setProjectIds(projectIds); + } + + if (!regularAccounts.isEmpty()) { + response.setAccountNames(regularAccounts); + } + + response.setObjectName("templatepermission"); + return response; + } + + @Override + public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) { + AsyncJob result = ApiDBUtils._asyncMgr.queryAsyncJobResult(cmd); + return createAsyncJobResponse(result); + } + + @Override + public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { + SecurityGroupResponse response = new SecurityGroupResponse(); + Map securiytGroupAccounts = new HashMap(); + Map allowedSecurityGroups = new HashMap(); + Map allowedSecuriytGroupAccounts = new HashMap(); + + if ((securityRules != null) && !securityRules.isEmpty()) { + SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(securityRules.get(0).getSecurityGroupId()); + response.setId(securityGroup.getId()); + response.setName(securityGroup.getName()); + response.setDescription(securityGroup.getDescription()); + + Account account = securiytGroupAccounts.get(securityGroup.getAccountId()); + + if (account == null) { + account = ApiDBUtils.findAccountById(securityGroup.getAccountId()); + securiytGroupAccounts.put(securityGroup.getAccountId(), account); + } + + populateAccount(response, account.getId()); + populateDomain(response, account.getDomainId()); + + List egressResponses = new ArrayList(); + List ingressResponses = new ArrayList(); + for (SecurityRule securityRule : securityRules) { + SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse(); + + securityGroupData.setRuleId(securityRule.getId()); + securityGroupData.setProtocol(securityRule.getProtocol()); + if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) { + securityGroupData.setIcmpType(securityRule.getStartPort()); + securityGroupData.setIcmpCode(securityRule.getEndPort()); + } else { + securityGroupData.setStartPort(securityRule.getStartPort()); + securityGroupData.setEndPort(securityRule.getEndPort()); + } + + Long allowedSecurityGroupId = securityRule.getAllowedNetworkId(); + if (allowedSecurityGroupId != null) { + SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); + if (allowedSecurityGroup == null) { + allowedSecurityGroup = ApiDBUtils.findSecurityGroupById(allowedSecurityGroupId); + allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); + } + + securityGroupData.setSecurityGroupName(allowedSecurityGroup.getName()); + + Account allowedAccount = allowedSecuriytGroupAccounts.get(allowedSecurityGroup.getAccountId()); + if (allowedAccount == null) { + allowedAccount = ApiDBUtils.findAccountById(allowedSecurityGroup.getAccountId()); + allowedSecuriytGroupAccounts.put(allowedAccount.getId(), allowedAccount); + } + + securityGroupData.setAccountName(allowedAccount.getAccountName()); + } else { + securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr()); + } + if (securityRule.getRuleType() == SecurityRuleType.IngressRule) { + securityGroupData.setObjectName("ingressrule"); + ingressResponses.add(securityGroupData); + } else { + securityGroupData.setObjectName("egressrule"); + egressResponses.add(securityGroupData); + } + + } + response.setSecurityGroupIngressRules(ingressResponses); + response.setSecurityGroupEgressRules(egressResponses); + response.setObjectName("securitygroup"); + + } + return response; + } + + @Override + public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) { + NetworkOfferingResponse response = new NetworkOfferingResponse(); + response.setId(offering.getId()); + response.setName(offering.getName()); + response.setDisplayText(offering.getDisplayText()); + response.setTags(offering.getTags()); + response.setTrafficType(offering.getTrafficType().toString()); + response.setIsDefault(offering.isDefault()); + response.setSpecifyVlan(offering.getSpecifyVlan()); + response.setConserveMode(offering.isConserveMode()); + response.setSpecifyIpRanges(offering.getSpecifyIpRanges()); + response.setAvailability(offering.getAvailability().toString()); + response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId())); + if (offering.getServiceOfferingId() != null) { + response.setServiceOfferingId(offering.getServiceOfferingId()); + } else { + response.setServiceOfferingId(ApiDBUtils.findDefaultRouterServiceOffering()); + } + if (offering.getGuestType() != null) { + response.setGuestIpType(offering.getGuestType().toString()); + } + + response.setState(offering.getState().name()); + + Map> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + if (Service.Lb == service) { + List lbCapResponse = new ArrayList(); + + CapabilityResponse lbIsoaltion = new CapabilityResponse(); + lbIsoaltion.setName(Capability.SupportedLBIsolation.getName()); + lbIsoaltion.setValue(offering.getDedicatedLB() ? "dedicated" : "shared"); + lbCapResponse.add(lbIsoaltion); + + CapabilityResponse eLb = new CapabilityResponse(); + eLb.setName(Capability.ElasticLb.getName()); + eLb.setValue(offering.getElasticLb() ? "true" : "false"); + lbCapResponse.add(eLb); + + svcRsp.setCapabilities(lbCapResponse); + } else if (Service.SourceNat == service) { + List capabilities = new ArrayList(); + CapabilityResponse sharedSourceNat = new CapabilityResponse(); + sharedSourceNat.setName(Capability.SupportedSourceNatTypes.getName()); + sharedSourceNat.setValue(offering.getSharedSourceNat() ? "perzone" : "peraccount"); + capabilities.add(sharedSourceNat); + + CapabilityResponse redundantRouter = new CapabilityResponse(); + redundantRouter.setName(Capability.RedundantRouter.getName()); + redundantRouter.setValue(offering.getRedundantRouter() ? "true" : "false"); + capabilities.add(redundantRouter); + + svcRsp.setCapabilities(capabilities); + } else if (service == Service.StaticNat) { + List staticNatCapResponse = new ArrayList(); + + CapabilityResponse eIp = new CapabilityResponse(); + eIp.setName(Capability.ElasticIp.getName()); + eIp.setValue(offering.getElasticLb() ? "true" : "false"); + staticNatCapResponse.add(eIp); + + svcRsp.setCapabilities(staticNatCapResponse); + } + + serviceResponses.add(svcRsp); + } + response.setForVpc(ApiDBUtils.isOfferingForVpc(offering)); + + response.setServices(serviceResponses); + response.setObjectName("networkoffering"); + return response; + } + + @Override + public NetworkResponse createNetworkResponse(Network network) { + // need to get network profile in order to retrieve dns information from there + NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId()); + NetworkResponse response = new NetworkResponse(); + response.setId(network.getId()); + response.setName(network.getName()); + response.setDisplaytext(network.getDisplayText()); + if (network.getBroadcastDomainType() != null) { + response.setBroadcastDomainType(network.getBroadcastDomainType().toString()); + } + + if (network.getTrafficType() != null) { + response.setTrafficType(network.getTrafficType().name()); + } + + if (network.getGuestType() != null) { + response.setType(network.getGuestType().toString()); + } + + response.setGateway(network.getGateway()); + + // FIXME - either set netmask or cidr + response.setCidr(network.getCidr()); + if (network.getCidr() != null) { + response.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); + } + + if (network.getBroadcastUri() != null) { + String broadcastUri = network.getBroadcastUri().toString(); + response.setBroadcastUri(broadcastUri); + String vlan="N/A"; + if (broadcastUri.startsWith("vlan")) { + vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); + } + response.setVlan(vlan); + } + + DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId()); + response.setZoneId(network.getDataCenterId()); + response.setZoneName(zone.getName()); + response.setPhysicalNetworkId(network.getPhysicalNetworkId()); + + // populate network offering information + NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId()); + if (networkOffering != null) { + response.setNetworkOfferingId(networkOffering.getId()); + response.setNetworkOfferingName(networkOffering.getName()); + response.setNetworkOfferingDisplayText(networkOffering.getDisplayText()); + response.setIsSystem(networkOffering.isSystemOnly()); + response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString()); + } + + if (network.getAclType() != null) { + response.setAclType(network.getAclType().toString()); + } + response.setState(network.getState().toString()); + response.setRestartRequired(network.isRestartRequired()); + response.setRelated(network.getRelated()); + response.setNetworkDomain(network.getNetworkDomain()); + + response.setDns1(profile.getDns1()); + response.setDns2(profile.getDns2()); + // populate capability + Map> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId()); + List serviceResponses = new ArrayList(); + if (serviceCapabilitiesMap != null) { + for (Service service : serviceCapabilitiesMap.keySet()) { + ServiceResponse serviceResponse = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + serviceResponse.setName(service.getName()); + + // set list of capabilities for the service + List capabilityResponses = new ArrayList(); + Map serviceCapabilities = serviceCapabilitiesMap.get(service); + if (serviceCapabilities != null) { + for (Capability capability : serviceCapabilities.keySet()) { + CapabilityResponse capabilityResponse = new CapabilityResponse(); + String capabilityValue = serviceCapabilities.get(capability); + capabilityResponse.setName(capability.getName()); + capabilityResponse.setValue(capabilityValue); + capabilityResponse.setObjectName("capability"); + capabilityResponses.add(capabilityResponse); + } + serviceResponse.setCapabilities(capabilityResponses); + } + + serviceResponse.setObjectName("service"); + serviceResponses.add(serviceResponse); + } + } + response.setServices(serviceResponses); + + if (network.getAclType() == null || network.getAclType() == ACLType.Account) { + populateOwner(response, network); + } else { + // get domain from network_domain table + Pair domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId()); + response.setDomainId(domainNetworkDetails.first()); + response.setSubdomainAccess(domainNetworkDetails.second()); + } + + Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId()); + if (dedicatedDomainId != null) { + Domain domain = ApiDBUtils.findDomainById(dedicatedDomainId); + response.setDomainId(dedicatedDomainId); + response.setDomainName(domain.getName()); + } + + response.setSpecifyIpRanges(network.getSpecifyIpRanges()); + response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); + response.setVpcId(network.getVpcId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Network, network.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setObjectName("network"); + return response; + } + + @Override + public Long getSecurityGroupId(String groupName, long accountId) { + SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId); + if (sg == null) { + return null; + } else { + return sg.getId(); + } + } + + @Override + public ProjectResponse createProjectResponse(Project project) { + ProjectResponse response = new ProjectResponse(); + response.setId(project.getId()); + response.setName(project.getName()); + response.setDisplaytext(project.getDisplayText()); + response.setState(project.getState().toString()); + + Domain domain = ApiDBUtils.findDomainById(project.getDomainId()); + response.setDomainId(domain.getId()); + response.setDomain(domain.getName()); + + response.setOwner(ApiDBUtils.getProjectOwner(project.getId()).getAccountName()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Project, project.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setObjectName("project"); + return response; + } + + @Override + public FirewallResponse createFirewallResponse(FirewallRule fwRule) { + FirewallResponse response = new FirewallResponse(); + + response.setId(fwRule.getId()); + response.setProtocol(fwRule.getProtocol()); + if (fwRule.getSourcePortStart() != null) { + response.setStartPort(Integer.toString(fwRule.getSourcePortStart())); + } + + if (fwRule.getSourcePortEnd() != null) { + response.setEndPort(Integer.toString(fwRule.getSourcePortEnd())); + } + + List cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId()); + response.setCidrList(StringUtils.join(cidrs, ",")); + + IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); + response.setPublicIpAddressId(ip.getId()); + response.setPublicIpAddress(ip.getAddress().addr()); + + FirewallRule.State state = fwRule.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + + response.setIcmpCode(fwRule.getIcmpCode()); + response.setIcmpType(fwRule.getIcmpType()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.FirewallRule, fwRule.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setState(stateToSet); + response.setObjectName("firewallrule"); + return response; + } + + @Override + public NetworkACLResponse createNetworkACLResponse(FirewallRule networkACL) { + NetworkACLResponse response = new NetworkACLResponse(); + + response.setId(networkACL.getId()); + response.setProtocol(networkACL.getProtocol()); + if (networkACL.getSourcePortStart() != null) { + response.setStartPort(Integer.toString(networkACL.getSourcePortStart())); + } + + if (networkACL.getSourcePortEnd() != null) { + response.setEndPort(Integer.toString(networkACL.getSourcePortEnd())); + } + + List cidrs = ApiDBUtils.findFirewallSourceCidrs(networkACL.getId()); + response.setCidrList(StringUtils.join(cidrs, ",")); + + response.setTrafficType(networkACL.getTrafficType().toString()); + + FirewallRule.State state = networkACL.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + + response.setIcmpCode(networkACL.getIcmpCode()); + response.setIcmpType(networkACL.getIcmpType()); + + response.setState(stateToSet); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setObjectName("networkacl"); + return response; + } + + public UserVmData newUserVmData(UserVm userVm) { + UserVmData userVmData = new UserVmData(); + userVmData.setId(userVm.getId()); + userVmData.setName(userVm.getHostName()); + userVmData.setCreated(userVm.getCreated()); + userVmData.setGuestOsId(userVm.getGuestOSId()); + userVmData.setHaEnable(userVm.isHaEnabled()); + if (userVm.getState() != null) { + userVmData.setState(userVm.getState().toString()); + } + if (userVm.getDisplayName() != null) { + userVmData.setDisplayName(userVm.getDisplayName()); + } else { + userVmData.setDisplayName(userVm.getHostName()); + } + userVmData.setInstanceName(userVm.getInstanceName()); + + userVmData.setDomainId(userVm.getDomainId()); + + if (userVm.getHypervisorType() != null) { + userVmData.setHypervisor(userVm.getHypervisorType().toString()); + } + + if (userVm.getPassword() != null) { + userVmData.setPassword(userVm.getPassword()); + } + return userVmData; + } + + public UserVmResponse newUserVmResponse(UserVmData userVmData, boolean caller_is_admin) { + UserVmResponse userVmResponse = new UserVmResponse(); + + userVmResponse.setHypervisor(userVmData.getHypervisor()); + userVmResponse.setId(userVmData.getId()); + userVmResponse.setName(userVmData.getName()); + + userVmResponse.setDisplayName(userVmData.getDisplayName()); + + populateAccount(userVmResponse, userVmData.getAccountId()); + populateDomain(userVmResponse, userVmData.getDomainId()); + + userVmResponse.setCreated(userVmData.getCreated()); + userVmResponse.setState(userVmData.getState()); + userVmResponse.setHaEnable(userVmData.getHaEnable()); + userVmResponse.setGroupId(userVmData.getGroupId()); + userVmResponse.setGroup(userVmData.getGroup()); + userVmResponse.setZoneId(userVmData.getZoneId()); + userVmResponse.setZoneName(userVmData.getZoneName()); + if (caller_is_admin) { + userVmResponse.setInstanceName(userVmData.getInstanceName()); + userVmResponse.setHostId(userVmData.getHostId()); + userVmResponse.setHostName(userVmData.getHostName()); + } + userVmResponse.setTemplateId(userVmData.getTemplateId()); + userVmResponse.setTemplateName(userVmData.getTemplateName()); + userVmResponse.setTemplateDisplayText(userVmData.getTemplateDisplayText()); + userVmResponse.setPasswordEnabled(userVmData.getPasswordEnabled()); + userVmResponse.setIsoId(userVmData.getIsoId()); + userVmResponse.setIsoName(userVmData.getIsoName()); + userVmResponse.setIsoDisplayText(userVmData.getIsoDisplayText()); + userVmResponse.setServiceOfferingId(userVmData.getServiceOfferingId()); + userVmResponse.setServiceOfferingName(userVmData.getServiceOfferingName()); + userVmResponse.setCpuNumber(userVmData.getCpuNumber()); + userVmResponse.setCpuSpeed(userVmData.getCpuSpeed()); + userVmResponse.setMemory(userVmData.getMemory()); + userVmResponse.setCpuUsed(userVmData.getCpuUsed()); + userVmResponse.setNetworkKbsRead(userVmData.getNetworkKbsRead()); + userVmResponse.setNetworkKbsWrite(userVmData.getNetworkKbsWrite()); + userVmResponse.setGuestOsId(userVmData.getGuestOsId()); + userVmResponse.setRootDeviceId(userVmData.getRootDeviceId()); + userVmResponse.setRootDeviceType(userVmData.getRootDeviceType()); + userVmResponse.setPassword(userVmData.getPassword()); + userVmResponse.setJobId(userVmData.getJobId()); + userVmResponse.setJobStatus(userVmData.getJobStatus()); + userVmResponse.setForVirtualNetwork(userVmData.getForVirtualNetwork()); + + Set securityGroupResponse = new HashSet(); + for (SecurityGroupData sgd : userVmData.getSecurityGroupList()) { + if (sgd.getId() != null) { + SecurityGroupResponse sgr = new SecurityGroupResponse(); + sgr.setId(sgd.getId()); + sgr.setName(sgd.getName()); + sgr.setDescription(sgd.getDescription()); + + Account account = ApiDBUtils.findAccountByNameDomain(sgd.getAccountName(), sgd.getDomainId()); + if (account != null) { + populateAccount(sgr, account.getId()); + populateDomain(sgr, account.getDomainId()); + } + + sgr.setObjectName(sgd.getObjectName()); + securityGroupResponse.add(sgr); + } + } + userVmResponse.setSecurityGroupList(new ArrayList(securityGroupResponse)); + + Set nicResponses = new HashSet(); + for (NicData nd : userVmData.getNics()) { + NicResponse nr = new NicResponse(); + nr.setId(nd.getId()); + nr.setNetworkid(nd.getNetworkid()); + nr.setNetmask(nd.getNetmask()); + nr.setGateway(nd.getGateway()); + nr.setIpaddress(nd.getIpaddress()); + nr.setIsolationUri(nd.getIsolationUri()); + nr.setBroadcastUri(nd.getBroadcastUri()); + nr.setTrafficType(nd.getTrafficType()); + nr.setType(nd.getType()); + nr.setIsDefault(nd.getIsDefault()); + nr.setMacAddress(nd.getMacAddress()); + nr.setObjectName(nd.getObjectName()); + nicResponses.add(nr); + } + userVmResponse.setNics(new ArrayList(nicResponses)); + userVmResponse.setPublicIpId(userVmData.getPublicIpId()); + userVmResponse.setPublicIp(userVmData.getPublicIp()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVmData.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + userVmResponse.setTags(tagResponses); + + return userVmResponse; + } + + @Override + public HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities) { + HypervisorCapabilitiesResponse hpvCapabilitiesResponse = new HypervisorCapabilitiesResponse(); + hpvCapabilitiesResponse.setId(hpvCapabilities.getId()); + hpvCapabilitiesResponse.setHypervisor(hpvCapabilities.getHypervisorType()); + hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion()); + hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled()); + hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit()); + return hpvCapabilitiesResponse; + } + + private void populateOwner(ControlledEntityResponse response, ControlledEntity object) { + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(object.getAccountId()); + + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + response.setProjectId(project.getId()); + response.setProjectName(project.getName()); + } else { + response.setAccountName(account.getAccountName()); + } + + Domain domain = ApiDBUtils.findDomainById(object.getDomainId()); + response.setDomainId(domain.getId()); + response.setDomainName(domain.getName()); + } + + private void populateAccount(ControlledEntityResponse response, long accountId) { + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(accountId); + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + response.setProjectId(project.getId()); + response.setProjectName(project.getName()); + } else { + response.setAccountName(account.getAccountName()); + } + } + + private void populateDomain(ControlledEntityResponse response, long domainId) { + Domain domain = ApiDBUtils.findDomainById(domainId); + + response.setDomainId(domain.getId()); + response.setDomainName(domain.getName()); + } + + @Override + public ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount) { + Account account = ApiDBUtils.findAccountById(projectAccount.getAccountId()); + ProjectAccountResponse projectAccountResponse = new ProjectAccountResponse(); + + long projectId = projectAccount.getProjectId(); + projectAccountResponse.setProjectId(projectId); + projectAccountResponse.setProjectName(ApiDBUtils.findProjectById(projectId).getName()); + + projectAccountResponse.setId(account.getId()); + projectAccountResponse.setAccountName(account.getAccountName()); + projectAccountResponse.setAccountType(account.getType()); + projectAccountResponse.setRole(projectAccount.getAccountRole().toString()); + populateDomain(projectAccountResponse, account.getDomainId()); + + // add all the users for an account as part of the response obj + List usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId()); + List userResponseList = new ArrayList(); + for (UserVO user : usersForAccount) { + UserResponse userResponse = createUserResponse(user); + userResponseList.add(userResponse); + } + + projectAccountResponse.setUsers(userResponseList); + projectAccountResponse.setObjectName("projectaccount"); + + return projectAccountResponse; + } + + @Override + public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) { + ProjectInvitationResponse response = new ProjectInvitationResponse(); + response.setId(invite.getId()); + response.setProjectId(invite.getProjectId()); + response.setProjectName(ApiDBUtils.findProjectById(invite.getProjectId()).getName()); + response.setInvitationState(invite.getState().toString()); + + if (invite.getForAccountId() != null) { + Account account = ApiDBUtils.findAccountById(invite.getForAccountId()); + response.setAccountName(account.getAccountName()); + + } else { + response.setEmail(invite.getEmail()); + } + + populateDomain(response, invite.getInDomainId()); + + response.setObjectName("projectinvitation"); + return response; + } + + @Override + public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) { + SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse(); + vmResponse.setId(vm.getId()); + vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); + vmResponse.setName(vm.getHostName()); + if (vm.getHostId() != null) { + vmResponse.setHostId(vm.getHostId()); + } + if (vm.getState() != null) { + vmResponse.setState(vm.getState().toString()); + } + if (vm.getType() == Type.DomainRouter) { + VirtualRouter router = (VirtualRouter) vm; + if (router.getRole() != null) { + vmResponse.setRole(router.getRole().toString()); + } + } + vmResponse.setObjectName("systemvminstance"); + return vmResponse; + } + + @Override + public PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result) { + PhysicalNetworkResponse response = new PhysicalNetworkResponse(); + + response.setZoneId(result.getDataCenterId()); + response.setNetworkSpeed(result.getSpeed()); + response.setVlan(result.getVnet()); + response.setDomainId(result.getDomainId()); + response.setId(result.getUuid()); + if (result.getBroadcastDomainRange() != null) { + response.setBroadcastDomainRange(result.getBroadcastDomainRange().toString()); + } + response.setIsolationMethods(result.getIsolationMethods()); + response.setTags(result.getTags()); + if (result.getState() != null) { + response.setState(result.getState().toString()); + } + + response.setName(result.getName()); + + response.setObjectName("physicalnetwork"); + return response; + } + + @Override + public ServiceResponse createNetworkServiceResponse(Service service) { + ServiceResponse response = new ServiceResponse(); + response.setName(service.getName()); + + // set list of capabilities required for the service + List capabilityResponses = new ArrayList(); + Capability[] capabilities = service.getCapabilities(); + for (Capability cap : capabilities) { + CapabilityResponse capabilityResponse = new CapabilityResponse(); + capabilityResponse.setName(cap.getName()); + capabilityResponse.setObjectName("capability"); + if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || + cap.getName().equals(Capability.SupportedSourceNatTypes.getName()) || + cap.getName().equals(Capability.RedundantRouter.getName())) { + capabilityResponse.setCanChoose(true); + } else { + capabilityResponse.setCanChoose(false); + } + capabilityResponses.add(capabilityResponse); + } + response.setCapabilities(capabilityResponses); + + // set list of providers providing this service + List serviceProviders = ApiDBUtils.getProvidersForService(service); + List serviceProvidersResponses = new ArrayList(); + for (Network.Provider serviceProvider : serviceProviders) { + // return only Virtual Router/JuniperSRX as a provider for the firewall + if (service == Service.Firewall && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX)) { + continue; + } + + ProviderResponse serviceProviderResponse = createServiceProviderResponse(serviceProvider); + serviceProvidersResponses.add(serviceProviderResponse); + } + response.setProviders(serviceProvidersResponses); + + response.setObjectName("networkservice"); + return response; + + } + + private ProviderResponse createServiceProviderResponse(Provider serviceProvider) { + ProviderResponse response = new ProviderResponse(); + response.setName(serviceProvider.getName()); + boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider); + response.setCanEnableIndividualServices(canEnableIndividualServices); + return response; + } + + @Override + public ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result) { + ProviderResponse response = new ProviderResponse(); + response.setId(result.getUuid()); + response.setName(result.getProviderName()); + response.setPhysicalNetworkId(result.getPhysicalNetworkId()); + response.setDestinationPhysicalNetworkId(result.getDestinationPhysicalNetworkId()); + response.setState(result.getState().toString()); + + // set enabled services + List services = new ArrayList(); + for (Service service : result.getEnabledServices()) { + services.add(service.getName()); + } + response.setServices(services); + + response.setObjectName("networkserviceprovider"); + return response; + } + + @Override + public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result) { + TrafficTypeResponse response = new TrafficTypeResponse(); + response.setId(result.getUuid()); + response.setPhysicalNetworkId(result.getPhysicalNetworkId()); + response.setTrafficType(result.getTrafficType().toString()); + response.setXenLabel(result.getXenNetworkLabel()); + response.setKvmLabel(result.getKvmNetworkLabel()); + response.setVmwareLabel(result.getVmwareNetworkLabel()); + + response.setObjectName("traffictype"); + return response; + } + + @Override + public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) { + VirtualRouterProviderResponse response = new VirtualRouterProviderResponse(); + response.setId(result.getId()); + response.setNspId(result.getNspId()); + response.setEnabled(result.isEnabled()); + + response.setObjectName("virtualrouterelement"); + return response; + } + + @Override + public LBStickinessResponse createLBStickinessPolicyResponse( + StickinessPolicy stickinessPolicy, LoadBalancer lb) { + LBStickinessResponse spResponse = new LBStickinessResponse(); + + spResponse.setlbRuleId(lb.getId()); + Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId()); + if (accountTemp != null) { + spResponse.setAccountName(accountTemp.getAccountName()); + spResponse.setDomainId(accountTemp.getDomainId()); + spResponse.setDomainName(ApiDBUtils.findDomainById( + accountTemp.getDomainId()).getName()); + } + + List responses = new ArrayList(); + LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse( + stickinessPolicy); + responses.add(ruleResponse); + + spResponse.setRules(responses); + + spResponse.setObjectName("stickinesspolicies"); + return spResponse; + } + + @Override + public LBStickinessResponse createLBStickinessPolicyResponse( + List stickinessPolicies, LoadBalancer lb) { + LBStickinessResponse spResponse = new LBStickinessResponse(); + + if (lb == null) { + return spResponse; + } + spResponse.setlbRuleId(lb.getId()); + Account account = ApiDBUtils.findAccountById(lb.getAccountId()); + if (account != null) { + spResponse.setAccountName(account.getAccountName()); + spResponse.setDomainId(account.getDomainId()); + spResponse.setDomainName(ApiDBUtils.findDomainById( + account.getDomainId()).getName()); + } + + List responses = new ArrayList(); + for (StickinessPolicy stickinessPolicy : stickinessPolicies) { + LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy); + responses.add(ruleResponse); + } + spResponse.setRules(responses); + + spResponse.setObjectName("stickinesspolicies"); + return spResponse; + } + + @Override + public LDAPConfigResponse createLDAPConfigResponse(String hostname, + Integer port, Boolean useSSL, String queryFilter, + String searchBase, String bindDN) { + LDAPConfigResponse lr = new LDAPConfigResponse(); + lr.setHostname(hostname); + lr.setPort(port.toString()); + lr.setUseSSL(useSSL.toString()); + lr.setQueryFilter(queryFilter); + lr.setBindDN(bindDN); + lr.setSearchBase(searchBase); + lr.setObjectName("ldapconfig"); + return lr; + } + + @Override + public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) { + StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse(); + response.setUuid(result.getUuid()); + response.setVlan(result.getVlan()); + response.setEndIp(result.getEndIp()); + response.setStartIp(result.getStartIp()); + response.setPodUuid(result.getPodUuid()); + response.setZoneUuid(result.getZoneUuid()); + response.setNetworkUuid(result.getNetworkUuid()); + response.setNetmask(result.getNetmask()); + response.setGateway(result.getGateway()); + 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())); + Long accountId = resourceTag.getAccountId(); + Long domainId = resourceTag.getDomainId(); + if (accountId != null) { + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId()); + + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + response.setProjectId(project.getId()); + response.setProjectName(project.getName()); + } else { + response.setAccountName(account.getAccountName()); + } + } + + if (domainId != null) { + response.setDomainId(domainId); + response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); + } + + response.setCustomer(resourceTag.getCustomer()); + } + + response.setObjectName("tag"); + + return response; + } + + @Override + public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { + VpcOfferingResponse response = new VpcOfferingResponse(); + response.setId(offering.getId()); + response.setName(offering.getName()); + response.setDisplayText(offering.getDisplayText()); + response.setIsDefault(offering.isDefault()); + response.setState(offering.getState().name()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + response.setServices(serviceResponses); + response.setObjectName("vpcoffering"); + return response; + } + + @Override + public VpcResponse createVpcResponse(Vpc vpc) { + VpcResponse response = new VpcResponse(); + response.setId(vpc.getId()); + response.setName(vpc.getName()); + response.setDisplayText(vpc.getDisplayText()); + response.setState(vpc.getState().name()); + response.setVpcOfferingId(vpc.getVpcOfferingId()); + response.setCidr(vpc.getCidr()); + response.setRestartRequired(vpc.isRestartRequired()); + response.setNetworkDomain(vpc.getNetworkDomain()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + + List networkResponses = new ArrayList(); + List networks = ApiDBUtils.listVpcNetworks(vpc.getId()); + for (Network network : networks) { + NetworkResponse ntwkRsp = createNetworkResponse(network); + networkResponses.add(ntwkRsp); + } + + DataCenter zone = ApiDBUtils.findZoneById(vpc.getZoneId()); + response.setZoneId(vpc.getZoneId()); + response.setZoneName(zone.getName()); + + response.setNetworks(networkResponses); + response.setServices(serviceResponses); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Vpc, vpc.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + + response.setObjectName("vpc"); + return response; + } + + @Override + public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) { + PrivateGatewayResponse response = new PrivateGatewayResponse(); + response.setId(result.getId()); + response.setVlan(result.getVlanTag()); + response.setGateway(result.getGateway()); + response.setNetmask(result.getNetmask()); + response.setVpcId(result.getVpcId()); + response.setZoneId(result.getZoneId()); + DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId()); + response.setZoneName(zone.getName()); + response.setAddress(result.getIp4Address()); + response.setPhysicalNetworkId(result.getPhysicalNetworkId()); + + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + response.setState(result.getState().toString()); + + response.setObjectName("privategateway"); + 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()); + // 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); + + // 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.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); + + // 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; + } + + @Override + public StaticRouteResponse createStaticRouteResponse(StaticRoute result) { + StaticRouteResponse response = new StaticRouteResponse(); + response.setId(result.getId()); + response.setVpcId(result.getVpcId()); + response.setCidr(result.getCidr()); + + StaticRoute.State state = result.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + response.setState(stateToSet); + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.StaticRoute, result.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + response.setTags(tagResponses); + response.setObjectName("staticroute"); + return response; + } + + @Override + public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) { + Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse(); + response.setId(result.getId()); + response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString()); + response.setVpcId(result.getVpcId()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpngateway"); + + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + + return response; + } + + @Override + public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) { + Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse(); + response.setId(result.getId()); + response.setGatewayIp(result.getGatewayIp()); + response.setGuestCidrList(result.getGuestCidrList()); + response.setIpsecPsk(result.getIpsecPsk()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpncustomergateway"); + + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + + return response; + } + + @Override + public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) { + Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse(); + response.setId(result.getId()); + + response.setVpnGatewayId(result.getVpnGatewayId()); + Long vpnGatewayId = result.getVpnGatewayId(); + if(vpnGatewayId != null) { + Site2SiteVpnGatewayVO vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId); + + long ipId = vpnGateway.getAddrId(); + IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId); + response.setIp(ipObj.getAddress().addr()); + } + + response.setCustomerGatewayId(result.getCustomerGatewayId()); + Long customerGatewayId = result.getCustomerGatewayId(); + if(customerGatewayId != null) { + Site2SiteCustomerGatewayVO customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId); + response.setGatewayIp(customerGateway.getGatewayIp()); + response.setGuestCidrList(customerGateway.getGuestCidrList()); + response.setIpsecPsk(customerGateway.getIpsecPsk()); + response.setIkePolicy(customerGateway.getIkePolicy()); + response.setEspPolicy(customerGateway.getEspPolicy()); + response.setLifetime(customerGateway.getLifetime()); + } + + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + + response.setState(result.getState().toString()); + response.setCreated(result.getCreated()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpnconnection"); + 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.setZoneId(counter.getZoneId()); + * response.setObjectName("counter"); + * + * response.setVpnGatewayId(result.getVpnGatewayId()); + * Long vpnGatewayId = result.getVpnGatewayId(); + * if(vpnGatewayId != null) { + * Site2SiteVpnGatewayVO vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId); + * + * long ipId = vpnGateway.getAddrId(); + * IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId); + * response.setIp(ipObj.getAddress().addr()); + * } + * + * response.setCustomerGatewayId(result.getCustomerGatewayId()); + * Long customerGatewayId = result.getCustomerGatewayId(); + * if(customerGatewayId != null) { + * Site2SiteCustomerGatewayVO customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId); + * response.setGatewayIp(customerGateway.getGatewayIp()); + * response.setGuestCidrList(customerGateway.getGuestCidrList()); + * response.setIpsecPsk(customerGateway.getIpsecPsk()); + * response.setIkePolicy(customerGateway.getIkePolicy()); + * response.setEspPolicy(customerGateway.getEspPolicy()); + * response.setLifetime(customerGateway.getLifetime()); + * } + * + * response.setCreated(result.getCreated()); + * response.setRemoved(result.getRemoved()); + * response.setObjectName("vpnconnection"); + * 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()); + // Account account = ApiDBUtils.findAccountById(condition.getAccountId()); + // response.setZoneId(condition.getZoneId()); + // response.setObjectName("condition"); + // + // populateOwner(response, condition); + // 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; + } +} diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index a840fac90ab..5586aace2ef 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -1,1101 +1,1137 @@ -// 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.api; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.UnsupportedEncodingException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.security.SecureRandom; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TimeZone; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.http.ConnectionClosedException; -import org.apache.http.HttpException; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.HttpServerConnection; -import org.apache.http.HttpStatus; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.impl.DefaultHttpResponseFactory; -import org.apache.http.impl.DefaultHttpServerConnection; -import org.apache.http.impl.NoConnectionReuseStrategy; -import org.apache.http.impl.SocketHttpServerConnection; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.BasicHttpProcessor; -import org.apache.http.protocol.HttpContext; -import org.apache.http.protocol.HttpRequestHandler; -import org.apache.http.protocol.HttpRequestHandlerRegistry; -import org.apache.http.protocol.HttpService; -import org.apache.http.protocol.ResponseConnControl; -import org.apache.http.protocol.ResponseContent; -import org.apache.http.protocol.ResponseDate; -import org.apache.http.protocol.ResponseServer; -import org.apache.log4j.Logger; - -import com.cloud.api.response.ApiResponseSerializer; -import com.cloud.api.response.ExceptionResponse; -import com.cloud.api.response.ListResponse; -import com.cloud.async.AsyncJob; -import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobVO; -import com.cloud.cluster.StackMaid; -import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationVO; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.domain.Domain; -import com.cloud.domain.DomainVO; -import com.cloud.event.EventUtils; -import com.cloud.exception.CloudAuthenticationException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.server.ManagementServer; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.DomainManager; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.user.UserContext; -import com.cloud.user.UserVO; -import com.cloud.utils.IdentityProxy; -import com.cloud.utils.Pair; -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.component.PluggableService; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.encoding.Base64; -import com.cloud.uuididentity.dao.IdentityDao; -import com.cloud.utils.exception.CSExceptionErrorCode; - - -public class ApiServer implements HttpRequestHandler { - private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); - private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); - - public static final short ADMIN_COMMAND = 1; - public static final short DOMAIN_ADMIN_COMMAND = 4; - public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2; - public static final short USER_COMMAND = 8; - public static boolean encodeApiResponse = false; - public static String jsonContentType = "text/javascript"; - private Properties _apiCommands = null; - private ApiDispatcher _dispatcher; - private AccountManager _accountMgr = null; - private DomainManager _domainMgr = null; - private AsyncJobManager _asyncMgr = null; - private Account _systemAccount = null; - private User _systemUser = null; - - private static int _workerCount = 0; - - private static ApiServer s_instance = null; - private static List s_userCommands = null; - private static List s_resellerCommands = null; // AKA domain-admin - private static List s_adminCommands = null; - private static List s_resourceDomainAdminCommands = null; - private static List s_allCommands = null; - private static List s_pluggableServiceCommands = null; - private static final DateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - - private static ExecutorService _executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("ApiServer")); - - static { - s_userCommands = new ArrayList(); - s_resellerCommands = new ArrayList(); - s_adminCommands = new ArrayList(); - s_resourceDomainAdminCommands = new ArrayList(); - s_allCommands = new ArrayList(); - s_pluggableServiceCommands = new ArrayList(); - } - - private ApiServer() { - } - - public static void initApiServer(String[] apiConfig) { - if (s_instance == null) { - s_instance = new ApiServer(); - s_instance.init(apiConfig); - } - } - - public static ApiServer getInstance() { - // initApiServer(); - return s_instance; - } - - public Properties get_apiCommands() { - return _apiCommands; - } - - public static boolean isPluggableServiceCommand(String cmdClassName) { - if (s_pluggableServiceCommands != null) { - if (s_pluggableServiceCommands.contains(cmdClassName)) { - return true; - } - } - return false; - } - - private String[] getPluggableServicesApiConfigs() { - List pluggableServicesApiConfigs = new ArrayList(); - - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - List services = locator.getAllPluggableServices(); - for (PluggableService service : services) { - pluggableServicesApiConfigs.add(service.getPropertiesFile()); - } - return pluggableServicesApiConfigs.toArray(new String[0]); - } - - private void processConfigFiles(String[] apiConfig, boolean pluggableServicesConfig) { - try { - if (_apiCommands == null) { - _apiCommands = new Properties(); - } - Properties preProcessedCommands = new Properties(); - if (apiConfig != null) { - for (String configFile : apiConfig) { - File commandsFile = PropertiesUtil.findConfigFile(configFile); - if (commandsFile != null) { - try { - preProcessedCommands.load(new FileInputStream(commandsFile)); - } catch (FileNotFoundException fnfex) { - // in case of a file within a jar in classpath, try to open stream using url - InputStream stream = PropertiesUtil.openStreamFromURL(configFile); - if (stream != null) { - preProcessedCommands.load(stream); - } else { - s_logger.error("Unable to find properites file", fnfex); - } - } - } - } - for (Object key : preProcessedCommands.keySet()) { - String preProcessedCommand = preProcessedCommands.getProperty((String) key); - String[] commandParts = preProcessedCommand.split(";"); - _apiCommands.put(key, commandParts[0]); - - if (pluggableServicesConfig) { - s_pluggableServiceCommands.add(commandParts[0]); - } - - if (commandParts.length > 1) { - try { - short cmdPermissions = Short.parseShort(commandParts[1]); - if ((cmdPermissions & ADMIN_COMMAND) != 0) { - s_adminCommands.add((String) key); - } - if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { - s_resourceDomainAdminCommands.add((String) key); - } - if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { - s_resellerCommands.add((String) key); - } - if ((cmdPermissions & USER_COMMAND) != 0) { - s_userCommands.add((String) key); - } - } catch (NumberFormatException nfe) { - s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand); - } - } - } - - s_allCommands.addAll(s_adminCommands); - s_allCommands.addAll(s_resourceDomainAdminCommands); - s_allCommands.addAll(s_userCommands); - s_allCommands.addAll(s_resellerCommands); - } - } catch (FileNotFoundException fnfex) { - s_logger.error("Unable to find properites file", fnfex); - } catch (IOException ioex) { - s_logger.error("Exception loading properties file", ioex); - } - } - - public void init(String[] apiConfig) { - BaseCmd.setComponents(new ApiResponseHelper()); - BaseListCmd.configure(); - processConfigFiles(apiConfig, false); - - // get commands for all pluggable services - String[] pluggableServicesApiConfigs = getPluggableServicesApiConfigs(); - processConfigFiles(pluggableServicesApiConfigs, true); - - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - _accountMgr = locator.getManager(AccountManager.class); - _asyncMgr = locator.getManager(AsyncJobManager.class); - _systemAccount = _accountMgr.getSystemAccount(); - _systemUser = _accountMgr.getSystemUser(); - _dispatcher = ApiDispatcher.getInstance(); - _domainMgr = locator.getManager(DomainManager.class); - - Integer apiPort = null; // api port, null by default - ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); - SearchCriteria sc = configDao.createSearchCriteria(); - sc.addAnd("name", SearchCriteria.Op.EQ, "integration.api.port"); - List values = configDao.search(sc, null); - if ((values != null) && (values.size() > 0)) { - ConfigurationVO apiPortConfig = values.get(0); - if (apiPortConfig.getValue() != null) { - apiPort = Integer.parseInt(apiPortConfig.getValue()); - } - } - - encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())); - - String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key()); - if (jsonType != null) { - jsonContentType = jsonType; - } - - if (apiPort != null) { - ListenerThread listenerThread = new ListenerThread(this, apiPort); - listenerThread.start(); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - // get some information for the access log... - StringBuffer sb = new StringBuffer(); - HttpServerConnection connObj = (HttpServerConnection) context.getAttribute("http.connection"); - if (connObj instanceof SocketHttpServerConnection) { - InetAddress remoteAddr = ((SocketHttpServerConnection) connObj).getRemoteAddress(); - sb.append(remoteAddr.toString() + " -- "); - } - sb.append(request.getRequestLine()); - - try { - String uri = request.getRequestLine().getUri(); - int requestParamsStartIndex = uri.indexOf('?'); - if (requestParamsStartIndex >= 0) { - uri = uri.substring(requestParamsStartIndex + 1); - } - - String[] paramArray = uri.split("&"); - if (paramArray.length < 1) { - s_logger.info("no parameters received for request: " + uri + ", aborting..."); - return; - } - - Map parameterMap = new HashMap(); - - String responseType = BaseCmd.RESPONSE_TYPE_XML; - for (String paramEntry : paramArray) { - String[] paramValue = paramEntry.split("="); - if (paramValue.length != 2) { - s_logger.info("malformed parameter: " + paramEntry + ", skipping"); - continue; - } - if ("response".equalsIgnoreCase(paramValue[0])) { - responseType = paramValue[1]; - } else { - // according to the servlet spec, the parameter map should be in the form (name=String, - // value=String[]), so - // parameter values will be stored in an array - parameterMap.put(/* name */paramValue[0], /* value */new String[] { paramValue[1] }); - } - } - try { - // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM - UserContext.registerContext(_systemUser.getId(), _systemAccount, null, true); - sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") "); - String responseText = handleRequest(parameterMap, true, responseType, sb); - sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length())); - - writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null); - } catch (ServerApiException se) { - String responseText = getSerializedApiError(se.getErrorCode(), se.getDescription(), parameterMap, responseType, se); - writeResponse(response, responseText, se.getErrorCode(), responseType, se.getDescription()); - sb.append(" " + se.getErrorCode() + " " + se.getDescription()); - } catch (RuntimeException e) { - // log runtime exception like NullPointerException to help identify the source easier - s_logger.error("Unhandled exception, ", e); - throw e; - } - } finally { - s_accessLogger.info(sb.toString()); - UserContext.unregisterContext(); - } - } - - @SuppressWarnings("rawtypes") - public String handleRequest(Map params, boolean decode, String responseType, StringBuffer auditTrailSb) throws ServerApiException { - String response = null; - String[] command = null; - try { - command = (String[]) params.get("command"); - if (command == null) { - s_logger.error("invalid request, no command sent"); - if (s_logger.isTraceEnabled()) { - s_logger.trace("dumping request parameters"); - for (Object key : params.keySet()) { - String keyStr = (String) key; - String[] value = (String[]) params.get(key); - s_logger.trace(" key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0])); - } - } - throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent"); - } else { - Map paramMap = new HashMap(); - Set keys = params.keySet(); - Iterator keysIter = keys.iterator(); - while (keysIter.hasNext()) { - String key = (String) keysIter.next(); - if ("command".equalsIgnoreCase(key)) { - continue; - } - String[] value = (String[]) params.get(key); - - String decodedValue = null; - if (decode) { - try { - decodedValue = URLDecoder.decode(value[0], "UTF-8"); - } catch (UnsupportedEncodingException usex) { - s_logger.warn(key + " could not be decoded, value = " + value[0]); - throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0]); - } catch (IllegalArgumentException iae) { - s_logger.warn(key + " could not be decoded, value = " + value[0]); - throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0] + " which contains illegal characters eg.%"); - } - } else { - decodedValue = value[0]; - } - paramMap.put(key, decodedValue); - } - String cmdClassName = _apiCommands.getProperty(command[0]); - if (cmdClassName != null) { - Class cmdClass = Class.forName(cmdClassName); - BaseCmd cmdObj = (BaseCmd) cmdClass.newInstance(); - cmdObj.setFullUrlParams(paramMap); - cmdObj.setResponseType(responseType); - // This is where the command is either serialized, or directly dispatched - response = queueCommand(cmdObj, paramMap); - buildAuditTrail(auditTrailSb, command[0], response); - } else { - if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { - String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]); - s_logger.warn(errorString); - auditTrailSb.append(" " + errorString); - throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, errorString); - } - } - } - } catch (Exception ex) { - if (ex instanceof InvalidParameterValueException) { - InvalidParameterValueException ref = (InvalidParameterValueException)ex; - ServerApiException e = new ServerApiException(BaseCmd.PARAM_ERROR, ex.getMessage()); - // copy over the IdentityProxy information as well and throw the serverapiexception. - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy obj = idList.get(i); - e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName()); - } - } - // Also copy over the cserror code and the function/layer in which it was thrown. - e.setCSErrorCode(ref.getCSErrorCode()); - throw e; - } else if (ex instanceof PermissionDeniedException) { - PermissionDeniedException ref = (PermissionDeniedException)ex; - ServerApiException e = new ServerApiException(BaseCmd.ACCOUNT_ERROR, ex.getMessage()); - // copy over the IdentityProxy information as well and throw the serverapiexception. - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy obj = idList.get(i); - e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName()); - } - } - e.setCSErrorCode(ref.getCSErrorCode()); - throw e; - } else if (ex instanceof ServerApiException) { - throw (ServerApiException) ex; - } else { - s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command[0]), ex); - ServerApiException e = new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal server error, unable to execute request."); - e.setCSErrorCode(CSExceptionErrorCode.getCSErrCode("ServerApiException")); - throw e; - } - } - return response; - } - - private String queueCommand(BaseCmd cmdObj, Map params) { - UserContext ctx = UserContext.current(); - Long callerUserId = ctx.getCallerUserId(); - Account caller = ctx.getCaller(); - if (cmdObj instanceof BaseAsyncCmd) { - Long objectId = null; - String objectEntityTable = null; - if (cmdObj instanceof BaseAsyncCreateCmd) { - BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; - _dispatcher.dispatchCreateCmd(createCmd, params); - objectId = createCmd.getEntityId(); - objectEntityTable = createCmd.getEntityTable(); - params.put("id", objectId.toString()); - } else { - ApiDispatcher.setupParameters(cmdObj, params); - ApiDispatcher.plugService(cmdObj); - } - - BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj; - - if (callerUserId != null) { - params.put("ctxUserId", callerUserId.toString()); - } - if (caller != null) { - params.put("ctxAccountId", String.valueOf(caller.getId())); - } - - long startEventId = ctx.getStartEventId(); - asyncCmd.setStartEventId(startEventId); - - // save the scheduled event - Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, - asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), - startEventId); - if (startEventId == 0) { - // There was no create event before, set current event id as start eventId - startEventId = eventId; - } - - params.put("ctxStartEventId", String.valueOf(startEventId)); - - ctx.setAccountId(asyncCmd.getEntityOwnerId()); - - AsyncJobVO job = new AsyncJobVO(); - job.setInstanceId((objectId == null) ? asyncCmd.getInstanceId() : objectId); - job.setInstanceType(asyncCmd.getInstanceType()); - job.setUserId(callerUserId); - job.setAccountId(caller.getId()); - - job.setCmd(cmdObj.getClass().getName()); - job.setCmdInfo(ApiGsonHelper.getBuilder().create().toJson(params)); - - long jobId = _asyncMgr.submitAsyncJob(job); - - if (jobId == 0L) { - String errorMsg = "Unable to schedule async job for command " + job.getCmd(); - s_logger.warn(errorMsg); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, errorMsg); - } - - if (objectId != null) { - SerializationContext.current().setUuidTranslation(true); - return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objectId, objectEntityTable); - } - - SerializationContext.current().setUuidTranslation(true); - return ApiResponseSerializer.toSerializedString(asyncCmd.getResponse(jobId), asyncCmd.getResponseType()); - } else { - _dispatcher.dispatch(cmdObj, params); - - // if the command is of the listXXXCommand, we will need to also return the - // the job id and status if possible - if (cmdObj instanceof BaseListCmd) { - buildAsyncListResponse((BaseListCmd) cmdObj, caller); - } - - SerializationContext.current().setUuidTranslation(true); - return ApiResponseSerializer.toSerializedString((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); - } - } - - private void buildAsyncListResponse(BaseListCmd command, Account account) { - List responses = ((ListResponse) command.getResponseObject()).getResponses(); - if (responses != null && responses.size() > 0) { - List jobs = null; - - // list all jobs for ROOT admin - if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) { - jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), null); - } else { - jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), account.getId()); - } - - if (jobs.size() == 0) { - return; - } - - // Using maps might possibly be more efficient if the set is large enough but for now, we'll just do a - // comparison of two lists. Either way, there shouldn't be too many async jobs active for the account. - for (AsyncJob job : jobs) { - if (job.getInstanceId() == null) { - continue; - } - for (ResponseObject response : responses) { - if (response.getObjectId() != null && job.getInstanceId().longValue() == response.getObjectId().longValue()) { - response.setJobId(job.getId()); - response.setJobStatus(job.getStatus()); - } - } - } - } - } - - private void buildAuditTrail(StringBuffer auditTrailSb, String command, String result) { - if (result == null) { - return; - } - auditTrailSb.append(" " + HttpServletResponse.SC_OK + " "); - auditTrailSb.append(result); - /* - * if (command.equals("queryAsyncJobResult")){ //For this command we need to also log job status and job - * resultcode for - * (Pair pair : resultValues){ String key = pair.first(); if (key.equals("jobstatus")){ - * auditTrailSb.append(" "); auditTrailSb.append(key); auditTrailSb.append("="); - * auditTrailSb.append(pair.second()); - * }else if (key.equals("jobresultcode")){ auditTrailSb.append(" "); auditTrailSb.append(key); - * auditTrailSb.append("="); - * auditTrailSb.append(pair.second()); } } }else { for (Pair pair : resultValues){ if - * (pair.first().equals("jobid")){ // Its an async job so report the jobid auditTrailSb.append(" "); - * auditTrailSb.append(pair.first()); auditTrailSb.append("="); auditTrailSb.append(pair.second()); } } } - */ - } - - private static boolean isCommandAvailable(String commandName) { - boolean isCommandAvailable = false; - isCommandAvailable = s_allCommands.contains(commandName); - return isCommandAvailable; - } - - public boolean verifyRequest(Map requestParameters, Long userId) throws ServerApiException { - try { - String apiKey = null; - String secretKey = null; - String signature = null; - String unsignedRequest = null; - - String[] command = (String[]) requestParameters.get("command"); - if (command == null) { - s_logger.info("missing command, ignoring request..."); - return false; - } - - String commandName = command[0]; - - // if userId not null, that mean that user is logged in - if (userId != null) { - Long accountId = ApiDBUtils.findUserById(userId).getAccountId(); - Account userAccount = _accountMgr.getAccount(accountId); - short accountType = userAccount.getType(); - - if (!isCommandAvailable(accountType, commandName)) { - s_logger.warn("The given command:" + commandName + " does not exist"); - throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command does not exist"); - } - return true; - } else { - // check against every available command to see if the command exists or not - if (!isCommandAvailable(commandName) && !commandName.equals("login") && !commandName.equals("logout")) { - s_logger.warn("The given command:" + commandName + " does not exist"); - throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command does not exist"); - } - } - - // - build a request string with sorted params, make sure it's all lowercase - // - sign the request, verify the signature is the same - List parameterNames = new ArrayList(); - - for (Object paramNameObj : requestParameters.keySet()) { - parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later - } - - Collections.sort(parameterNames); - - String signatureVersion = null; - String expires = null; - - for (String paramName : parameterNames) { - // parameters come as name/value pairs in the form String/String[] - String paramValue = ((String[]) requestParameters.get(paramName))[0]; - - if ("signature".equalsIgnoreCase(paramName)) { - signature = paramValue; - } else { - if ("apikey".equalsIgnoreCase(paramName)) { - apiKey = paramValue; - } - else if ("signatureversion".equalsIgnoreCase(paramName)) { - signatureVersion = paramValue; - } else if ("expires".equalsIgnoreCase(paramName)) { - expires = paramValue; - } - - if (unsignedRequest == null) { - unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); - } else { - unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); - } - } - } - - // if api/secret key are passed to the parameters - if ((signature == null) || (apiKey == null)) { - if (s_logger.isDebugEnabled()) { - s_logger.info("expired session, missing signature, or missing apiKey -- ignoring request...sig: " + signature + ", apiKey: " + apiKey); - } - return false; // no signature, bad request - } - - Date expiresTS = null; - if ("3".equals(signatureVersion)) { - // New signature authentication. Check for expire parameter and its validity - if (expires == null) { - s_logger.info("missing Expires parameter -- ignoring request...sig: " + signature + ", apiKey: " + apiKey); - return false; - } - synchronized (_dateFormat) { - try { - expiresTS = _dateFormat.parse(expires); - } catch (ParseException pe) { - s_logger.info("Incorrect date format for Expires parameter", pe); - return false; - } - } - Date now = new Date(System.currentTimeMillis()); - if (expiresTS.before(now)) { - s_logger.info("Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey); - return false; - } - } - - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - txn.close(); - User user = null; - // verify there is a user with this api key - Pair userAcctPair = _accountMgr.findUserByApiKey(apiKey); - if (userAcctPair == null) { - s_logger.info("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey); - return false; - } - - user = userAcctPair.first(); - Account account = userAcctPair.second(); - - if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) { - s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() + "; accountState: " - + account.getState()); - return false; - } - - UserContext.updateContext(user.getId(), account, null); - - if (!isCommandAvailable(account.getType(), commandName)) { - s_logger.warn("The given command:" + commandName + " does not exist"); - throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist"); - } - - // verify secret key exists - secretKey = user.getSecretKey(); - if (secretKey == null) { - s_logger.info("User does not have a secret key associated with the account -- ignoring request, username: " + user.getUsername()); - return false; - } - - unsignedRequest = unsignedRequest.toLowerCase(); - - Mac mac = Mac.getInstance("HmacSHA1"); - SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); - mac.init(keySpec); - mac.update(unsignedRequest.getBytes()); - byte[] encryptedBytes = mac.doFinal(); - String computedSignature = Base64.encodeBytes(encryptedBytes); - boolean equalSig = signature.equals(computedSignature); - if (!equalSig) { - s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature); - } - return equalSig; - } catch (Exception ex) { - if (ex instanceof ServerApiException && ((ServerApiException) ex).getErrorCode() == BaseCmd.UNSUPPORTED_ACTION_ERROR) { - throw (ServerApiException) ex; - } - s_logger.error("unable to verifty request signature", ex); - } - return false; - } - - public Long fetchDomainId(String domainUUID){ - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - IdentityDao identityDao = locator.getDao(IdentityDao.class); - try{ - Long domainId = identityDao.getIdentityId("domain", domainUUID); - return domainId; - }catch(InvalidParameterValueException ex){ - return null; - } - } - - public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress ,Map requestParameters) throws CloudAuthenticationException { - // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist - // we will default to ROOT - if (domainId == null) { - if (domainPath == null || domainPath.trim().length() == 0) { - domainId = DomainVO.ROOT_DOMAIN; - } else { - Domain domainObj = _domainMgr.findDomainByPath(domainPath); - if (domainObj != null) { - domainId = domainObj.getId(); - } else { // if an unknown path is passed in, fail the login call - throw new CloudAuthenticationException("Unable to find the domain from the path " + domainPath); - } - } - } - - UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters); - if (userAcct != null) { - String timezone = userAcct.getTimezone(); - float offsetInHrs = 0f; - if (timezone != null) { - TimeZone t = TimeZone.getTimeZone(timezone); - s_logger.info("Current user logged in under " + timezone + " timezone"); - - java.util.Date date = new java.util.Date(); - long longDate = date.getTime(); - float offsetInMs = (t.getOffset(longDate)); - offsetInHrs = offsetInMs / (1000 * 60 * 60); - s_logger.info("Timezone offset from UTC is: " + offsetInHrs); - } - - Account account = _accountMgr.getAccount(userAcct.getAccountId()); - - // set the userId and account object for everyone - session.setAttribute("userid", userAcct.getId()); - UserVO user = (UserVO) _accountMgr.getActiveUser(userAcct.getId()); - if(user.getUuid() != null){ - session.setAttribute("user_UUID", user.getUuid()); - } - - session.setAttribute("username", userAcct.getUsername()); - session.setAttribute("firstname", userAcct.getFirstname()); - session.setAttribute("lastname", userAcct.getLastname()); - session.setAttribute("accountobj", account); - session.setAttribute("account", account.getAccountName()); - - session.setAttribute("domainid", account.getDomainId()); - DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId()); - if(domain.getUuid() != null){ - session.setAttribute("domain_UUID", domain.getUuid()); - } - - session.setAttribute("type", Short.valueOf(account.getType()).toString()); - session.setAttribute("registrationtoken", userAcct.getRegistrationToken()); - session.setAttribute("registered", new Boolean(userAcct.isRegistered()).toString()); - - if (timezone != null) { - session.setAttribute("timezone", timezone); - session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString()); - } - - // (bug 5483) generate a session key that the user must submit on every request to prevent CSRF, add that - // to the login response so that session-based authenticators know to send the key back - SecureRandom sesssionKeyRandom = new SecureRandom(); - byte sessionKeyBytes[] = new byte[20]; - sesssionKeyRandom.nextBytes(sessionKeyBytes); - String sessionKey = Base64.encodeBytes(sessionKeyBytes); - session.setAttribute("sessionkey", sessionKey); - - return; - } - throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials"); - } - - public void logoutUser(long userId) { - _accountMgr.logoutUser(Long.valueOf(userId)); - return; - } - - public boolean verifyUser(Long userId) { - User user = _accountMgr.getUserIncludingRemoved(userId); - Account account = null; - if (user != null) { - account = _accountMgr.getAccount(user.getAccountId()); - } - - if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) || !account.getState().equals(Account.State.enabled)) { - s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API"); - return false; - } - return true; - } - - public static boolean isCommandAvailable(short accountType, String commandName) { - boolean isCommandAvailable = false; - switch (accountType) { - case Account.ACCOUNT_TYPE_ADMIN: - isCommandAvailable = s_adminCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: - isCommandAvailable = s_resellerCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: - isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_NORMAL: - isCommandAvailable = s_userCommands.contains(commandName); - break; - } - return isCommandAvailable; - } - - // FIXME: rather than isError, we might was to pass in the status code to give more flexibility - private void writeResponse(HttpResponse resp, final String responseText, final int statusCode, String responseType, String reasonPhrase) { - try { - resp.setStatusCode(statusCode); - resp.setReasonPhrase(reasonPhrase); - - BasicHttpEntity body = new BasicHttpEntity(); - if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - // JSON response - body.setContentType(jsonContentType); - if (responseText == null) { - body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes("UTF-8"))); - } - } else { - body.setContentType("text/xml"); - if (responseText == null) { - body.setContent(new ByteArrayInputStream("Internal Server Error".getBytes("UTF-8"))); - } - } - - if (responseText != null) { - body.setContent(new ByteArrayInputStream(responseText.getBytes("UTF-8"))); - } - resp.setEntity(body); - } catch (Exception ex) { - s_logger.error("error!", ex); - } - } - - // FIXME: the following two threads are copied from - // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java - // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or - // modify the - // code to be very specific to our needs - static class ListenerThread extends Thread { - private HttpService _httpService = null; - private ServerSocket _serverSocket = null; - private HttpParams _params = null; - - public ListenerThread(ApiServer requestHandler, int port) { - try { - _serverSocket = new ServerSocket(port); - } catch (IOException ioex) { - s_logger.error("error initializing api server", ioex); - return; - } - - _params = new BasicHttpParams(); - _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) - .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) - .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); - - // Set up the HTTP protocol processor - BasicHttpProcessor httpproc = new BasicHttpProcessor(); - httpproc.addInterceptor(new ResponseDate()); - httpproc.addInterceptor(new ResponseServer()); - httpproc.addInterceptor(new ResponseContent()); - httpproc.addInterceptor(new ResponseConnControl()); - - // Set up request handlers - HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); - reqistry.register("*", requestHandler); - - // Set up the HTTP service - _httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory()); - _httpService.setParams(_params); - _httpService.setHandlerResolver(reqistry); - } - - @Override - public void run() { - s_logger.info("ApiServer listening on port " + _serverSocket.getLocalPort()); - while (!Thread.interrupted()) { - try { - // Set up HTTP connection - Socket socket = _serverSocket.accept(); - DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); - conn.bind(socket, _params); - - // Execute a new worker task to handle the request - _executor.execute(new WorkerTask(_httpService, conn, _workerCount++)); - } catch (InterruptedIOException ex) { - break; - } catch (IOException e) { - s_logger.error("I/O error initializing connection thread", e); - break; - } - } - } - } - - static class WorkerTask implements Runnable { - private final HttpService _httpService; - private final HttpServerConnection _conn; - - public WorkerTask(final HttpService httpService, final HttpServerConnection conn, final int count) { - _httpService = httpService; - _conn = conn; - } - - @Override - public void run() { - HttpContext context = new BasicHttpContext(null); - try { - while (!Thread.interrupted() && _conn.isOpen()) { - try { - _httpService.handleRequest(_conn, context); - _conn.close(); - } finally { - StackMaid.current().exitCleanup(); - } - } - } catch (ConnectionClosedException ex) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("ApiServer: Client closed connection"); - } - } catch (IOException ex) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("ApiServer: IOException - " + ex); - } - } catch (HttpException ex) { - s_logger.warn("ApiServer: Unrecoverable HTTP protocol violation" + ex); - } finally { - try { - _conn.shutdown(); - } catch (IOException ignore) { - } - } - } - } - - public String getSerializedApiError(int errorCode, String errorText, Map apiCommandParams, String responseType, Exception ex) { - String responseName = null; - String cmdClassName = null; - - String responseText = null; - - try { - if (errorCode == BaseCmd.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) { - responseName = "errorresponse"; - } else { - Object cmdObj = apiCommandParams.get("command"); - // cmd name can be null when "command" parameter is missing in the request - if (cmdObj != null) { - String cmdName = ((String[]) cmdObj)[0]; - cmdClassName = _apiCommands.getProperty(cmdName); - if (cmdClassName != null) { - Class claz = Class.forName(cmdClassName); - responseName = ((BaseCmd) claz.newInstance()).getCommandName(); - } else { - responseName = "errorresponse"; - } - } - } - ExceptionResponse apiResponse = new ExceptionResponse(); - apiResponse.setErrorCode(errorCode); - apiResponse.setErrorText(errorText); - apiResponse.setResponseName(responseName); - // Also copy over the IdentityProxy object List into this new apiResponse, from - // the exception caught. When invoked from handle(), the exception here can - // be either ServerApiException, PermissionDeniedException or InvalidParameterValue - // Exception. When invoked from ApiServlet's processRequest(), this can be - // a standard exception like NumberFormatException. We'll leave the standard ones alone. - if (ex != null) { - if (ex instanceof ServerApiException || ex instanceof PermissionDeniedException - || ex instanceof InvalidParameterValueException) { - // Cast the exception appropriately and retrieve the IdentityProxy - if (ex instanceof ServerApiException) { - ServerApiException ref = (ServerApiException) ex; - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - for (int i=0; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - } - } - // Also copy over the cserror code and the function/layer in which it was thrown. - apiResponse.setCSErrorCode(ref.getCSErrorCode()); - } else if (ex instanceof PermissionDeniedException) { - PermissionDeniedException ref = (PermissionDeniedException) ex; - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - for (int i=0; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - } - } - // Also copy over the cserror code and the function/layer in which it was thrown. - apiResponse.setCSErrorCode(ref.getCSErrorCode()); - } else if (ex instanceof InvalidParameterValueException) { - InvalidParameterValueException ref = (InvalidParameterValueException) ex; - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - for (int i=0; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - } - } - // Also copy over the cserror code and the function/layer in which it was thrown. - apiResponse.setCSErrorCode(ref.getCSErrorCode()); - } - } - } - SerializationContext.current().setUuidTranslation(true); - responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType); - - } catch (Exception e) { - s_logger.error("Exception responding to http request", e); - } - return responseText; - } -} +// 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.api; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.UnsupportedEncodingException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.security.SecureRandom; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.http.ConnectionClosedException; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpServerConnection; +import org.apache.http.HttpStatus; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.impl.DefaultHttpResponseFactory; +import org.apache.http.impl.DefaultHttpServerConnection; +import org.apache.http.impl.NoConnectionReuseStrategy; +import org.apache.http.impl.SocketHttpServerConnection; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.BasicHttpProcessor; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpRequestHandler; +import org.apache.http.protocol.HttpRequestHandlerRegistry; +import org.apache.http.protocol.HttpService; +import org.apache.http.protocol.ResponseConnControl; +import org.apache.http.protocol.ResponseContent; +import org.apache.http.protocol.ResponseDate; +import org.apache.http.protocol.ResponseServer; +import org.apache.log4j.Logger; + +import com.cloud.api.response.ApiResponseSerializer; +import com.cloud.api.response.ExceptionResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.async.AsyncJob; +import com.cloud.async.AsyncJobManager; +import com.cloud.async.AsyncJobVO; +import com.cloud.cluster.StackMaid; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.event.EventUtils; +import com.cloud.exception.CloudAuthenticationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.user.UserContext; +import com.cloud.user.UserVO; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; +import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.PluggableService; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.encoding.Base64; +import com.cloud.utils.exception.CSExceptionErrorCode; +import com.cloud.uuididentity.dao.IdentityDao; + +public class ApiServer implements HttpRequestHandler { + private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); + private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); + + public static final short ADMIN_COMMAND = 1; + public static final short DOMAIN_ADMIN_COMMAND = 4; + public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2; + public static final short USER_COMMAND = 8; + public static boolean encodeApiResponse = false; + public static String jsonContentType = "text/javascript"; + private Properties _apiCommands = null; + private ApiDispatcher _dispatcher; + private AccountManager _accountMgr = null; + private DomainManager _domainMgr = null; + private AsyncJobManager _asyncMgr = null; + private Account _systemAccount = null; + private User _systemUser = null; + private String serverIpAddress = null; + private String serverPort = null; + + private static int _workerCount = 0; + + private static ApiServer s_instance = null; + private static List s_userCommands = null; + private static List s_resellerCommands = null; // AKA domain-admin + private static List s_adminCommands = null; + private static List s_resourceDomainAdminCommands = null; + private static List s_allCommands = null; + private static List s_pluggableServiceCommands = null; + private static final DateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + + private static ExecutorService _executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("ApiServer")); + + static { + s_userCommands = new ArrayList(); + s_resellerCommands = new ArrayList(); + s_adminCommands = new ArrayList(); + s_resourceDomainAdminCommands = new ArrayList(); + s_allCommands = new ArrayList(); + s_pluggableServiceCommands = new ArrayList(); + } + + private ApiServer() { + } + + public static void initApiServer(String[] apiConfig) { + if (s_instance == null) { + s_instance = new ApiServer(); + s_instance.init(apiConfig); + } + } + + public static ApiServer getInstance() { + // initApiServer(); + return s_instance; + } + + public Properties get_apiCommands() { + return _apiCommands; + } + + public String getServerIpAddress() { + return serverIpAddress; + } + + public String getServerPort() { + return serverPort; + } + + public static boolean isPluggableServiceCommand(String cmdClassName) { + if (s_pluggableServiceCommands != null) { + if (s_pluggableServiceCommands.contains(cmdClassName)) { + return true; + } + } + return false; + } + + private String[] getPluggableServicesApiConfigs() { + List pluggableServicesApiConfigs = new ArrayList(); + + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + List services = locator.getAllPluggableServices(); + for (PluggableService service : services) { + pluggableServicesApiConfigs.add(service.getPropertiesFile()); + } + return pluggableServicesApiConfigs.toArray(new String[0]); + } + + private void processConfigFiles(String[] apiConfig, boolean pluggableServicesConfig) { + try { + if (_apiCommands == null) { + _apiCommands = new Properties(); + } + Properties preProcessedCommands = new Properties(); + if (apiConfig != null) { + for (String configFile : apiConfig) { + File commandsFile = PropertiesUtil.findConfigFile(configFile); + if (commandsFile != null) { + try { + preProcessedCommands.load(new FileInputStream(commandsFile)); + } catch (FileNotFoundException fnfex) { + // in case of a file within a jar in classpath, try to open stream using url + InputStream stream = PropertiesUtil.openStreamFromURL(configFile); + if (stream != null) { + preProcessedCommands.load(stream); + } else { + s_logger.error("Unable to find properites file", fnfex); + } + } + } + } + for (Object key : preProcessedCommands.keySet()) { + String preProcessedCommand = preProcessedCommands.getProperty((String) key); + String[] commandParts = preProcessedCommand.split(";"); + _apiCommands.put(key, commandParts[0]); + + if (pluggableServicesConfig) { + s_pluggableServiceCommands.add(commandParts[0]); + } + + if (commandParts.length > 1) { + try { + short cmdPermissions = Short.parseShort(commandParts[1]); + if ((cmdPermissions & ADMIN_COMMAND) != 0) { + s_adminCommands.add((String) key); + } + if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { + s_resourceDomainAdminCommands.add((String) key); + } + if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { + s_resellerCommands.add((String) key); + } + if ((cmdPermissions & USER_COMMAND) != 0) { + s_userCommands.add((String) key); + } + } catch (NumberFormatException nfe) { + s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand); + } + } + } + + s_allCommands.addAll(s_adminCommands); + s_allCommands.addAll(s_resourceDomainAdminCommands); + s_allCommands.addAll(s_userCommands); + s_allCommands.addAll(s_resellerCommands); + } + } catch (FileNotFoundException fnfex) { + s_logger.error("Unable to find properites file", fnfex); + } catch (IOException ioex) { + s_logger.error("Exception loading properties file", ioex); + } + } + + public void init(String[] apiConfig) { + BaseCmd.setComponents(new ApiResponseHelper()); + BaseListCmd.configure(); + processConfigFiles(apiConfig, false); + + // get commands for all pluggable services + String[] pluggableServicesApiConfigs = getPluggableServicesApiConfigs(); + processConfigFiles(pluggableServicesApiConfigs, true); + + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + _accountMgr = locator.getManager(AccountManager.class); + _asyncMgr = locator.getManager(AsyncJobManager.class); + _systemAccount = _accountMgr.getSystemAccount(); + _systemUser = _accountMgr.getSystemUser(); + _dispatcher = ApiDispatcher.getInstance(); + _domainMgr = locator.getManager(DomainManager.class); + + Integer apiPort = null; // api port, null by default + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + SearchCriteria sc = configDao.createSearchCriteria(); + sc.addAnd("name", SearchCriteria.Op.EQ, "integration.api.port"); + List values = configDao.search(sc, null); + if ((values != null) && (values.size() > 0)) { + ConfigurationVO apiPortConfig = values.get(0); + if (apiPortConfig.getValue() != null) { + apiPort = Integer.parseInt(apiPortConfig.getValue()); + } + } + + encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())); + + String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key()); + if (jsonType != null) { + jsonContentType = jsonType; + } + + if (apiPort != null) { + ListenerThread listenerThread = new ListenerThread(this, apiPort); + + serverIpAddress = listenerThread.getServerIpAddress(); + serverPort = listenerThread.getServerPort(); + listenerThread.start(); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { + // get some information for the access log... + StringBuffer sb = new StringBuffer(); + HttpServerConnection connObj = (HttpServerConnection) context.getAttribute("http.connection"); + if (connObj instanceof SocketHttpServerConnection) { + InetAddress remoteAddr = ((SocketHttpServerConnection) connObj).getRemoteAddress(); + sb.append(remoteAddr.toString() + " -- "); + } + sb.append(request.getRequestLine()); + + try { + String uri = request.getRequestLine().getUri(); + int requestParamsStartIndex = uri.indexOf('?'); + if (requestParamsStartIndex >= 0) { + uri = uri.substring(requestParamsStartIndex + 1); + } + + String[] paramArray = uri.split("&"); + if (paramArray.length < 1) { + s_logger.info("no parameters received for request: " + uri + ", aborting..."); + return; + } + + Map parameterMap = new HashMap(); + + String responseType = BaseCmd.RESPONSE_TYPE_XML; + for (String paramEntry : paramArray) { + String[] paramValue = paramEntry.split("="); + if (paramValue.length != 2) { + s_logger.info("malformed parameter: " + paramEntry + ", skipping"); + continue; + } + if ("response".equalsIgnoreCase(paramValue[0])) { + responseType = paramValue[1]; + } else { + // according to the servlet spec, the parameter map should be in the form (name=String, + // value=String[]), so + // parameter values will be stored in an array + parameterMap.put(/* name */paramValue[0], /* value */new String[] { paramValue[1] }); + } + } + try { + // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM + UserContext.registerContext(_systemUser.getId(), _systemAccount, null, true); + sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") "); + String responseText = handleRequest(parameterMap, true, responseType, sb); + sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length())); + + writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null); + } catch (ServerApiException se) { + String responseText = getSerializedApiError(se.getErrorCode(), se.getDescription(), parameterMap, responseType, se); + writeResponse(response, responseText, se.getErrorCode(), responseType, se.getDescription()); + sb.append(" " + se.getErrorCode() + " " + se.getDescription()); + } catch (RuntimeException e) { + // log runtime exception like NullPointerException to help identify the source easier + s_logger.error("Unhandled exception, ", e); + throw e; + } + } finally { + s_accessLogger.info(sb.toString()); + UserContext.unregisterContext(); + } + } + + @SuppressWarnings("rawtypes") + public String handleRequest(Map params, boolean decode, String responseType, StringBuffer auditTrailSb) throws ServerApiException { + String response = null; + String[] command = null; + try { + command = (String[]) params.get("command"); + if (command == null) { + s_logger.error("invalid request, no command sent"); + if (s_logger.isTraceEnabled()) { + s_logger.trace("dumping request parameters"); + for (Object key : params.keySet()) { + String keyStr = (String) key; + String[] value = (String[]) params.get(key); + s_logger.trace(" key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0])); + } + } + throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent"); + } else { + Map paramMap = new HashMap(); + Set keys = params.keySet(); + Iterator keysIter = keys.iterator(); + while (keysIter.hasNext()) { + String key = (String) keysIter.next(); + if ("command".equalsIgnoreCase(key)) { + continue; + } + String[] value = (String[]) params.get(key); + + String decodedValue = null; + if (decode) { + try { + decodedValue = URLDecoder.decode(value[0], "UTF-8"); + } catch (UnsupportedEncodingException usex) { + s_logger.warn(key + " could not be decoded, value = " + value[0]); + throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0]); + } catch (IllegalArgumentException iae) { + s_logger.warn(key + " could not be decoded, value = " + value[0]); + throw new ServerApiException(BaseCmd.PARAM_ERROR, key + " could not be decoded, received value " + value[0] + " which contains illegal characters eg.%"); + } + } else { + decodedValue = value[0]; + } + paramMap.put(key, decodedValue); + } + String cmdClassName = _apiCommands.getProperty(command[0]); + if (cmdClassName != null) { + Class cmdClass = Class.forName(cmdClassName); + BaseCmd cmdObj = (BaseCmd) cmdClass.newInstance(); + cmdObj.setFullUrlParams(paramMap); + cmdObj.setResponseType(responseType); + // This is where the command is either serialized, or directly dispatched + response = queueCommand(cmdObj, paramMap); + buildAuditTrail(auditTrailSb, command[0], response); + } else { + if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { + String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]); + s_logger.warn(errorString); + auditTrailSb.append(" " + errorString); + throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, errorString); + } + } + } + } catch (Exception ex) { + if (ex instanceof InvalidParameterValueException) { + InvalidParameterValueException ref = (InvalidParameterValueException)ex; + ServerApiException e = new ServerApiException(BaseCmd.PARAM_ERROR, ex.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy obj = idList.get(i); + e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName()); + } + } + // Also copy over the cserror code and the function/layer in which it was thrown. + e.setCSErrorCode(ref.getCSErrorCode()); + throw e; + } else if (ex instanceof PermissionDeniedException) { + PermissionDeniedException ref = (PermissionDeniedException)ex; + ServerApiException e = new ServerApiException(BaseCmd.ACCOUNT_ERROR, ex.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy obj = idList.get(i); + e.addProxyObject(obj.getTableName(), obj.getValue(), obj.getidFieldName()); + } + } + e.setCSErrorCode(ref.getCSErrorCode()); + throw e; + } else if (ex instanceof ServerApiException) { + throw (ServerApiException) ex; + } else { + s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command[0]), ex); + ServerApiException e = new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal server error, unable to execute request."); + e.setCSErrorCode(CSExceptionErrorCode.getCSErrCode("ServerApiException")); + throw e; + } + } + return response; + } + + private String queueCommand(BaseCmd cmdObj, Map params) { + UserContext ctx = UserContext.current(); + Long callerUserId = ctx.getCallerUserId(); + Account caller = ctx.getCaller(); + if (cmdObj instanceof BaseAsyncCmd) { + Long objectId = null; + String objectEntityTable = null; + if (cmdObj instanceof BaseAsyncCreateCmd) { + BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; + _dispatcher.dispatchCreateCmd(createCmd, params); + objectId = createCmd.getEntityId(); + objectEntityTable = createCmd.getEntityTable(); + params.put("id", objectId.toString()); + } else { + ApiDispatcher.setupParameters(cmdObj, params); + ApiDispatcher.plugService(cmdObj); + } + + BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj; + + if (callerUserId != null) { + params.put("ctxUserId", callerUserId.toString()); + } + if (caller != null) { + params.put("ctxAccountId", String.valueOf(caller.getId())); + } + + long startEventId = ctx.getStartEventId(); + asyncCmd.setStartEventId(startEventId); + + // save the scheduled event + Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, + asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), + startEventId); + if (startEventId == 0) { + // There was no create event before, set current event id as start eventId + startEventId = eventId; + } + + params.put("ctxStartEventId", String.valueOf(startEventId)); + + ctx.setAccountId(asyncCmd.getEntityOwnerId()); + + AsyncJobVO job = new AsyncJobVO(); + job.setInstanceId((objectId == null) ? asyncCmd.getInstanceId() : objectId); + job.setInstanceType(asyncCmd.getInstanceType()); + job.setUserId(callerUserId); + job.setAccountId(caller.getId()); + + job.setCmd(cmdObj.getClass().getName()); + job.setCmdInfo(ApiGsonHelper.getBuilder().create().toJson(params)); + + long jobId = _asyncMgr.submitAsyncJob(job); + + if (jobId == 0L) { + String errorMsg = "Unable to schedule async job for command " + job.getCmd(); + s_logger.warn(errorMsg); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, errorMsg); + } + + if (objectId != null) { + SerializationContext.current().setUuidTranslation(true); + return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objectId, objectEntityTable); + } + + SerializationContext.current().setUuidTranslation(true); + return ApiResponseSerializer.toSerializedString(asyncCmd.getResponse(jobId), asyncCmd.getResponseType()); + } else { + _dispatcher.dispatch(cmdObj, params); + + // if the command is of the listXXXCommand, we will need to also return the + // the job id and status if possible + if (cmdObj instanceof BaseListCmd) { + buildAsyncListResponse((BaseListCmd) cmdObj, caller); + } + + SerializationContext.current().setUuidTranslation(true); + return ApiResponseSerializer.toSerializedString((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); + } + } + + private void buildAsyncListResponse(BaseListCmd command, Account account) { + List responses = ((ListResponse) command.getResponseObject()).getResponses(); + if (responses != null && responses.size() > 0) { + List jobs = null; + + // list all jobs for ROOT admin + if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) { + jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), null); + } else { + jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), account.getId()); + } + + if (jobs.size() == 0) { + return; + } + + // Using maps might possibly be more efficient if the set is large enough but for now, we'll just do a + // comparison of two lists. Either way, there shouldn't be too many async jobs active for the account. + for (AsyncJob job : jobs) { + if (job.getInstanceId() == null) { + continue; + } + for (ResponseObject response : responses) { + if (response.getObjectId() != null && job.getInstanceId().longValue() == response.getObjectId().longValue()) { + response.setJobId(job.getId()); + response.setJobStatus(job.getStatus()); + } + } + } + } + } + + private void buildAuditTrail(StringBuffer auditTrailSb, String command, String result) { + if (result == null) { + return; + } + auditTrailSb.append(" " + HttpServletResponse.SC_OK + " "); + auditTrailSb.append(result); + /* + * if (command.equals("queryAsyncJobResult")){ //For this command we need to also log job status and job + * resultcode for + * (Pair pair : resultValues){ String key = pair.first(); if (key.equals("jobstatus")){ + * auditTrailSb.append(" "); auditTrailSb.append(key); auditTrailSb.append("="); + * auditTrailSb.append(pair.second()); + * }else if (key.equals("jobresultcode")){ auditTrailSb.append(" "); auditTrailSb.append(key); + * auditTrailSb.append("="); + * auditTrailSb.append(pair.second()); } } }else { for (Pair pair : resultValues){ if + * (pair.first().equals("jobid")){ // Its an async job so report the jobid auditTrailSb.append(" "); + * auditTrailSb.append(pair.first()); auditTrailSb.append("="); auditTrailSb.append(pair.second()); } } } + */ + } + + private static boolean isCommandAvailable(String commandName) { + boolean isCommandAvailable = false; + isCommandAvailable = s_allCommands.contains(commandName); + return isCommandAvailable; + } + + public boolean verifyRequest(Map requestParameters, Long userId) throws ServerApiException { + try { + String apiKey = null; + String secretKey = null; + String signature = null; + String unsignedRequest = null; + + String[] command = (String[]) requestParameters.get("command"); + if (command == null) { + s_logger.info("missing command, ignoring request..."); + return false; + } + + String commandName = command[0]; + + // if userId not null, that mean that user is logged in + if (userId != null) { + Long accountId = ApiDBUtils.findUserById(userId).getAccountId(); + Account userAccount = _accountMgr.getAccount(accountId); + short accountType = userAccount.getType(); + + if (!isCommandAvailable(accountType, commandName)) { + s_logger.warn("The given command:" + commandName + " does not exist"); + throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command does not exist"); + } + return true; + } else { + // check against every available command to see if the command exists or not + if (!isCommandAvailable(commandName) && !commandName.equals("login") && !commandName.equals("logout")) { + s_logger.warn("The given command:" + commandName + " does not exist"); + throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command does not exist"); + } + } + + // - build a request string with sorted params, make sure it's all lowercase + // - sign the request, verify the signature is the same + List parameterNames = new ArrayList(); + + for (Object paramNameObj : requestParameters.keySet()) { + parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later + } + + Collections.sort(parameterNames); + + String signatureVersion = null; + String expires = null; + + for (String paramName : parameterNames) { + // parameters come as name/value pairs in the form String/String[] + String paramValue = ((String[]) requestParameters.get(paramName))[0]; + + if ("signature".equalsIgnoreCase(paramName)) { + signature = paramValue; + } else { + if ("apikey".equalsIgnoreCase(paramName)) { + apiKey = paramValue; + } + else if ("signatureversion".equalsIgnoreCase(paramName)) { + signatureVersion = paramValue; + } else if ("expires".equalsIgnoreCase(paramName)) { + expires = paramValue; + } + + if (unsignedRequest == null) { + unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); + } else { + unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20"); + } + } + } + + // if api/secret key are passed to the parameters + if ((signature == null) || (apiKey == null)) { + if (s_logger.isDebugEnabled()) { + s_logger.info("expired session, missing signature, or missing apiKey -- ignoring request...sig: " + signature + ", apiKey: " + apiKey); + } + return false; // no signature, bad request + } + + Date expiresTS = null; + if ("3".equals(signatureVersion)) { + // New signature authentication. Check for expire parameter and its validity + if (expires == null) { + s_logger.info("missing Expires parameter -- ignoring request...sig: " + signature + ", apiKey: " + apiKey); + return false; + } + synchronized (_dateFormat) { + try { + expiresTS = _dateFormat.parse(expires); + } catch (ParseException pe) { + s_logger.info("Incorrect date format for Expires parameter", pe); + return false; + } + } + Date now = new Date(System.currentTimeMillis()); + if (expiresTS.before(now)) { + s_logger.info("Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey); + return false; + } + } + + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + User user = null; + // verify there is a user with this api key + Pair userAcctPair = _accountMgr.findUserByApiKey(apiKey); + if (userAcctPair == null) { + s_logger.info("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey); + return false; + } + + user = userAcctPair.first(); + Account account = userAcctPair.second(); + + if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) { + s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() + "; accountState: " + + account.getState()); + return false; + } + + UserContext.updateContext(user.getId(), account, null); + + if (!isCommandAvailable(account.getType(), commandName)) { + s_logger.warn("The given command:" + commandName + " does not exist"); + throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist"); + } + + // verify secret key exists + secretKey = user.getSecretKey(); + if (secretKey == null) { + s_logger.info("User does not have a secret key associated with the account -- ignoring request, username: " + user.getUsername()); + return false; + } + + unsignedRequest = unsignedRequest.toLowerCase(); + + Mac mac = Mac.getInstance("HmacSHA1"); + SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); + mac.init(keySpec); + mac.update(unsignedRequest.getBytes()); + byte[] encryptedBytes = mac.doFinal(); + String computedSignature = Base64.encodeBytes(encryptedBytes); + boolean equalSig = signature.equals(computedSignature); + if (!equalSig) { + s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature); + } + return equalSig; + } catch (Exception ex) { + if (ex instanceof ServerApiException && ((ServerApiException) ex).getErrorCode() == BaseCmd.UNSUPPORTED_ACTION_ERROR) { + throw (ServerApiException) ex; + } + s_logger.error("unable to verifty request signature", ex); + } + return false; + } + + public Long fetchDomainId(String domainUUID){ + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + IdentityDao identityDao = locator.getDao(IdentityDao.class); + try{ + Long domainId = identityDao.getIdentityId("domain", domainUUID); + return domainId; + }catch(InvalidParameterValueException ex){ + return null; + } + } + + public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress ,Map requestParameters) throws CloudAuthenticationException { + // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist + // we will default to ROOT + if (domainId == null) { + if (domainPath == null || domainPath.trim().length() == 0) { + domainId = DomainVO.ROOT_DOMAIN; + } else { + Domain domainObj = _domainMgr.findDomainByPath(domainPath); + if (domainObj != null) { + domainId = domainObj.getId(); + } else { // if an unknown path is passed in, fail the login call + throw new CloudAuthenticationException("Unable to find the domain from the path " + domainPath); + } + } + } + + UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters); + if (userAcct != null) { + String timezone = userAcct.getTimezone(); + float offsetInHrs = 0f; + if (timezone != null) { + TimeZone t = TimeZone.getTimeZone(timezone); + s_logger.info("Current user logged in under " + timezone + " timezone"); + + java.util.Date date = new java.util.Date(); + long longDate = date.getTime(); + float offsetInMs = (t.getOffset(longDate)); + offsetInHrs = offsetInMs / (1000 * 60 * 60); + s_logger.info("Timezone offset from UTC is: " + offsetInHrs); + } + + Account account = _accountMgr.getAccount(userAcct.getAccountId()); + + // set the userId and account object for everyone + session.setAttribute("userid", userAcct.getId()); + UserVO user = (UserVO) _accountMgr.getActiveUser(userAcct.getId()); + if(user.getUuid() != null){ + session.setAttribute("user_UUID", user.getUuid()); + } + + session.setAttribute("username", userAcct.getUsername()); + session.setAttribute("firstname", userAcct.getFirstname()); + session.setAttribute("lastname", userAcct.getLastname()); + session.setAttribute("accountobj", account); + session.setAttribute("account", account.getAccountName()); + + session.setAttribute("domainid", account.getDomainId()); + DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId()); + if(domain.getUuid() != null){ + session.setAttribute("domain_UUID", domain.getUuid()); + } + + session.setAttribute("type", Short.valueOf(account.getType()).toString()); + session.setAttribute("registrationtoken", userAcct.getRegistrationToken()); + session.setAttribute("registered", new Boolean(userAcct.isRegistered()).toString()); + + if (timezone != null) { + session.setAttribute("timezone", timezone); + session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString()); + } + + // (bug 5483) generate a session key that the user must submit on every request to prevent CSRF, add that + // to the login response so that session-based authenticators know to send the key back + SecureRandom sesssionKeyRandom = new SecureRandom(); + byte sessionKeyBytes[] = new byte[20]; + sesssionKeyRandom.nextBytes(sessionKeyBytes); + String sessionKey = Base64.encodeBytes(sessionKeyBytes); + session.setAttribute("sessionkey", sessionKey); + + return; + } + throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials"); + } + + public void logoutUser(long userId) { + _accountMgr.logoutUser(Long.valueOf(userId)); + return; + } + + public boolean verifyUser(Long userId) { + User user = _accountMgr.getUserIncludingRemoved(userId); + Account account = null; + if (user != null) { + account = _accountMgr.getAccount(user.getAccountId()); + } + + if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) || !account.getState().equals(Account.State.enabled)) { + s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API"); + return false; + } + return true; + } + + public static boolean isCommandAvailable(short accountType, String commandName) { + boolean isCommandAvailable = false; + switch (accountType) { + case Account.ACCOUNT_TYPE_ADMIN: + isCommandAvailable = s_adminCommands.contains(commandName); + break; + case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: + isCommandAvailable = s_resellerCommands.contains(commandName); + break; + case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: + isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName); + break; + case Account.ACCOUNT_TYPE_NORMAL: + isCommandAvailable = s_userCommands.contains(commandName); + break; + } + return isCommandAvailable; + } + + // FIXME: rather than isError, we might was to pass in the status code to give more flexibility + private void writeResponse(HttpResponse resp, final String responseText, final int statusCode, String responseType, String reasonPhrase) { + try { + resp.setStatusCode(statusCode); + resp.setReasonPhrase(reasonPhrase); + + BasicHttpEntity body = new BasicHttpEntity(); + if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + // JSON response + body.setContentType(jsonContentType); + if (responseText == null) { + body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes("UTF-8"))); + } + } else { + body.setContentType("text/xml"); + if (responseText == null) { + body.setContent(new ByteArrayInputStream("Internal Server Error".getBytes("UTF-8"))); + } + } + + if (responseText != null) { + body.setContent(new ByteArrayInputStream(responseText.getBytes("UTF-8"))); + } + resp.setEntity(body); + } catch (Exception ex) { + s_logger.error("error!", ex); + } + } + + // FIXME: the following two threads are copied from + // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java + // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or + // modify the + // code to be very specific to our needs + static class ListenerThread extends Thread { + private HttpService _httpService = null; + private ServerSocket _serverSocket = null; + private HttpParams _params = null; + + public ListenerThread(ApiServer requestHandler, int port) { + try { + _serverSocket = new ServerSocket(port); + } catch (IOException ioex) { + s_logger.error("error initializing api server", ioex); + return; + } + + _params = new BasicHttpParams(); + _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) + .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) + .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); + + // Set up the HTTP protocol processor + BasicHttpProcessor httpproc = new BasicHttpProcessor(); + httpproc.addInterceptor(new ResponseDate()); + httpproc.addInterceptor(new ResponseServer()); + httpproc.addInterceptor(new ResponseContent()); + httpproc.addInterceptor(new ResponseConnControl()); + + // Set up request handlers + HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); + reqistry.register("*", requestHandler); + + // Set up the HTTP service + _httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory()); + _httpService.setParams(_params); + _httpService.setHandlerResolver(reqistry); + } + + public String getServerIpAddress() { + String hostName; + InetAddress addrs[] = null; + try { + hostName = InetAddress.getLocalHost().getHostName(); + addrs = InetAddress.getAllByName(hostName); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + String myIp = "UNKNOWN"; + for (InetAddress addr : addrs) { + if (!addr.isLoopbackAddress() && addr.isSiteLocalAddress()) { + myIp = addr.getHostAddress(); + break; + } + } + return myIp; + } + + public String getServerPort() { + return _serverSocket.getLocalPort() + ""; + } + + @Override + public void run() { + s_logger.info("ApiServer listening on port " + _serverSocket.getLocalPort()); + while (!Thread.interrupted()) { + try { + // Set up HTTP connection + Socket socket = _serverSocket.accept(); + DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); + conn.bind(socket, _params); + + // Execute a new worker task to handle the request + _executor.execute(new WorkerTask(_httpService, conn, _workerCount++)); + } catch (InterruptedIOException ex) { + break; + } catch (IOException e) { + s_logger.error("I/O error initializing connection thread", e); + break; + } + } + } + } + + static class WorkerTask implements Runnable { + private final HttpService _httpService; + private final HttpServerConnection _conn; + + public WorkerTask(final HttpService httpService, final HttpServerConnection conn, final int count) { + _httpService = httpService; + _conn = conn; + } + + @Override + public void run() { + HttpContext context = new BasicHttpContext(null); + try { + while (!Thread.interrupted() && _conn.isOpen()) { + try { + _httpService.handleRequest(_conn, context); + _conn.close(); + } finally { + StackMaid.current().exitCleanup(); + } + } + } catch (ConnectionClosedException ex) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("ApiServer: Client closed connection"); + } + } catch (IOException ex) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("ApiServer: IOException - " + ex); + } + } catch (HttpException ex) { + s_logger.warn("ApiServer: Unrecoverable HTTP protocol violation" + ex); + } finally { + try { + _conn.shutdown(); + } catch (IOException ignore) { + } + } + } + } + + public String getSerializedApiError(int errorCode, String errorText, Map apiCommandParams, String responseType, Exception ex) { + String responseName = null; + String cmdClassName = null; + + String responseText = null; + + try { + if (errorCode == BaseCmd.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) { + responseName = "errorresponse"; + } else { + Object cmdObj = apiCommandParams.get("command"); + // cmd name can be null when "command" parameter is missing in the request + if (cmdObj != null) { + String cmdName = ((String[]) cmdObj)[0]; + cmdClassName = _apiCommands.getProperty(cmdName); + if (cmdClassName != null) { + Class claz = Class.forName(cmdClassName); + responseName = ((BaseCmd) claz.newInstance()).getCommandName(); + } else { + responseName = "errorresponse"; + } + } + } + ExceptionResponse apiResponse = new ExceptionResponse(); + apiResponse.setErrorCode(errorCode); + apiResponse.setErrorText(errorText); + apiResponse.setResponseName(responseName); + // Also copy over the IdentityProxy object List into this new apiResponse, from + // the exception caught. When invoked from handle(), the exception here can + // be either ServerApiException, PermissionDeniedException or InvalidParameterValue + // Exception. When invoked from ApiServlet's processRequest(), this can be + // a standard exception like NumberFormatException. We'll leave the standard ones alone. + if (ex != null) { + if (ex instanceof ServerApiException || ex instanceof PermissionDeniedException + || ex instanceof InvalidParameterValueException) { + // Cast the exception appropriately and retrieve the IdentityProxy + if (ex instanceof ServerApiException) { + ServerApiException ref = (ServerApiException) ex; + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + for (int i=0; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + } + } + // Also copy over the cserror code and the function/layer in which it was thrown. + apiResponse.setCSErrorCode(ref.getCSErrorCode()); + } else if (ex instanceof PermissionDeniedException) { + PermissionDeniedException ref = (PermissionDeniedException) ex; + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + for (int i=0; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + } + } + // Also copy over the cserror code and the function/layer in which it was thrown. + apiResponse.setCSErrorCode(ref.getCSErrorCode()); + } else if (ex instanceof InvalidParameterValueException) { + InvalidParameterValueException ref = (InvalidParameterValueException) ex; + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + for (int i=0; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + apiResponse.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + } + } + // Also copy over the cserror code and the function/layer in which it was thrown. + apiResponse.setCSErrorCode(ref.getCSErrorCode()); + } + } + } + SerializationContext.current().setUuidTranslation(true); + responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType); + + } catch (Exception e) { + s_logger.error("Exception responding to http request", e); + } + return responseText; + } +} diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index f367175dfd8..19dfe89ed4c 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -1,460 +1,475 @@ -// 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.configuration; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.cloud.agent.manager.ClusteredAgentManagerImpl; -import com.cloud.alert.AlertManagerImpl; -import com.cloud.alert.dao.AlertDaoImpl; -import com.cloud.async.AsyncJobExecutorContextImpl; -import com.cloud.async.AsyncJobManagerImpl; -import com.cloud.async.SyncQueueManagerImpl; -import com.cloud.async.dao.AsyncJobDaoImpl; -import com.cloud.async.dao.SyncQueueDaoImpl; -import com.cloud.async.dao.SyncQueueItemDaoImpl; -import com.cloud.capacity.CapacityManagerImpl; -import com.cloud.capacity.dao.CapacityDaoImpl; -import com.cloud.certificate.dao.CertificateDaoImpl; -import com.cloud.cluster.CheckPointManagerImpl; -import com.cloud.cluster.ClusterFenceManagerImpl; -import com.cloud.cluster.ClusterManagerImpl; -import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; -import com.cloud.cluster.dao.ManagementServerHostDaoImpl; -import com.cloud.cluster.dao.ManagementServerHostPeerDaoImpl; -import com.cloud.cluster.dao.StackMaidDaoImpl; -import com.cloud.configuration.dao.ConfigurationDaoImpl; -import com.cloud.configuration.dao.ResourceCountDaoImpl; -import com.cloud.configuration.dao.ResourceLimitDaoImpl; -import com.cloud.consoleproxy.ConsoleProxyManagerImpl; -import com.cloud.dao.EntityManager; -import com.cloud.dao.EntityManagerImpl; -import com.cloud.dc.ClusterDetailsDaoImpl; -import com.cloud.dc.dao.AccountVlanMapDaoImpl; -import com.cloud.dc.dao.ClusterDaoImpl; -import com.cloud.dc.dao.ClusterVSMMapDaoImpl; -import com.cloud.dc.dao.DataCenterDaoImpl; -import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; -import com.cloud.dc.dao.DcDetailsDaoImpl; -import com.cloud.dc.dao.HostPodDaoImpl; -import com.cloud.dc.dao.PodVlanMapDaoImpl; -import com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl; -import com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl; -import com.cloud.dc.dao.VlanDaoImpl; -import com.cloud.domain.dao.DomainDaoImpl; -import com.cloud.event.dao.EventDaoImpl; -import com.cloud.event.dao.UsageEventDaoImpl; -import com.cloud.ha.HighAvailabilityManagerImpl; -import com.cloud.ha.dao.HighAvailabilityDaoImpl; -import com.cloud.host.dao.HostDaoImpl; -import com.cloud.host.dao.HostDetailsDaoImpl; -import com.cloud.host.dao.HostTagsDaoImpl; -import com.cloud.hypervisor.HypervisorGuruManagerImpl; -import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl; -import com.cloud.keystore.KeystoreDaoImpl; -import com.cloud.keystore.KeystoreManagerImpl; -import com.cloud.maint.UpgradeManagerImpl; -import com.cloud.maint.dao.AgentUpgradeDaoImpl; -import com.cloud.network.ExternalLoadBalancerUsageManagerImpl; -import com.cloud.network.NetworkManagerImpl; -import com.cloud.network.StorageNetworkManagerImpl; -import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl; -import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; -import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; -import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; -import com.cloud.network.dao.FirewallRulesDaoImpl; -import com.cloud.network.dao.IPAddressDaoImpl; -import com.cloud.network.dao.InlineLoadBalancerNicMapDaoImpl; -import com.cloud.network.dao.LBStickinessPolicyDaoImpl; -import com.cloud.network.dao.LoadBalancerDaoImpl; -import com.cloud.network.dao.LoadBalancerVMMapDaoImpl; -import com.cloud.network.dao.NetworkDaoImpl; -import com.cloud.network.dao.NetworkDomainDaoImpl; -import com.cloud.network.dao.NetworkExternalFirewallDaoImpl; -import com.cloud.network.dao.NetworkExternalLoadBalancerDaoImpl; -import com.cloud.network.dao.NetworkRuleConfigDaoImpl; -import com.cloud.network.dao.NetworkServiceMapDaoImpl; -import com.cloud.network.dao.PhysicalNetworkDaoImpl; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl; -import com.cloud.network.dao.PortProfileDaoImpl; -import com.cloud.network.dao.RemoteAccessVpnDaoImpl; -import com.cloud.network.dao.Site2SiteCustomerGatewayDaoImpl; -import com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl; -import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; -import com.cloud.network.dao.VirtualRouterProviderDaoImpl; -import com.cloud.network.dao.VpnUserDaoImpl; -import com.cloud.network.element.CiscoNexusVSMElement; -import com.cloud.network.element.CiscoNexusVSMElementService; -import com.cloud.network.element.F5ExternalLoadBalancerElement; -import com.cloud.network.element.F5ExternalLoadBalancerElementService; -import com.cloud.network.element.JuniperSRXExternalFirewallElement; -import com.cloud.network.element.JuniperSRXFirewallElementService; -import com.cloud.network.element.NetscalerElement; -import com.cloud.network.element.NetscalerLoadBalancerElementService; -import com.cloud.network.element.VirtualRouterElement; -import com.cloud.network.element.VirtualRouterElementService; -import com.cloud.network.firewall.FirewallManagerImpl; -import com.cloud.network.lb.ElasticLoadBalancerManagerImpl; -import com.cloud.network.lb.LoadBalancingRulesManagerImpl; -import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl; -import com.cloud.network.ovs.OvsTunnelManagerImpl; -import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl; -import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl; -import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; -import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; -import com.cloud.network.rules.RulesManagerImpl; -import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; -import com.cloud.network.security.SecurityGroupManagerImpl2; -import com.cloud.network.security.dao.SecurityGroupDaoImpl; -import com.cloud.network.security.dao.SecurityGroupRuleDaoImpl; -import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; -import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; -import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl; -import com.cloud.network.security.dao.VmRulesetLogDaoImpl; -import com.cloud.network.vpc.NetworkACLManagerImpl; -import com.cloud.network.vpc.VpcManagerImpl; -import com.cloud.network.vpc.Dao.PrivateIpDaoImpl; -import com.cloud.network.vpc.Dao.StaticRouteDaoImpl; -import com.cloud.network.vpc.Dao.VpcDaoImpl; -import com.cloud.network.vpc.Dao.VpcGatewayDaoImpl; -import com.cloud.network.vpc.Dao.VpcOfferingDaoImpl; -import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDaoImpl; -import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; -import com.cloud.network.vpn.Site2SiteVpnManagerImpl; -import com.cloud.offerings.dao.NetworkOfferingDaoImpl; -import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl; -import com.cloud.projects.ProjectManagerImpl; -import com.cloud.projects.dao.ProjectAccountDaoImpl; -import com.cloud.projects.dao.ProjectDaoImpl; -import com.cloud.projects.dao.ProjectInvitationDaoImpl; -import com.cloud.resource.ResourceManagerImpl; -import com.cloud.resourcelimit.ResourceLimitManagerImpl; -import com.cloud.service.dao.ServiceOfferingDaoImpl; -import com.cloud.storage.OCFS2ManagerImpl; -import com.cloud.storage.StorageManagerImpl; -import com.cloud.storage.dao.DiskOfferingDaoImpl; -import com.cloud.storage.dao.GuestOSCategoryDaoImpl; -import com.cloud.storage.dao.GuestOSDaoImpl; -import com.cloud.storage.dao.LaunchPermissionDaoImpl; -import com.cloud.storage.dao.SnapshotDaoImpl; -import com.cloud.storage.dao.SnapshotPolicyDaoImpl; -import com.cloud.storage.dao.SnapshotScheduleDaoImpl; -import com.cloud.storage.dao.StoragePoolDaoImpl; -import com.cloud.storage.dao.StoragePoolHostDaoImpl; -import com.cloud.storage.dao.StoragePoolWorkDaoImpl; -import com.cloud.storage.dao.SwiftDaoImpl; -import com.cloud.storage.dao.UploadDaoImpl; -import com.cloud.storage.dao.VMTemplateDaoImpl; -import com.cloud.storage.dao.VMTemplateDetailsDaoImpl; -import com.cloud.storage.dao.VMTemplateHostDaoImpl; -import com.cloud.storage.dao.VMTemplatePoolDaoImpl; -import com.cloud.storage.dao.VMTemplateSwiftDaoImpl; -import com.cloud.storage.dao.VMTemplateZoneDaoImpl; -import com.cloud.storage.dao.VolumeDaoImpl; -import com.cloud.storage.dao.VolumeHostDaoImpl; -import com.cloud.storage.download.DownloadMonitorImpl; -import com.cloud.storage.secondary.SecondaryStorageManagerImpl; -import com.cloud.storage.snapshot.SnapshotManagerImpl; -import com.cloud.storage.snapshot.SnapshotSchedulerImpl; -import com.cloud.storage.swift.SwiftManagerImpl; -import com.cloud.storage.upload.UploadMonitorImpl; -import com.cloud.tags.TaggedResourceManagerImpl; -import com.cloud.tags.dao.ResourceTagsDaoImpl; -import com.cloud.template.HyervisorTemplateAdapter; -import com.cloud.template.TemplateAdapter; -import com.cloud.template.TemplateAdapter.TemplateAdapterType; -import com.cloud.template.TemplateManagerImpl; -import com.cloud.user.AccountDetailsDaoImpl; -import com.cloud.user.AccountManagerImpl; -import com.cloud.user.DomainManagerImpl; -import com.cloud.user.dao.AccountDaoImpl; -import com.cloud.user.dao.SSHKeyPairDaoImpl; -import com.cloud.user.dao.UserAccountDaoImpl; -import com.cloud.user.dao.UserDaoImpl; -import com.cloud.user.dao.UserStatisticsDaoImpl; -import com.cloud.user.dao.UserStatsLogDaoImpl; -import com.cloud.utils.component.Adapter; -import com.cloud.utils.component.ComponentLibrary; -import com.cloud.utils.component.ComponentLibraryBase; -import com.cloud.utils.component.ComponentLocator.ComponentInfo; -import com.cloud.utils.component.Manager; -import com.cloud.utils.component.PluggableService; -import com.cloud.utils.db.GenericDao; -import com.cloud.uuididentity.IdentityServiceImpl; -import com.cloud.uuididentity.dao.IdentityDaoImpl; -import com.cloud.vm.ClusteredVirtualMachineManagerImpl; -import com.cloud.vm.ItWorkDaoImpl; -import com.cloud.vm.UserVmManagerImpl; -import com.cloud.vm.dao.ConsoleProxyDaoImpl; -import com.cloud.vm.dao.DomainRouterDaoImpl; -import com.cloud.vm.dao.InstanceGroupDaoImpl; -import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl; -import com.cloud.vm.dao.NicDaoImpl; -import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; -import com.cloud.vm.dao.UserVmDaoImpl; -import com.cloud.vm.dao.UserVmDetailsDaoImpl; -import com.cloud.vm.dao.VMInstanceDaoImpl; - - -public class DefaultComponentLibrary extends ComponentLibraryBase implements ComponentLibrary { - protected void populateDaos() { - addDao("StackMaidDao", StackMaidDaoImpl.class); - addDao("VMTemplateZoneDao", VMTemplateZoneDaoImpl.class); - addDao("VMTemplateDetailsDao", VMTemplateDetailsDaoImpl.class); - addDao("DomainRouterDao", DomainRouterDaoImpl.class); - addDao("HostDao", HostDaoImpl.class); - addDao("VMInstanceDao", VMInstanceDaoImpl.class); - addDao("UserVmDao", UserVmDaoImpl.class); - ComponentInfo> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class); - info.addParameter("cache.size", "50"); - info.addParameter("cache.time.to.live", "600"); - info = addDao("DiskOfferingDao", DiskOfferingDaoImpl.class); - info.addParameter("cache.size", "50"); - info.addParameter("cache.time.to.live", "600"); - info = addDao("DataCenterDao", DataCenterDaoImpl.class); - info.addParameter("cache.size", "50"); - info.addParameter("cache.time.to.live", "600"); - info = addDao("HostPodDao", HostPodDaoImpl.class); - info.addParameter("cache.size", "50"); - info.addParameter("cache.time.to.live", "600"); - addDao("IPAddressDao", IPAddressDaoImpl.class); - info = addDao("VlanDao", VlanDaoImpl.class); - info.addParameter("cache.size", "30"); - info.addParameter("cache.time.to.live", "3600"); - addDao("PodVlanMapDao", PodVlanMapDaoImpl.class); - addDao("AccountVlanMapDao", AccountVlanMapDaoImpl.class); - addDao("VolumeDao", VolumeDaoImpl.class); - addDao("EventDao", EventDaoImpl.class); - info = addDao("UserDao", UserDaoImpl.class); - info.addParameter("cache.size", "5000"); - info.addParameter("cache.time.to.live", "300"); - addDao("UserStatisticsDao", UserStatisticsDaoImpl.class); - addDao("UserStatsLogDao", UserStatsLogDaoImpl.class); - addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); - addDao("LoadBalancerDao", LoadBalancerDaoImpl.class); - addDao("NetworkRuleConfigDao", NetworkRuleConfigDaoImpl.class); - addDao("LoadBalancerVMMapDao", LoadBalancerVMMapDaoImpl.class); - addDao("LBStickinessPolicyDao", LBStickinessPolicyDaoImpl.class); - addDao("DataCenterIpAddressDao", DataCenterIpAddressDaoImpl.class); - addDao("SecurityGroupDao", SecurityGroupDaoImpl.class); - addDao("SecurityGroupRuleDao", SecurityGroupRuleDaoImpl.class); - addDao("SecurityGroupVMMapDao", SecurityGroupVMMapDaoImpl.class); - addDao("SecurityGroupRulesDao", SecurityGroupRulesDaoImpl.class); - addDao("SecurityGroupWorkDao", SecurityGroupWorkDaoImpl.class); - addDao("VmRulesetLogDao", VmRulesetLogDaoImpl.class); - addDao("AlertDao", AlertDaoImpl.class); - addDao("CapacityDao", CapacityDaoImpl.class); - addDao("DomainDao", DomainDaoImpl.class); - addDao("AccountDao", AccountDaoImpl.class); - addDao("ResourceLimitDao", ResourceLimitDaoImpl.class); - addDao("ResourceCountDao", ResourceCountDaoImpl.class); - addDao("UserAccountDao", UserAccountDaoImpl.class); - addDao("VMTemplateHostDao", VMTemplateHostDaoImpl.class); - addDao("VolumeHostDao", VolumeHostDaoImpl.class); - addDao("VMTemplateSwiftDao", VMTemplateSwiftDaoImpl.class); - addDao("UploadDao", UploadDaoImpl.class); - addDao("VMTemplatePoolDao", VMTemplatePoolDaoImpl.class); - addDao("LaunchPermissionDao", LaunchPermissionDaoImpl.class); - addDao("ConfigurationDao", ConfigurationDaoImpl.class); - info = addDao("VMTemplateDao", VMTemplateDaoImpl.class); - info.addParameter("cache.size", "100"); - info.addParameter("cache.time.to.live", "600"); - info.addParameter("routing.uniquename", "routing"); - addDao("HighAvailabilityDao", HighAvailabilityDaoImpl.class); - addDao("ConsoleProxyDao", ConsoleProxyDaoImpl.class); - addDao("SecondaryStorageVmDao", SecondaryStorageVmDaoImpl.class); - addDao("ManagementServerHostDao", ManagementServerHostDaoImpl.class); - addDao("ManagementServerHostPeerDao", ManagementServerHostPeerDaoImpl.class); - addDao("AgentUpgradeDao", AgentUpgradeDaoImpl.class); - addDao("SnapshotDao", SnapshotDaoImpl.class); - addDao("AsyncJobDao", AsyncJobDaoImpl.class); - addDao("SyncQueueDao", SyncQueueDaoImpl.class); - addDao("SyncQueueItemDao", SyncQueueItemDaoImpl.class); - addDao("GuestOSDao", GuestOSDaoImpl.class); - addDao("GuestOSCategoryDao", GuestOSCategoryDaoImpl.class); - addDao("StoragePoolDao", StoragePoolDaoImpl.class); - addDao("StoragePoolHostDao", StoragePoolHostDaoImpl.class); - addDao("DetailsDao", HostDetailsDaoImpl.class); - addDao("SnapshotPolicyDao", SnapshotPolicyDaoImpl.class); - addDao("SnapshotScheduleDao", SnapshotScheduleDaoImpl.class); - addDao("ClusterDao", ClusterDaoImpl.class); - addDao("CertificateDao", CertificateDaoImpl.class); - addDao("NetworkConfigurationDao", NetworkDaoImpl.class); - addDao("NetworkOfferingDao", NetworkOfferingDaoImpl.class); - addDao("NicDao", NicDaoImpl.class); - addDao("InstanceGroupDao", InstanceGroupDaoImpl.class); - addDao("InstanceGroupVMMapDao", InstanceGroupVMMapDaoImpl.class); - addDao("RemoteAccessVpnDao", RemoteAccessVpnDaoImpl.class); - addDao("VpnUserDao", VpnUserDaoImpl.class); - addDao("ItWorkDao", ItWorkDaoImpl.class); - addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); - addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class); - addDao("FirewallRulesCidrsDao", FirewallRulesCidrsDaoImpl.class); - addDao("SSHKeyPairDao", SSHKeyPairDaoImpl.class); - addDao("UsageEventDao", UsageEventDaoImpl.class); - addDao("ClusterDetailsDao", ClusterDetailsDaoImpl.class); - addDao("UserVmDetailsDao", UserVmDetailsDaoImpl.class); - addDao("OvsTunnelInterfaceDao", OvsTunnelInterfaceDaoImpl.class); - addDao("OvsTunnelAccountDao", OvsTunnelNetworkDaoImpl.class); - addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class); - addDao("HostTagsDao", HostTagsDaoImpl.class); - addDao("NetworkDomainDao", NetworkDomainDaoImpl.class); - addDao("KeystoreDao", KeystoreDaoImpl.class); - addDao("DcDetailsDao", DcDetailsDaoImpl.class); - addDao("SwiftDao", SwiftDaoImpl.class); - addDao("AgentTransferMapDao", HostTransferMapDaoImpl.class); - addDao("ProjectDao", ProjectDaoImpl.class); - addDao("InlineLoadBalancerNicMapDao", InlineLoadBalancerNicMapDaoImpl.class); - addDao("ElasticLbVmMap", ElasticLbVmMapDaoImpl.class); - addDao("ProjectsAccountDao", ProjectAccountDaoImpl.class); - addDao("ProjectInvitationDao", ProjectInvitationDaoImpl.class); - addDao("IdentityDao", IdentityDaoImpl.class); - addDao("AccountDetailsDao", AccountDetailsDaoImpl.class); - addDao("NetworkOfferingServiceMapDao", NetworkOfferingServiceMapDaoImpl.class); - info = addDao("HypervisorCapabilitiesDao",HypervisorCapabilitiesDaoImpl.class); - info.addParameter("cache.size", "100"); - info.addParameter("cache.time.to.live", "600"); - addDao("PhysicalNetworkDao", PhysicalNetworkDaoImpl.class); - addDao("PhysicalNetworkServiceProviderDao", PhysicalNetworkServiceProviderDaoImpl.class); - addDao("VirtualRouterProviderDao", VirtualRouterProviderDaoImpl.class); - addDao("ExternalLoadBalancerDeviceDao", ExternalLoadBalancerDeviceDaoImpl.class); - addDao("ExternalFirewallDeviceDao", ExternalFirewallDeviceDaoImpl.class); - addDao("NetworkExternalLoadBalancerDao", NetworkExternalLoadBalancerDaoImpl.class); - addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class); - addDao("CiscoNexusVSMDeviceDao", CiscoNexusVSMDeviceDaoImpl.class); - addDao("ClusterVSMMapDao", ClusterVSMMapDaoImpl.class); - addDao("PortProfileDao", PortProfileDaoImpl.class); - addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class); - addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class); - addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); - addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class); - addDao("TagsDao", ResourceTagsDaoImpl.class); - addDao("VpcDao", VpcDaoImpl.class); - addDao("VpcOfferingDao", VpcOfferingDaoImpl.class); - addDao("VpcOfferingServiceMapDao", VpcOfferingServiceMapDaoImpl.class); - addDao("PrivateIpDao", PrivateIpDaoImpl.class); - addDao("VpcGatewayDao", VpcGatewayDaoImpl.class); - addDao("StaticRouteDao", StaticRouteDaoImpl.class); - addDao("Site2SiteVpnGatewayDao", Site2SiteVpnGatewayDaoImpl.class); - addDao("Site2SiteCustomerGatewayDao", Site2SiteCustomerGatewayDaoImpl.class); - addDao("Site2SiteVpnConnnectionDao", Site2SiteVpnConnectionDaoImpl.class); - } - - @Override - public synchronized Map>> getDaos() { - if (_daos.size() == 0) { - populateDaos(); - } - return _daos; - } - - protected void populateManagers() { - addManager("StackMaidManager", CheckPointManagerImpl.class); - addManager("Cluster Manager", ClusterManagerImpl.class); - addManager("ClusterFenceManager", ClusterFenceManagerImpl.class); - addManager("ClusteredAgentManager", ClusteredAgentManagerImpl.class); - addManager("SyncQueueManager", SyncQueueManagerImpl.class); - addManager("AsyncJobManager", AsyncJobManagerImpl.class); - addManager("AsyncJobExecutorContext", AsyncJobExecutorContextImpl.class); - addManager("configuration manager", ConfigurationManagerImpl.class); - addManager("account manager", AccountManagerImpl.class); - addManager("domain manager", DomainManagerImpl.class); - addManager("resource limit manager", ResourceLimitManagerImpl.class); - addManager("network manager", NetworkManagerImpl.class); - addManager("download manager", DownloadMonitorImpl.class); - addManager("upload manager", UploadMonitorImpl.class); - addManager("keystore manager", KeystoreManagerImpl.class); - addManager("secondary storage vm manager", SecondaryStorageManagerImpl.class); - addManager("vm manager", UserVmManagerImpl.class); - addManager("upgrade manager", UpgradeManagerImpl.class); - addManager("StorageManager", StorageManagerImpl.class); - addManager("Alert Manager", AlertManagerImpl.class); - addManager("Template Manager", TemplateManagerImpl.class); - addManager("Snapshot Manager", SnapshotManagerImpl.class); - addManager("SnapshotScheduler", SnapshotSchedulerImpl.class); - addManager("SecurityGroupManager", SecurityGroupManagerImpl2.class); - addManager("DomainRouterManager", VirtualNetworkApplianceManagerImpl.class); - addManager("EntityManager", EntityManagerImpl.class); - addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class); - addManager("RulesManager", RulesManagerImpl.class); - addManager("RemoteAccessVpnManager", RemoteAccessVpnManagerImpl.class); - addManager("OvsTunnelManager", OvsTunnelManagerImpl.class); - addManager("Capacity Manager", CapacityManagerImpl.class); - addManager("VirtualMachineManager", ClusteredVirtualMachineManagerImpl.class); - addManager("HypervisorGuruManager", HypervisorGuruManagerImpl.class); - addManager("ResourceManager", ResourceManagerImpl.class); - addManager("IdentityManager", IdentityServiceImpl.class); - addManager("OCFS2Manager", OCFS2ManagerImpl.class); - addManager("FirewallManager", FirewallManagerImpl.class); - ComponentInfo info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class); - info.addParameter("consoleproxy.sslEnabled", "true"); - addManager("ProjectManager", ProjectManagerImpl.class); - addManager("ElasticLoadBalancerManager", ElasticLoadBalancerManagerImpl.class); - addManager("SwiftManager", SwiftManagerImpl.class); - addManager("StorageNetworkManager", StorageNetworkManagerImpl.class); - addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class); - addManager("HA Manager", HighAvailabilityManagerImpl.class); - addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class); - addManager("VPC Manager", VpcManagerImpl.class); - addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class); - addManager("NetworkACLManager", NetworkACLManagerImpl.class); - addManager("Site2SiteVpnManager", Site2SiteVpnManagerImpl.class); - } - - @Override - public synchronized Map> getManagers() { - if (_managers.size() == 0) { - populateManagers(); - } - return _managers; - } - - protected void populateAdapters() { - addAdapter(TemplateAdapter.class, TemplateAdapterType.Hypervisor.getName(), HyervisorTemplateAdapter.class); - } - - @Override - public synchronized Map>> getAdapters() { - if (_adapters.size() == 0) { - populateAdapters(); - } - return _adapters; - } - - @Override - public synchronized Map, Class> getFactories() { - HashMap, Class> factories = new HashMap, Class>(); - factories.put(EntityManager.class, EntityManagerImpl.class); - return factories; - } - - protected void populateServices() { - addService("VirtualRouterElementService", VirtualRouterElementService.class, VirtualRouterElement.class); - addService("NetscalerExternalLoadBalancerElementService", NetscalerLoadBalancerElementService.class, NetscalerElement.class); - addService("F5LoadBalancerElementService", F5ExternalLoadBalancerElementService.class, F5ExternalLoadBalancerElement.class); - addService("JuniperSRXFirewallElementService", JuniperSRXFirewallElementService.class, JuniperSRXExternalFirewallElement.class); - addService("CiscoNexusVSMElementService", CiscoNexusVSMElementService.class, CiscoNexusVSMElement.class); - } - - @Override - public synchronized Map> getPluggableServices() { - if (_pluggableServices.size() == 0) { - populateServices(); - } - return _pluggableServices; - } -} +// 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.configuration; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.cloud.agent.manager.ClusteredAgentManagerImpl; +import com.cloud.alert.AlertManagerImpl; +import com.cloud.alert.dao.AlertDaoImpl; +import com.cloud.async.AsyncJobExecutorContextImpl; +import com.cloud.async.AsyncJobManagerImpl; +import com.cloud.async.SyncQueueManagerImpl; +import com.cloud.async.dao.AsyncJobDaoImpl; +import com.cloud.async.dao.SyncQueueDaoImpl; +import com.cloud.async.dao.SyncQueueItemDaoImpl; +import com.cloud.capacity.CapacityManagerImpl; +import com.cloud.capacity.dao.CapacityDaoImpl; +import com.cloud.certificate.dao.CertificateDaoImpl; +import com.cloud.cluster.CheckPointManagerImpl; +import com.cloud.cluster.ClusterFenceManagerImpl; +import com.cloud.cluster.ClusterManagerImpl; +import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; +import com.cloud.cluster.dao.ManagementServerHostDaoImpl; +import com.cloud.cluster.dao.ManagementServerHostPeerDaoImpl; +import com.cloud.cluster.dao.StackMaidDaoImpl; +import com.cloud.configuration.dao.ConfigurationDaoImpl; +import com.cloud.configuration.dao.ResourceCountDaoImpl; +import com.cloud.configuration.dao.ResourceLimitDaoImpl; +import com.cloud.consoleproxy.ConsoleProxyManagerImpl; +import com.cloud.dao.EntityManager; +import com.cloud.dao.EntityManagerImpl; +import com.cloud.dc.ClusterDetailsDaoImpl; +import com.cloud.dc.dao.AccountVlanMapDaoImpl; +import com.cloud.dc.dao.ClusterDaoImpl; +import com.cloud.dc.dao.ClusterVSMMapDaoImpl; +import com.cloud.dc.dao.DataCenterDaoImpl; +import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; +import com.cloud.dc.dao.DcDetailsDaoImpl; +import com.cloud.dc.dao.HostPodDaoImpl; +import com.cloud.dc.dao.PodVlanMapDaoImpl; +import com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl; +import com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl; +import com.cloud.dc.dao.VlanDaoImpl; +import com.cloud.domain.dao.DomainDaoImpl; +import com.cloud.event.dao.EventDaoImpl; +import com.cloud.event.dao.UsageEventDaoImpl; +import com.cloud.ha.HighAvailabilityManagerImpl; +import com.cloud.ha.dao.HighAvailabilityDaoImpl; +import com.cloud.host.dao.HostDaoImpl; +import com.cloud.host.dao.HostDetailsDaoImpl; +import com.cloud.host.dao.HostTagsDaoImpl; +import com.cloud.hypervisor.HypervisorGuruManagerImpl; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl; +import com.cloud.keystore.KeystoreDaoImpl; +import com.cloud.keystore.KeystoreManagerImpl; +import com.cloud.maint.UpgradeManagerImpl; +import com.cloud.maint.dao.AgentUpgradeDaoImpl; +import com.cloud.network.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.ConditionDaoImpl; +import com.cloud.network.as.dao.CounterDaoImpl; +import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl; +import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; +import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; +import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; +import com.cloud.network.dao.FirewallRulesDaoImpl; +import com.cloud.network.dao.IPAddressDaoImpl; +import com.cloud.network.dao.InlineLoadBalancerNicMapDaoImpl; +import com.cloud.network.dao.LBStickinessPolicyDaoImpl; +import com.cloud.network.as.dao.AutoScaleVmProfileDaoImpl; +import com.cloud.network.dao.LoadBalancerDaoImpl; +import com.cloud.network.dao.LoadBalancerVMMapDaoImpl; +import com.cloud.network.dao.NetworkDaoImpl; +import com.cloud.network.dao.NetworkDomainDaoImpl; +import com.cloud.network.dao.NetworkExternalFirewallDaoImpl; +import com.cloud.network.dao.NetworkExternalLoadBalancerDaoImpl; +import com.cloud.network.dao.NetworkRuleConfigDaoImpl; +import com.cloud.network.dao.NetworkServiceMapDaoImpl; +import com.cloud.network.dao.PhysicalNetworkDaoImpl; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl; +import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl; +import com.cloud.network.dao.PortProfileDaoImpl; +import com.cloud.network.dao.RemoteAccessVpnDaoImpl; +import com.cloud.network.dao.Site2SiteCustomerGatewayDaoImpl; +import com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl; +import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; +import com.cloud.network.dao.VirtualRouterProviderDaoImpl; +import com.cloud.network.dao.VpnUserDaoImpl; +import com.cloud.network.element.CiscoNexusVSMElement; +import com.cloud.network.element.CiscoNexusVSMElementService; +import com.cloud.network.element.F5ExternalLoadBalancerElement; +import com.cloud.network.element.F5ExternalLoadBalancerElementService; +import com.cloud.network.element.JuniperSRXExternalFirewallElement; +import com.cloud.network.element.JuniperSRXFirewallElementService; +import com.cloud.network.element.NetscalerElement; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.network.element.VirtualRouterElement; +import com.cloud.network.element.VirtualRouterElementService; +import com.cloud.network.firewall.FirewallManagerImpl; +import com.cloud.network.lb.ElasticLoadBalancerManagerImpl; +import com.cloud.network.lb.LoadBalancingRulesManagerImpl; +import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl; +import com.cloud.network.ovs.OvsTunnelManagerImpl; +import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl; +import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl; +import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; +import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; +import com.cloud.network.rules.RulesManagerImpl; +import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; +import com.cloud.network.security.SecurityGroupManagerImpl2; +import com.cloud.network.security.dao.SecurityGroupDaoImpl; +import com.cloud.network.security.dao.SecurityGroupRuleDaoImpl; +import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; +import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; +import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl; +import com.cloud.network.security.dao.VmRulesetLogDaoImpl; +import com.cloud.network.vpc.NetworkACLManagerImpl; +import com.cloud.network.vpc.VpcManagerImpl; +import com.cloud.network.vpc.Dao.PrivateIpDaoImpl; +import com.cloud.network.vpc.Dao.StaticRouteDaoImpl; +import com.cloud.network.vpc.Dao.VpcDaoImpl; +import com.cloud.network.vpc.Dao.VpcGatewayDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDaoImpl; +import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; +import com.cloud.network.vpn.Site2SiteVpnManagerImpl; +import com.cloud.offerings.dao.NetworkOfferingDaoImpl; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl; +import com.cloud.projects.ProjectManagerImpl; +import com.cloud.projects.dao.ProjectAccountDaoImpl; +import com.cloud.projects.dao.ProjectDaoImpl; +import com.cloud.projects.dao.ProjectInvitationDaoImpl; +import com.cloud.resource.ResourceManagerImpl; +import com.cloud.resourcelimit.ResourceLimitManagerImpl; +import com.cloud.service.dao.ServiceOfferingDaoImpl; +import com.cloud.storage.OCFS2ManagerImpl; +import com.cloud.storage.StorageManagerImpl; +import com.cloud.storage.dao.DiskOfferingDaoImpl; +import com.cloud.storage.dao.GuestOSCategoryDaoImpl; +import com.cloud.storage.dao.GuestOSDaoImpl; +import com.cloud.storage.dao.LaunchPermissionDaoImpl; +import com.cloud.storage.dao.SnapshotDaoImpl; +import com.cloud.storage.dao.SnapshotPolicyDaoImpl; +import com.cloud.storage.dao.SnapshotScheduleDaoImpl; +import com.cloud.storage.dao.StoragePoolDaoImpl; +import com.cloud.storage.dao.StoragePoolHostDaoImpl; +import com.cloud.storage.dao.StoragePoolWorkDaoImpl; +import com.cloud.storage.dao.SwiftDaoImpl; +import com.cloud.storage.dao.UploadDaoImpl; +import com.cloud.storage.dao.VMTemplateDaoImpl; +import com.cloud.storage.dao.VMTemplateDetailsDaoImpl; +import com.cloud.storage.dao.VMTemplateHostDaoImpl; +import com.cloud.storage.dao.VMTemplatePoolDaoImpl; +import com.cloud.storage.dao.VMTemplateSwiftDaoImpl; +import com.cloud.storage.dao.VMTemplateZoneDaoImpl; +import com.cloud.storage.dao.VolumeDaoImpl; +import com.cloud.storage.dao.VolumeHostDaoImpl; +import com.cloud.storage.download.DownloadMonitorImpl; +import com.cloud.storage.secondary.SecondaryStorageManagerImpl; +import com.cloud.storage.snapshot.SnapshotManagerImpl; +import com.cloud.storage.snapshot.SnapshotSchedulerImpl; +import com.cloud.storage.swift.SwiftManagerImpl; +import com.cloud.storage.upload.UploadMonitorImpl; +import com.cloud.tags.TaggedResourceManagerImpl; +import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.template.HyervisorTemplateAdapter; +import com.cloud.template.TemplateAdapter; +import com.cloud.template.TemplateAdapter.TemplateAdapterType; +import com.cloud.template.TemplateManagerImpl; +import com.cloud.user.AccountDetailsDaoImpl; +import com.cloud.user.AccountManagerImpl; +import com.cloud.user.DomainManagerImpl; +import com.cloud.user.dao.AccountDaoImpl; +import com.cloud.user.dao.SSHKeyPairDaoImpl; +import com.cloud.user.dao.UserAccountDaoImpl; +import com.cloud.user.dao.UserDaoImpl; +import com.cloud.user.dao.UserStatisticsDaoImpl; +import com.cloud.user.dao.UserStatsLogDaoImpl; +import com.cloud.utils.component.Adapter; +import com.cloud.utils.component.ComponentLibrary; +import com.cloud.utils.component.ComponentLibraryBase; +import com.cloud.utils.component.ComponentLocator.ComponentInfo; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.PluggableService; +import com.cloud.utils.db.GenericDao; +import com.cloud.uuididentity.IdentityServiceImpl; +import com.cloud.uuididentity.dao.IdentityDaoImpl; +import com.cloud.vm.ClusteredVirtualMachineManagerImpl; +import com.cloud.vm.ItWorkDaoImpl; +import com.cloud.vm.UserVmManagerImpl; +import com.cloud.vm.dao.ConsoleProxyDaoImpl; +import com.cloud.vm.dao.DomainRouterDaoImpl; +import com.cloud.vm.dao.InstanceGroupDaoImpl; +import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl; +import com.cloud.vm.dao.NicDaoImpl; +import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; +import com.cloud.vm.dao.UserVmDaoImpl; +import com.cloud.vm.dao.UserVmDetailsDaoImpl; +import com.cloud.vm.dao.VMInstanceDaoImpl; + +public class DefaultComponentLibrary extends ComponentLibraryBase implements ComponentLibrary { + protected void populateDaos() { + addDao("StackMaidDao", StackMaidDaoImpl.class); + addDao("VMTemplateZoneDao", VMTemplateZoneDaoImpl.class); + addDao("VMTemplateDetailsDao", VMTemplateDetailsDaoImpl.class); + addDao("DomainRouterDao", DomainRouterDaoImpl.class); + addDao("HostDao", HostDaoImpl.class); + addDao("VMInstanceDao", VMInstanceDaoImpl.class); + addDao("UserVmDao", UserVmDaoImpl.class); + ComponentInfo> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class); + info.addParameter("cache.size", "50"); + info.addParameter("cache.time.to.live", "600"); + info = addDao("DiskOfferingDao", DiskOfferingDaoImpl.class); + info.addParameter("cache.size", "50"); + info.addParameter("cache.time.to.live", "600"); + info = addDao("DataCenterDao", DataCenterDaoImpl.class); + info.addParameter("cache.size", "50"); + info.addParameter("cache.time.to.live", "600"); + info = addDao("HostPodDao", HostPodDaoImpl.class); + info.addParameter("cache.size", "50"); + info.addParameter("cache.time.to.live", "600"); + addDao("IPAddressDao", IPAddressDaoImpl.class); + info = addDao("VlanDao", VlanDaoImpl.class); + info.addParameter("cache.size", "30"); + info.addParameter("cache.time.to.live", "3600"); + addDao("PodVlanMapDao", PodVlanMapDaoImpl.class); + addDao("AccountVlanMapDao", AccountVlanMapDaoImpl.class); + addDao("VolumeDao", VolumeDaoImpl.class); + addDao("EventDao", EventDaoImpl.class); + info = addDao("UserDao", UserDaoImpl.class); + info.addParameter("cache.size", "5000"); + info.addParameter("cache.time.to.live", "300"); + addDao("UserStatisticsDao", UserStatisticsDaoImpl.class); + addDao("UserStatsLogDao", UserStatsLogDaoImpl.class); + addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); + addDao("LoadBalancerDao", LoadBalancerDaoImpl.class); + addDao("NetworkRuleConfigDao", NetworkRuleConfigDaoImpl.class); + addDao("LoadBalancerVMMapDao", LoadBalancerVMMapDaoImpl.class); + addDao("LBStickinessPolicyDao", LBStickinessPolicyDaoImpl.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); + addDao("SecurityGroupVMMapDao", SecurityGroupVMMapDaoImpl.class); + addDao("SecurityGroupRulesDao", SecurityGroupRulesDaoImpl.class); + addDao("SecurityGroupWorkDao", SecurityGroupWorkDaoImpl.class); + addDao("VmRulesetLogDao", VmRulesetLogDaoImpl.class); + addDao("AlertDao", AlertDaoImpl.class); + addDao("CapacityDao", CapacityDaoImpl.class); + addDao("DomainDao", DomainDaoImpl.class); + addDao("AccountDao", AccountDaoImpl.class); + addDao("ResourceLimitDao", ResourceLimitDaoImpl.class); + addDao("ResourceCountDao", ResourceCountDaoImpl.class); + addDao("UserAccountDao", UserAccountDaoImpl.class); + addDao("VMTemplateHostDao", VMTemplateHostDaoImpl.class); + addDao("VolumeHostDao", VolumeHostDaoImpl.class); + addDao("VMTemplateSwiftDao", VMTemplateSwiftDaoImpl.class); + addDao("UploadDao", UploadDaoImpl.class); + addDao("VMTemplatePoolDao", VMTemplatePoolDaoImpl.class); + addDao("LaunchPermissionDao", LaunchPermissionDaoImpl.class); + addDao("ConfigurationDao", ConfigurationDaoImpl.class); + info = addDao("VMTemplateDao", VMTemplateDaoImpl.class); + info.addParameter("cache.size", "100"); + info.addParameter("cache.time.to.live", "600"); + info.addParameter("routing.uniquename", "routing"); + addDao("HighAvailabilityDao", HighAvailabilityDaoImpl.class); + addDao("ConsoleProxyDao", ConsoleProxyDaoImpl.class); + addDao("SecondaryStorageVmDao", SecondaryStorageVmDaoImpl.class); + addDao("ManagementServerHostDao", ManagementServerHostDaoImpl.class); + addDao("ManagementServerHostPeerDao", ManagementServerHostPeerDaoImpl.class); + addDao("AgentUpgradeDao", AgentUpgradeDaoImpl.class); + addDao("SnapshotDao", SnapshotDaoImpl.class); + addDao("AsyncJobDao", AsyncJobDaoImpl.class); + addDao("SyncQueueDao", SyncQueueDaoImpl.class); + addDao("SyncQueueItemDao", SyncQueueItemDaoImpl.class); + addDao("GuestOSDao", GuestOSDaoImpl.class); + addDao("GuestOSCategoryDao", GuestOSCategoryDaoImpl.class); + addDao("StoragePoolDao", StoragePoolDaoImpl.class); + addDao("StoragePoolHostDao", StoragePoolHostDaoImpl.class); + addDao("DetailsDao", HostDetailsDaoImpl.class); + addDao("SnapshotPolicyDao", SnapshotPolicyDaoImpl.class); + addDao("SnapshotScheduleDao", SnapshotScheduleDaoImpl.class); + addDao("ClusterDao", ClusterDaoImpl.class); + addDao("CertificateDao", CertificateDaoImpl.class); + addDao("NetworkConfigurationDao", NetworkDaoImpl.class); + addDao("NetworkOfferingDao", NetworkOfferingDaoImpl.class); + addDao("NicDao", NicDaoImpl.class); + addDao("InstanceGroupDao", InstanceGroupDaoImpl.class); + addDao("InstanceGroupVMMapDao", InstanceGroupVMMapDaoImpl.class); + addDao("RemoteAccessVpnDao", RemoteAccessVpnDaoImpl.class); + addDao("VpnUserDao", VpnUserDaoImpl.class); + addDao("ItWorkDao", ItWorkDaoImpl.class); + addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); + addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class); + addDao("FirewallRulesCidrsDao", FirewallRulesCidrsDaoImpl.class); + addDao("SSHKeyPairDao", SSHKeyPairDaoImpl.class); + addDao("UsageEventDao", UsageEventDaoImpl.class); + addDao("ClusterDetailsDao", ClusterDetailsDaoImpl.class); + addDao("UserVmDetailsDao", UserVmDetailsDaoImpl.class); + addDao("OvsTunnelInterfaceDao", OvsTunnelInterfaceDaoImpl.class); + addDao("OvsTunnelAccountDao", OvsTunnelNetworkDaoImpl.class); + addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class); + addDao("HostTagsDao", HostTagsDaoImpl.class); + addDao("NetworkDomainDao", NetworkDomainDaoImpl.class); + addDao("KeystoreDao", KeystoreDaoImpl.class); + addDao("DcDetailsDao", DcDetailsDaoImpl.class); + addDao("SwiftDao", SwiftDaoImpl.class); + addDao("AgentTransferMapDao", HostTransferMapDaoImpl.class); + addDao("ProjectDao", ProjectDaoImpl.class); + addDao("InlineLoadBalancerNicMapDao", InlineLoadBalancerNicMapDaoImpl.class); + addDao("ElasticLbVmMap", ElasticLbVmMapDaoImpl.class); + addDao("ProjectsAccountDao", ProjectAccountDaoImpl.class); + addDao("ProjectInvitationDao", ProjectInvitationDaoImpl.class); + addDao("IdentityDao", IdentityDaoImpl.class); + addDao("AccountDetailsDao", AccountDetailsDaoImpl.class); + addDao("NetworkOfferingServiceMapDao", NetworkOfferingServiceMapDaoImpl.class); + info = addDao("HypervisorCapabilitiesDao",HypervisorCapabilitiesDaoImpl.class); + info.addParameter("cache.size", "100"); + info.addParameter("cache.time.to.live", "600"); + addDao("PhysicalNetworkDao", PhysicalNetworkDaoImpl.class); + addDao("PhysicalNetworkServiceProviderDao", PhysicalNetworkServiceProviderDaoImpl.class); + addDao("VirtualRouterProviderDao", VirtualRouterProviderDaoImpl.class); + addDao("ExternalLoadBalancerDeviceDao", ExternalLoadBalancerDeviceDaoImpl.class); + addDao("ExternalFirewallDeviceDao", ExternalFirewallDeviceDaoImpl.class); + addDao("NetworkExternalLoadBalancerDao", NetworkExternalLoadBalancerDaoImpl.class); + addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class); + addDao("CiscoNexusVSMDeviceDao", CiscoNexusVSMDeviceDaoImpl.class); + addDao("ClusterVSMMapDao", ClusterVSMMapDaoImpl.class); + addDao("PortProfileDao", PortProfileDaoImpl.class); + addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class); + addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class); + addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); + addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class); + addDao("TagsDao", ResourceTagsDaoImpl.class); + addDao("VpcDao", VpcDaoImpl.class); + addDao("VpcOfferingDao", VpcOfferingDaoImpl.class); + addDao("VpcOfferingServiceMapDao", VpcOfferingServiceMapDaoImpl.class); + addDao("PrivateIpDao", PrivateIpDaoImpl.class); + addDao("VpcGatewayDao", VpcGatewayDaoImpl.class); + addDao("StaticRouteDao", StaticRouteDaoImpl.class); + addDao("Site2SiteVpnGatewayDao", Site2SiteVpnGatewayDaoImpl.class); + addDao("Site2SiteCustomerGatewayDao", Site2SiteCustomerGatewayDaoImpl.class); + addDao("Site2SiteVpnConnnectionDao", Site2SiteVpnConnectionDaoImpl.class); + addDao("CounterDao", CounterDaoImpl.class); + addDao("ConditionDao", ConditionDaoImpl.class); + } + + @Override + public synchronized Map>> getDaos() { + if (_daos.size() == 0) { + populateDaos(); + } + return _daos; + } + + protected void populateManagers() { + addManager("StackMaidManager", CheckPointManagerImpl.class); + addManager("Cluster Manager", ClusterManagerImpl.class); + addManager("ClusterFenceManager", ClusterFenceManagerImpl.class); + addManager("ClusteredAgentManager", ClusteredAgentManagerImpl.class); + addManager("SyncQueueManager", SyncQueueManagerImpl.class); + addManager("AsyncJobManager", AsyncJobManagerImpl.class); + addManager("AsyncJobExecutorContext", AsyncJobExecutorContextImpl.class); + addManager("configuration manager", ConfigurationManagerImpl.class); + addManager("account manager", AccountManagerImpl.class); + addManager("domain manager", DomainManagerImpl.class); + addManager("resource limit manager", ResourceLimitManagerImpl.class); + addManager("network manager", NetworkManagerImpl.class); + addManager("download manager", DownloadMonitorImpl.class); + addManager("upload manager", UploadMonitorImpl.class); + addManager("keystore manager", KeystoreManagerImpl.class); + addManager("secondary storage vm manager", SecondaryStorageManagerImpl.class); + addManager("vm manager", UserVmManagerImpl.class); + addManager("upgrade manager", UpgradeManagerImpl.class); + addManager("StorageManager", StorageManagerImpl.class); + addManager("Alert Manager", AlertManagerImpl.class); + addManager("Template Manager", TemplateManagerImpl.class); + addManager("Snapshot Manager", SnapshotManagerImpl.class); + addManager("SnapshotScheduler", SnapshotSchedulerImpl.class); + addManager("SecurityGroupManager", SecurityGroupManagerImpl2.class); + addManager("DomainRouterManager", VirtualNetworkApplianceManagerImpl.class); + addManager("EntityManager", EntityManagerImpl.class); + addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class); + addManager("AutoScaleManager", AutoScaleManagerImpl.class); + addManager("RulesManager", RulesManagerImpl.class); + addManager("RemoteAccessVpnManager", RemoteAccessVpnManagerImpl.class); + addManager("OvsTunnelManager", OvsTunnelManagerImpl.class); + addManager("Capacity Manager", CapacityManagerImpl.class); + addManager("VirtualMachineManager", ClusteredVirtualMachineManagerImpl.class); + addManager("HypervisorGuruManager", HypervisorGuruManagerImpl.class); + addManager("ResourceManager", ResourceManagerImpl.class); + addManager("IdentityManager", IdentityServiceImpl.class); + addManager("OCFS2Manager", OCFS2ManagerImpl.class); + addManager("FirewallManager", FirewallManagerImpl.class); + ComponentInfo info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class); + info.addParameter("consoleproxy.sslEnabled", "true"); + addManager("ProjectManager", ProjectManagerImpl.class); + addManager("ElasticLoadBalancerManager", ElasticLoadBalancerManagerImpl.class); + addManager("SwiftManager", SwiftManagerImpl.class); + addManager("StorageNetworkManager", StorageNetworkManagerImpl.class); + addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class); + addManager("HA Manager", HighAvailabilityManagerImpl.class); + addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class); + addManager("VPC Manager", VpcManagerImpl.class); + addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class); + addManager("NetworkACLManager", NetworkACLManagerImpl.class); + addManager("Site2SiteVpnManager", Site2SiteVpnManagerImpl.class); + } + + @Override + public synchronized Map> getManagers() { + if (_managers.size() == 0) { + populateManagers(); + } + return _managers; + } + + protected void populateAdapters() { + addAdapter(TemplateAdapter.class, TemplateAdapterType.Hypervisor.getName(), HyervisorTemplateAdapter.class); + } + + @Override + public synchronized Map>> getAdapters() { + if (_adapters.size() == 0) { + populateAdapters(); + } + return _adapters; + } + + @Override + public synchronized Map, Class> getFactories() { + HashMap, Class> factories = new HashMap, Class>(); + factories.put(EntityManager.class, EntityManagerImpl.class); + return factories; + } + + protected void populateServices() { + addService("VirtualRouterElementService", VirtualRouterElementService.class, VirtualRouterElement.class); + addService("NetscalerExternalLoadBalancerElementService", NetscalerLoadBalancerElementService.class, NetscalerElement.class); + addService("F5LoadBalancerElementService", F5ExternalLoadBalancerElementService.class, F5ExternalLoadBalancerElement.class); + addService("JuniperSRXFirewallElementService", JuniperSRXFirewallElementService.class, JuniperSRXExternalFirewallElement.class); + addService("CiscoNexusVSMElementService", CiscoNexusVSMElementService.class, CiscoNexusVSMElement.class); + } + + @Override + public synchronized Map> getPluggableServices() { + if (_pluggableServices.size() == 0) { + populateServices(); + } + return _pluggableServices; + } +} diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 409970d8d92..133bfb5c01a 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -1,1026 +1,1030 @@ -// 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; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.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.IpAssocCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.routing.NetworkElementCommand; -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.api.ApiConstants; -import com.cloud.configuration.Config; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterIpAddressVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.Pod; -import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientNetworkCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.DetailVO; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.host.dao.HostDetailsDao; -import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState; -import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState; -import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice; -import com.cloud.network.Network.Service; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.ExternalFirewallDeviceDao; -import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.InlineLoadBalancerNicMapDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkExternalFirewallDao; -import com.cloud.network.dao.NetworkExternalLoadBalancerDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; -import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.resource.CreateLoadBalancerApplianceAnswer; -import com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StaticNatRuleImpl; -import com.cloud.network.rules.dao.PortForwardingRulesDao; -import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.resource.ResourceManager; -import com.cloud.resource.ResourceState; -import com.cloud.resource.ResourceStateAdapter; -import com.cloud.resource.ServerResource; -import com.cloud.resource.UnableDeleteHostException; -import com.cloud.server.api.response.ExternalLoadBalancerResponse; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.AdapterBase; -import com.cloud.utils.component.Inject; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; -import com.cloud.utils.net.UrlUtil; -import com.cloud.vm.Nic.ReservationStrategy; -import com.cloud.vm.Nic.State; -import com.cloud.vm.NicVO; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; -public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter { - - @Inject - NetworkExternalLoadBalancerDao _networkExternalLBDao; - @Inject - ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao; - @Inject - HostDao _hostDao; - @Inject - DataCenterDao _dcDao; - @Inject - NetworkManager _networkMgr; - @Inject - InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao; - @Inject - NicDao _nicDao; - @Inject - AgentManager _agentMgr; - @Inject - ResourceManager _resourceMgr; - @Inject - IPAddressDao _ipAddressDao; - @Inject - VlanDao _vlanDao; - @Inject - NetworkOfferingDao _networkOfferingDao; - @Inject - AccountDao _accountDao; - @Inject - PhysicalNetworkDao _physicalNetworkDao; - @Inject - PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; - @Inject - AccountManager _accountMgr; - @Inject - UserStatisticsDao _userStatsDao; - @Inject - NetworkDao _networkDao; - @Inject - DomainRouterDao _routerDao; - @Inject - LoadBalancerDao _loadBalancerDao; - @Inject - PortForwardingRulesDao _portForwardingRulesDao; - @Inject - ConfigurationDao _configDao; - @Inject - HostDetailsDao _hostDetailDao; - @Inject - NetworkExternalLoadBalancerDao _networkLBDao; - @Inject - NetworkServiceMapDao _ntwkSrvcProviderDao; - @Inject - NetworkExternalFirewallDao _networkExternalFirewallDao; - @Inject - ExternalFirewallDeviceDao _externalFirewallDeviceDao; - @Inject - protected HostPodDao _podDao = null; - - private long _defaultLbCapacity; - private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class); - - @Override - @DB - public ExternalLoadBalancerDeviceVO addExternalLoadBalancer(long physicalNetworkId, String url, String username, String password, String deviceName, ServerResource resource) { - - PhysicalNetworkVO pNetwork = null; - NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName); - long zoneId; - - 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."); - } - - pNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (pNetwork == null) { - throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); - } - zoneId = pNetwork.getDataCenterId(); - - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder()); - if (ntwkSvcProvider == null) { - throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + - " is not enabled in the physical network: " + physicalNetworkId + "to add this device"); - } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { - throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + - " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device"); - } - - URI uri; - try { - uri = new URI(url); - } catch (Exception e) { - s_logger.debug(e); - throw new InvalidParameterValueException(e.getMessage()); - } - - String ipAddress = uri.getHost(); - Map hostDetails = new HashMap(); - String hostName = getExternalLoadBalancerResourceGuid(pNetwork.getId(), deviceName, ipAddress); - hostDetails.put("name", hostName); - hostDetails.put("guid", UUID.randomUUID().toString()); - hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId())); - hostDetails.put("ip", ipAddress); - hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId())); - hostDetails.put("username", username); - hostDetails.put("password", password); - hostDetails.put("deviceName", deviceName); - - // leave parameter validation to be part server resource configure - Map configParams = new HashMap(); - UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); - hostDetails.putAll(configParams); - - Transaction txn = Transaction.currentTxn(); - try { - resource.configure(hostName, hostDetails); - - Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails); - if (host != null) { - - 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); - if (capacity == 0) { - capacity = _defaultLbCapacity; - } - - txn.start(); - ExternalLoadBalancerDeviceVO lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName(), - deviceName, capacity, dedicatedUse, inline); - _externalLoadBalancerDeviceDao.persist(lbDeviceVO); - - DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId())); - _hostDetailDao.persist(hostDetail); - - txn.commit(); - return lbDeviceVO; - } else { - throw new CloudRuntimeException("Failed to add load balancer device due to internal error."); - } - } catch (ConfigurationException e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } - } - - @Override - public boolean deleteExternalLoadBalancer(long hostId) { - HostVO externalLoadBalancer = _hostDao.findById(hostId); - if (externalLoadBalancer == null) { - throw new InvalidParameterValueException("Could not find an external load balancer with ID: " + hostId); - } - - DetailVO lbHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.LOAD_BALANCER_DEVICE_ID); - long lbDeviceId = Long.parseLong(lbHostDetails.getValue()); - - ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId); - if (lbDeviceVo.getAllocationState() == LBDeviceAllocationState.Provider) { - // check if cloudstack has provisioned any load balancer appliance on the device before deleting - List lbDevices = _externalLoadBalancerDeviceDao.listAll(); - if (lbDevices != null) { - for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { - if (lbDevice.getParentHostId() == hostId) { - throw new CloudRuntimeException("This load balancer device can not be deleted as there are one or more load balancers applainces provisioned by cloudstack on the device."); - } - } - } - } else { - // check if any networks are using this load balancer device - List networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); - if ((networks != null) && !networks.isEmpty()) { - throw new CloudRuntimeException("Delete can not be done as there are networks using this load balancer device "); - } - } - - try { - // put the host in maintenance state in order for it to be deleted - externalLoadBalancer.setResourceState(ResourceState.Maintenance); - _hostDao.update(hostId, externalLoadBalancer); - _resourceMgr.deleteHost(hostId, false, false); - - // delete the external load balancer entry - _externalLoadBalancerDeviceDao.remove(lbDeviceId); - - return true; - } catch (Exception e) { - s_logger.debug(e); - return false; - } - } - - @Override - public List listExternalLoadBalancers(long physicalNetworkId, String deviceName) { - List lbHosts = new ArrayList(); - NetworkDevice lbNetworkDevice = NetworkDevice.getNetworkDevice(deviceName); - PhysicalNetworkVO pNetwork = null; - - pNetwork = _physicalNetworkDao.findById(physicalNetworkId); - - if ((pNetwork == null) || (lbNetworkDevice == null)) { - throw new InvalidParameterValueException("Atleast one of the required parameter physical networkId, device name is invalid."); - } - - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), - lbNetworkDevice.getNetworkServiceProvder()); - // if provider not configured in to physical network, then there can be no instances - if (ntwkSvcProvider == null) { - return null; - } - - List lbDevices = _externalLoadBalancerDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, - ntwkSvcProvider.getProviderName()); - for (ExternalLoadBalancerDeviceVO provderInstance : lbDevices) { - lbHosts.add(_hostDao.findById(provderInstance.getHostId())); - } - return lbHosts; - } - - public ExternalLoadBalancerResponse createExternalLoadBalancerResponse(Host externalLoadBalancer) { - Map lbDetails = _hostDetailDao.findDetails(externalLoadBalancer.getId()); - ExternalLoadBalancerResponse response = new ExternalLoadBalancerResponse(); - response.setId(externalLoadBalancer.getId()); - response.setIpAddress(externalLoadBalancer.getPrivateIpAddress()); - response.setUsername(lbDetails.get("username")); - response.setPublicInterface(lbDetails.get("publicInterface")); - response.setPrivateInterface(lbDetails.get("privateInterface")); - response.setNumRetries(lbDetails.get("numRetries")); - return response; - } - - public String getExternalLoadBalancerResourceGuid(long physicalNetworkId, String deviceName, String ip) { - return physicalNetworkId + "-" + deviceName + "-" + ip; - } - - @Override - public ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) { - NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId()); - if (lbDeviceForNetwork != null) { - long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId(); - ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId); - assert (lbDeviceVo != null); - return lbDeviceVo; - } - return null; - } - - public void setExternalLoadBalancerForNetwork(Network network, long externalLBDeviceID) { - NetworkExternalLoadBalancerVO lbDeviceForNetwork = new NetworkExternalLoadBalancerVO(network.getId(), externalLBDeviceID); - _networkExternalLBDao.persist(lbDeviceForNetwork); - } - - @DB - protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(Network guestConfig) throws InsufficientCapacityException { - boolean retry = true; - boolean tryLbProvisioning = false; - ExternalLoadBalancerDeviceVO lbDevice = null; - long physicalNetworkId = guestConfig.getPhysicalNetworkId(); - NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId()); - String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb); - - while (retry) { - GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); - Transaction txn = Transaction.currentTxn(); - try { - if (deviceMapLock.lock(120)) { - try { - boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated -// load balancer? - long lbDeviceId; - - txn.start(); - try { - // FIXME: should the device allocation be done during network implement phase or do a - // lazy allocation when first rule for the network is configured?? - - // find a load balancer device for this network as per the network offering - lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB); - lbDeviceId = lbDevice.getId(); - - // 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 - NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId); - _networkExternalLBDao.persist(networkLB); - - // mark device to be either dedicated or shared use - lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared); - _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice); - - txn.commit(); - - // allocated load balancer for the network, so skip retry - tryLbProvisioning = false; - retry = false; - } catch (InsufficientCapacityException exception) { - // if already attempted to provision load balancer then throw out of capacity exception, - if (tryLbProvisioning) { - retry = false; - // TODO: throwing warning instead of error for now as its possible another provider can -// 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 - } - } - } finally { - deviceMapLock.unlock(); - if (lbDevice == null) { - txn.rollback(); - } - } - } - } finally { - deviceMapLock.releaseRef(); - } - - // there are no LB devices or there is no free capacity on the devices in the physical network so provision -// a new LB appliance - if (tryLbProvisioning) { - // check if LB appliance can be dynamically provisioned - List providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider); - if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) { - 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, - 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() + - " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId()); - } - Pod pod = _podDao.findById(dcPrivateIp.getPodId()); - String lbIP = dcPrivateIp.getIpAddress(); - String netmask = NetUtils.getCidrNetmask(pod.getCidrSize()); - String gateway = pod.getGateway(); - - // send CreateLoadBalancerApplianceCommand to the host capable of provisioning - CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway); - CreateLoadBalancerApplianceAnswer createLbAnswer = null; - try { - createLbAnswer = (CreateLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd); - if (createLbAnswer == null || !createLbAnswer.getResult()) { - s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId()); - continue; - } - } catch (Exception agentException) { - s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " + agentException.getMessage()); - continue; - } - - String username = createLbAnswer.getUsername(); - String password = createLbAnswer.getPassword(); - String publicIf = createLbAnswer.getPublicInterface(); - String privateIf = createLbAnswer.getPrivateInterface(); - - // we have provisioned load balancer so add the appliance as cloudstack provisioned external -// 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) - PublicIp publicIp = _networkMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null, false); - String publicIPNetmask = publicIp.getVlanNetmask(); - String publicIPgateway = publicIp.getVlanGateway(); - String publicIPVlanTag = publicIp.getVlanTag(); - 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; - ExternalLoadBalancerDeviceVO lbAppliance = null; - try { - lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource()); - } catch (Exception e) { - s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() + ". So provisioned load balancer appliance will be destroyed."); - } - - if (lbAppliance != null) { - // mark the load balancer as cloudstack managed and set parent host id on which lb -// appliance is provisioned - ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId()); - managedLb.setIsManagedDevice(true); - managedLb.setParentHostId(lbProviderDevice.getHostId()); - _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb); - } else { - // failed to add the provisioned load balancer into cloudstack so destroy the appliance - DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP); - DestroyLoadBalancerApplianceAnswer answer = null; - try { - answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd); - if (answer == null || !answer.getResult()) { - 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 - _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); - _networkMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); - } - } catch (Exception e) { - s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage()); - } - } - } - } - } - } - } - - return lbDevice; - } - - @Override - public ExternalLoadBalancerDeviceVO findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException { - long physicalNetworkId = network.getPhysicalNetworkId(); - List lbDevices = null; - String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb); - assert (provider != null); - - if (dedicatedLb) { - lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free); - if (lbDevices != null && !lbDevices.isEmpty()) { - // return first device that is free, fully configured and meant for dedicated use - for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { - if (lbdevice.getState() == LBDeviceState.Enabled && lbdevice.getIsDedicatedDevice()) { - return lbdevice; - } - } - } - } else { - // get the LB devices that are already allocated for shared use - lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Shared); - - if (lbDevices != null) { - - ExternalLoadBalancerDeviceVO maxFreeCapacityLbdevice = null; - long maxFreeCapacity = 0; - - // loop through the LB device in the physical network and pick the one with maximum free capacity - for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { - - // skip if device is not enabled - if (lbdevice.getState() != LBDeviceState.Enabled) { - continue; - } - - // get the used capacity from the list of guest networks that are mapped to this load balancer - List mappedNetworks = _networkExternalLBDao.listByLoadBalancerDeviceId(lbdevice.getId()); - long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty())) ? 0 : mappedNetworks.size(); - - // get the configured capacity for this device - long fullCapacity = lbdevice.getCapacity(); - if (fullCapacity == 0) { - fullCapacity = _defaultLbCapacity; // if capacity not configured then use the default - } - - long freeCapacity = fullCapacity - usedCapacity; - if (freeCapacity > 0) { - if (maxFreeCapacityLbdevice == null) { - maxFreeCapacityLbdevice = lbdevice; - maxFreeCapacity = freeCapacity; - } else if (freeCapacity > maxFreeCapacity) { - maxFreeCapacityLbdevice = lbdevice; - maxFreeCapacity = freeCapacity; - } - } - } - - // return the device with maximum free capacity and is meant for shared use - if (maxFreeCapacityLbdevice != null) { - return maxFreeCapacityLbdevice; - } - } - - // 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 - // 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()) { - for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { - if (lbdevice.getState() == LBDeviceState.Enabled && !lbdevice.getIsDedicatedDevice()) { - return lbdevice; - } - } - } - } - - // there are no devices which capacity - throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " + - " to implement the network", Network.class, network.getId()); - } - - @DB - protected boolean freeLoadBalancerForNetwork(Network guestConfig) { - Transaction txn = Transaction.currentTxn(); - GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); - - try { - if (deviceMapLock.lock(120)) { - txn.start(); - // since network is shutdown remove the network mapping to the load balancer device - NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId()); - long lbDeviceId = networkLBDevice.getExternalLBDeviceId(); - _networkExternalLBDao.remove(networkLBDevice.getId()); - - List ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId()); - ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId); - boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty()); - boolean lbCloudManaged = lbDevice.getIsManagedDevice(); - - if (!lbInUse && !lbCloudManaged) { - // this is the last network mapped to the load balancer device so set device allocation state to be -// free - lbDevice.setAllocationState(LBDeviceAllocationState.Free); - _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice); - } - - // commit the changes before sending agent command to destroy cloudstack managed LB - txn.commit(); - - if (!lbInUse && lbCloudManaged) { - // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned - Host lbHost = _hostDao.findById(lbDevice.getHostId()); - String lbIP = lbHost.getPrivateIpAddress(); - DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP); - DestroyLoadBalancerApplianceAnswer answer = null; - try { - answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd); - if (answer == null || !answer.getResult()) { - s_logger.warn("Failed to destoy load balancer appliance used by the network" + guestConfig.getId() + " due to " + answer.getDetails()); - } - } catch (Exception e) { - s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId()); - } - deviceMapLock.unlock(); - - // remove the provisioned load balancer appliance from cloudstack - deleteExternalLoadBalancer(lbHost.getId()); - - // release the private IP back to dc pool, as the load balancer appliance is now destroyed - _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null); - - // release the public IP allocated for this LB appliance - DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip"); - IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString()); - _networkMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); - } else { - deviceMapLock.unlock(); - } - - return true; - } else { - s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock "); - return false; - } - } catch (Exception exception) { - txn.rollback(); - s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage()); - } finally { - deviceMapLock.releaseRef(); - } - - return false; - } - - HostVO getFirewallProviderForNetwork(Network network) { - HostVO fwHost = null; - - // get the firewall provider (could be either virtual router or external firewall device) for the network - String fwProvider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Firewall); - - if (fwProvider.equalsIgnoreCase("VirtualRouter")) { - // FIXME: use network service provider container framework support to implement on virtual router - } else { - NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId()); - assert (fwDeviceForNetwork != null) : "Why firewall provider is not ready for the network to apply static nat rules?"; - long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId(); - ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId); - fwHost = _hostDao.findById(fwDevice.getHostId()); - } - - return fwHost; - } - - private boolean externalLoadBalancerIsInline(HostVO externalLoadBalancer) { - DetailVO detail = _hostDetailDao.findDetail(externalLoadBalancer.getId(), "inline"); - return (detail != null && detail.getValue().equals("true")); - } - - private NicVO savePlaceholderNic(Network network, String ipAddress) { - NicVO nic = new NicVO(null, null, network.getId(), null); - nic.setIp4Address(ipAddress); - nic.setReservationStrategy(ReservationStrategy.PlaceHolder); - nic.setState(State.Reserved); - return _nicDao.persist(nic); - } - - private NicVO getPlaceholderNic(Network network) { - List guestIps = _nicDao.listByNetworkId(network.getId()); - for (NicVO guestIp : guestIps) { - // only external firewall and external load balancer will create NicVO with PlaceHolder reservation strategy - if (guestIp.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && guestIp.getVmType() == null - && guestIp.getReserver() == null && !guestIp.getIp4Address().equals(network.getGateway())) { - return guestIp; - } - } - return null; - } - - private void applyStaticNatRuleForInlineLBRule(DataCenterVO zone, Network network, HostVO firewallHost, boolean revoked, String publicIp, String privateIp) throws ResourceUnavailableException { - List staticNatRules = new ArrayList(); - IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0); - VlanVO vlan = _vlanDao.findById(ipVO.getVlanId()); - FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null, null); - FirewallRule.State state = !revoked ? FirewallRule.State.Add : FirewallRule.State.Revoke; - fwRule.setState(state); - StaticNatRule rule = new StaticNatRuleImpl(fwRule, privateIp); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, vlan.getVlanTag(), publicIp, privateIp); - staticNatRules.add(ruleTO); - - applyStaticNatRules(staticNatRules, network, firewallHost.getId()); - } - - protected void applyStaticNatRules(List staticNatRules, Network network, long firewallHostId) throws ResourceUnavailableException { - if (!staticNatRules.isEmpty()) { - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null); - Answer answer = _agentMgr.easySend(firewallHostId, cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "firewall provider for the network was unable to apply static nat rules due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, Network.class, network.getId()); - } - } - } - - @Override - public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { - // Find the external load balancer in this zone - long zoneId = network.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - - List loadBalancingRules = new ArrayList(); - - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } - - if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { - return true; - } - - ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); - if (lbDeviceVO == null) { - s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); - return true; - } - - HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); - - boolean externalLoadBalancerIsInline = externalLoadBalancerIsInline(externalLoadBalancer); - - if (network.getState() == Network.State.Allocated) { - s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands."); - return true; - } - - List loadBalancersToApply = new ArrayList(); - for (int i = 0; i < loadBalancingRules.size(); i++) { - LoadBalancingRule rule = loadBalancingRules.get(i); - - boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); - String protocol = rule.getProtocol(); - String algorithm = rule.getAlgorithm(); - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); - int srcPort = rule.getSourcePortStart(); - List destinations = rule.getDestinations(); - List sourceCidrs = rule.getSourceCidrList(); - - if (externalLoadBalancerIsInline) { - InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(srcIp); - NicVO loadBalancingIpNic = null; - HostVO firewallProviderHost = null; - - if (externalLoadBalancerIsInline) { - firewallProviderHost = getFirewallProviderForNetwork(network); - } - - if (!revoked) { - if (mapping == null) { - // Acquire a new guest IP address and save it as the load balancing IP address - String loadBalancingIpAddress = _networkMgr.acquireGuestIpAddress(network, null); - - if (loadBalancingIpAddress == null) { - String msg = "Ran out of guest IP addresses."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); - } - - // If a NIC doesn't exist for the load balancing IP address, create one - loadBalancingIpNic = _nicDao.findByIp4AddressAndNetworkId(loadBalancingIpAddress, network.getId()); - if (loadBalancingIpNic == null) { - loadBalancingIpNic = savePlaceholderNic(network, loadBalancingIpAddress); - } - - // Save a mapping between the source IP address and the load balancing IP address NIC - mapping = new InlineLoadBalancerNicMapVO(rule.getId(), srcIp, loadBalancingIpNic.getId()); - _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 - applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); - } else { - loadBalancingIpNic = _nicDao.findById(mapping.getNicId()); - } - } else { - if (mapping != null) { - // Find the NIC that the mapping refers to - 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 - applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); - - // Delete the mapping between the source IP address and the load balancing IP address - _inlineLoadBalancerNicMapDao.expunge(mapping.getId()); - - // Delete the NIC - _nicDao.expunge(loadBalancingIpNic.getId()); - } else { - s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet."); - continue; - } - } - - // Change the source IP address for the load balancing rule to be the load balancing IP address - srcIp = loadBalancingIpNic.getIp4Address(); - } - - if (destinations != null && !destinations.isEmpty()) { - LoadBalancerTO loadBalancer = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); - loadBalancersToApply.add(loadBalancer); - } - } - - if (loadBalancersToApply.size() > 0) { - int numLoadBalancersForCommand = loadBalancersToApply.size(); - LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); - long guestVlanTag = Integer.parseInt(network.getBroadcastUri().getHost()); - cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); - Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "Unable to apply load balancer rules to the external load balancer appliance in zone " + zone.getName() + " due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); - } - } - - return true; - } - - @Override - public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException { - if (guestConfig.getTrafficType() != TrafficType.Guest) { - s_logger.trace("External load balancer can only be used for guest networks."); - return false; - } - - long zoneId = guestConfig.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - HostVO externalLoadBalancer = null; - - if (add) { - ExternalLoadBalancerDeviceVO lbDeviceVO = allocateLoadBalancerForNetwork(guestConfig); - if (lbDeviceVO == null) { - String msg = "failed to alloacate a external load balancer for the network " + guestConfig.getId(); - s_logger.error(msg); - throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId()); - } - externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); - s_logger.debug("Allocated external load balancer device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId()); - } else { - // find the load balancer device allocated for the network - 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."); - return true; - } - - externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); - assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??"; - } - - // Send a command to the external load balancer to implement or shutdown the guest network - long guestVlanTag = Long.parseLong(guestConfig.getBroadcastUri().getHost()); - String selfIp = null; - String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr()); - Integer networkRate = _networkMgr.getNetworkRate(guestConfig.getId(), null); - - if (add) { - // Acquire a self-ip address from the guest network IP address range - selfIp = _networkMgr.acquireGuestIpAddress(guestConfig, null); - if (selfIp == null) { - String msg = "failed to acquire guest IP address so not implementing the network on the external load balancer "; - s_logger.error(msg); - throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId()); - } - } else { - // get the self-ip used by the load balancer - 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."); - return true; - } - selfIp = selfipNic.getIp4Address(); - } - - IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, null, networkRate, false); - IpAddressTO[] ips = new IpAddressTO[1]; - ips[0] = ip; - IpAssocCommand cmd = new IpAssocCommand(ips); - Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); - - if (answer == null || !answer.getResult()) { - String action = add ? "implement" : "shutdown"; - String answerDetails = (answer != null) ? answer.getDetails() : "answer was null"; - String msg = "External load balancer was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + " due to " + answerDetails; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId()); - } - - if (add) { - // Insert a new NIC for this guest network to reserve the self IP - savePlaceholderNic(guestConfig, selfIp); - } else { - // release the self-ip obtained from guest network - NicVO selfipNic = getPlaceholderNic(guestConfig); - _nicDao.remove(selfipNic.getId()); - - // release the load balancer allocated for the network - boolean releasedLB = freeLoadBalancerForNetwork(guestConfig); - if (!releasedLB) { - String msg = "Failed to release the external load balancer used for the network: " + guestConfig.getId(); - s_logger.error(msg); - } - } - - if (s_logger.isDebugEnabled()) { - Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId()); - String action = add ? "implemented" : "shut down"; - s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag); - } - - return true; - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - _defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); - _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); - return true; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, - Map details, List hostTags) { - if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) { - return null; - } - host.setType(Host.Type.ExternalLoadBalancer); - return host; - } - - @Override - public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - if (host.getType() != com.cloud.host.Host.Type.ExternalLoadBalancer) { - return null; - } - return new DeleteHostAnswer(true); - } - -} +// 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; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.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.IpAssocCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +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.api.ApiConstants; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterIpAddressVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Pod; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.DetailVO; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState; +import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState; +import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice; +import com.cloud.network.Network.Service; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.ExternalFirewallDeviceDao; +import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.InlineLoadBalancerNicMapDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkExternalFirewallDao; +import com.cloud.network.dao.NetworkExternalLoadBalancerDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.resource.CreateLoadBalancerApplianceAnswer; +import com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.StaticNatRuleImpl; +import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; +import com.cloud.server.api.response.ExternalLoadBalancerResponse; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.utils.net.UrlUtil; +import com.cloud.vm.Nic.ReservationStrategy; +import com.cloud.vm.Nic.State; +import com.cloud.vm.NicVO; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter { + + @Inject + NetworkExternalLoadBalancerDao _networkExternalLBDao; + @Inject + ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao; + @Inject + HostDao _hostDao; + @Inject + DataCenterDao _dcDao; + @Inject + NetworkManager _networkMgr; + @Inject + InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao; + @Inject + NicDao _nicDao; + @Inject + AgentManager _agentMgr; + @Inject + ResourceManager _resourceMgr; + @Inject + IPAddressDao _ipAddressDao; + @Inject + VlanDao _vlanDao; + @Inject + NetworkOfferingDao _networkOfferingDao; + @Inject + AccountDao _accountDao; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + AccountManager _accountMgr; + @Inject + UserStatisticsDao _userStatsDao; + @Inject + NetworkDao _networkDao; + @Inject + DomainRouterDao _routerDao; + @Inject + LoadBalancerDao _loadBalancerDao; + @Inject + PortForwardingRulesDao _portForwardingRulesDao; + @Inject + ConfigurationDao _configDao; + @Inject + HostDetailsDao _hostDetailDao; + @Inject + NetworkExternalLoadBalancerDao _networkLBDao; + @Inject + NetworkServiceMapDao _ntwkSrvcProviderDao; + @Inject + NetworkExternalFirewallDao _networkExternalFirewallDao; + @Inject + ExternalFirewallDeviceDao _externalFirewallDeviceDao; + @Inject + protected HostPodDao _podDao = null; + + private long _defaultLbCapacity; + private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class); + + @Override + @DB + public ExternalLoadBalancerDeviceVO addExternalLoadBalancer(long physicalNetworkId, String url, String username, String password, String deviceName, ServerResource resource) { + + PhysicalNetworkVO pNetwork = null; + NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName); + long zoneId; + + 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."); + } + + pNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (pNetwork == null) { + throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); + } + zoneId = pNetwork.getDataCenterId(); + + PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder()); + if (ntwkSvcProvider == null) { + throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + + " is not enabled in the physical network: " + physicalNetworkId + "to add this device"); + } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { + throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + + " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device"); + } + + URI uri; + try { + uri = new URI(url); + } catch (Exception e) { + s_logger.debug(e); + throw new InvalidParameterValueException(e.getMessage()); + } + + String ipAddress = uri.getHost(); + Map hostDetails = new HashMap(); + String hostName = getExternalLoadBalancerResourceGuid(pNetwork.getId(), deviceName, ipAddress); + hostDetails.put("name", hostName); + hostDetails.put("guid", UUID.randomUUID().toString()); + hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId())); + hostDetails.put("ip", ipAddress); + hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId())); + hostDetails.put("username", username); + hostDetails.put("password", password); + hostDetails.put("deviceName", deviceName); + + // leave parameter validation to be part server resource configure + Map configParams = new HashMap(); + UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); + hostDetails.putAll(configParams); + + Transaction txn = Transaction.currentTxn(); + try { + resource.configure(hostName, hostDetails); + + Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails); + if (host != null) { + + 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); + if (capacity == 0) { + capacity = _defaultLbCapacity; + } + + txn.start(); + ExternalLoadBalancerDeviceVO lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName(), + deviceName, capacity, dedicatedUse, inline); + _externalLoadBalancerDeviceDao.persist(lbDeviceVO); + + DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId())); + _hostDetailDao.persist(hostDetail); + + txn.commit(); + return lbDeviceVO; + } else { + throw new CloudRuntimeException("Failed to add load balancer device due to internal error."); + } + } catch (ConfigurationException e) { + txn.rollback(); + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public boolean deleteExternalLoadBalancer(long hostId) { + HostVO externalLoadBalancer = _hostDao.findById(hostId); + if (externalLoadBalancer == null) { + throw new InvalidParameterValueException("Could not find an external load balancer with ID: " + hostId); + } + + DetailVO lbHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.LOAD_BALANCER_DEVICE_ID); + long lbDeviceId = Long.parseLong(lbHostDetails.getValue()); + + ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId); + if (lbDeviceVo.getAllocationState() == LBDeviceAllocationState.Provider) { + // check if cloudstack has provisioned any load balancer appliance on the device before deleting + List lbDevices = _externalLoadBalancerDeviceDao.listAll(); + if (lbDevices != null) { + for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { + if (lbDevice.getParentHostId() == hostId) { + throw new CloudRuntimeException("This load balancer device can not be deleted as there are one or more load balancers applainces provisioned by cloudstack on the device."); + } + } + } + } else { + // check if any networks are using this load balancer device + List networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); + if ((networks != null) && !networks.isEmpty()) { + throw new CloudRuntimeException("Delete can not be done as there are networks using this load balancer device "); + } + } + + try { + // put the host in maintenance state in order for it to be deleted + externalLoadBalancer.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, externalLoadBalancer); + _resourceMgr.deleteHost(hostId, false, false); + + // delete the external load balancer entry + _externalLoadBalancerDeviceDao.remove(lbDeviceId); + + return true; + } catch (Exception e) { + s_logger.debug(e); + return false; + } + } + + @Override + public List listExternalLoadBalancers(long physicalNetworkId, String deviceName) { + List lbHosts = new ArrayList(); + NetworkDevice lbNetworkDevice = NetworkDevice.getNetworkDevice(deviceName); + PhysicalNetworkVO pNetwork = null; + + pNetwork = _physicalNetworkDao.findById(physicalNetworkId); + + if ((pNetwork == null) || (lbNetworkDevice == null)) { + throw new InvalidParameterValueException("Atleast one of the required parameter physical networkId, device name is invalid."); + } + + PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), + lbNetworkDevice.getNetworkServiceProvder()); + // if provider not configured in to physical network, then there can be no instances + if (ntwkSvcProvider == null) { + return null; + } + + List lbDevices = _externalLoadBalancerDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, + ntwkSvcProvider.getProviderName()); + for (ExternalLoadBalancerDeviceVO provderInstance : lbDevices) { + lbHosts.add(_hostDao.findById(provderInstance.getHostId())); + } + return lbHosts; + } + + public ExternalLoadBalancerResponse createExternalLoadBalancerResponse(Host externalLoadBalancer) { + Map lbDetails = _hostDetailDao.findDetails(externalLoadBalancer.getId()); + ExternalLoadBalancerResponse response = new ExternalLoadBalancerResponse(); + response.setId(externalLoadBalancer.getId()); + response.setIpAddress(externalLoadBalancer.getPrivateIpAddress()); + response.setUsername(lbDetails.get("username")); + response.setPublicInterface(lbDetails.get("publicInterface")); + response.setPrivateInterface(lbDetails.get("privateInterface")); + response.setNumRetries(lbDetails.get("numRetries")); + return response; + } + + public String getExternalLoadBalancerResourceGuid(long physicalNetworkId, String deviceName, String ip) { + return physicalNetworkId + "-" + deviceName + "-" + ip; + } + + @Override + public ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) { + NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId()); + if (lbDeviceForNetwork != null) { + long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId(); + ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId); + assert (lbDeviceVo != null); + return lbDeviceVo; + } + return null; + } + + public void setExternalLoadBalancerForNetwork(Network network, long externalLBDeviceID) { + NetworkExternalLoadBalancerVO lbDeviceForNetwork = new NetworkExternalLoadBalancerVO(network.getId(), externalLBDeviceID); + _networkExternalLBDao.persist(lbDeviceForNetwork); + } + + @DB + protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(Network guestConfig) throws InsufficientCapacityException { + boolean retry = true; + boolean tryLbProvisioning = false; + ExternalLoadBalancerDeviceVO lbDevice = null; + long physicalNetworkId = guestConfig.getPhysicalNetworkId(); + NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId()); + String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb); + + while (retry) { + GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); + Transaction txn = Transaction.currentTxn(); + try { + if (deviceMapLock.lock(120)) { + try { + boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated +// load balancer? + long lbDeviceId; + + txn.start(); + try { + // FIXME: should the device allocation be done during network implement phase or do a + // lazy allocation when first rule for the network is configured?? + + // find a load balancer device for this network as per the network offering + lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB); + lbDeviceId = lbDevice.getId(); + + // 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 + NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId); + _networkExternalLBDao.persist(networkLB); + + // mark device to be either dedicated or shared use + lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared); + _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice); + + txn.commit(); + + // allocated load balancer for the network, so skip retry + tryLbProvisioning = false; + retry = false; + } catch (InsufficientCapacityException exception) { + // if already attempted to provision load balancer then throw out of capacity exception, + if (tryLbProvisioning) { + retry = false; + // TODO: throwing warning instead of error for now as its possible another provider can +// 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 + } + } + } finally { + deviceMapLock.unlock(); + if (lbDevice == null) { + txn.rollback(); + } + } + } + } finally { + deviceMapLock.releaseRef(); + } + + // there are no LB devices or there is no free capacity on the devices in the physical network so provision +// a new LB appliance + if (tryLbProvisioning) { + // check if LB appliance can be dynamically provisioned + List providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider); + if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) { + 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, + 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() + + " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId()); + } + Pod pod = _podDao.findById(dcPrivateIp.getPodId()); + String lbIP = dcPrivateIp.getIpAddress(); + String netmask = NetUtils.getCidrNetmask(pod.getCidrSize()); + String gateway = pod.getGateway(); + + // send CreateLoadBalancerApplianceCommand to the host capable of provisioning + CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway); + CreateLoadBalancerApplianceAnswer createLbAnswer = null; + try { + createLbAnswer = (CreateLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd); + if (createLbAnswer == null || !createLbAnswer.getResult()) { + s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId()); + continue; + } + } catch (Exception agentException) { + s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " + agentException.getMessage()); + continue; + } + + String username = createLbAnswer.getUsername(); + String password = createLbAnswer.getPassword(); + String publicIf = createLbAnswer.getPublicInterface(); + String privateIf = createLbAnswer.getPrivateInterface(); + + // we have provisioned load balancer so add the appliance as cloudstack provisioned external +// 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) + PublicIp publicIp = _networkMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null, false); + String publicIPNetmask = publicIp.getVlanNetmask(); + String publicIPgateway = publicIp.getVlanGateway(); + String publicIPVlanTag = publicIp.getVlanTag(); + 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; + ExternalLoadBalancerDeviceVO lbAppliance = null; + try { + lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource()); + } catch (Exception e) { + s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() + ". So provisioned load balancer appliance will be destroyed."); + } + + if (lbAppliance != null) { + // mark the load balancer as cloudstack managed and set parent host id on which lb +// appliance is provisioned + ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId()); + managedLb.setIsManagedDevice(true); + managedLb.setParentHostId(lbProviderDevice.getHostId()); + _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb); + } else { + // failed to add the provisioned load balancer into cloudstack so destroy the appliance + DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP); + DestroyLoadBalancerApplianceAnswer answer = null; + try { + answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd); + if (answer == null || !answer.getResult()) { + 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 + _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); + _networkMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + } + } catch (Exception e) { + s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage()); + } + } + } + } + } + } + } + + return lbDevice; + } + + @Override + public ExternalLoadBalancerDeviceVO findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException { + long physicalNetworkId = network.getPhysicalNetworkId(); + List lbDevices = null; + String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb); + assert (provider != null); + + if (dedicatedLb) { + lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free); + if (lbDevices != null && !lbDevices.isEmpty()) { + // return first device that is free, fully configured and meant for dedicated use + for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { + if (lbdevice.getState() == LBDeviceState.Enabled && lbdevice.getIsDedicatedDevice()) { + return lbdevice; + } + } + } + } else { + // get the LB devices that are already allocated for shared use + lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Shared); + + if (lbDevices != null) { + + ExternalLoadBalancerDeviceVO maxFreeCapacityLbdevice = null; + long maxFreeCapacity = 0; + + // loop through the LB device in the physical network and pick the one with maximum free capacity + for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { + + // skip if device is not enabled + if (lbdevice.getState() != LBDeviceState.Enabled) { + continue; + } + + // get the used capacity from the list of guest networks that are mapped to this load balancer + List mappedNetworks = _networkExternalLBDao.listByLoadBalancerDeviceId(lbdevice.getId()); + long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty())) ? 0 : mappedNetworks.size(); + + // get the configured capacity for this device + long fullCapacity = lbdevice.getCapacity(); + if (fullCapacity == 0) { + fullCapacity = _defaultLbCapacity; // if capacity not configured then use the default + } + + long freeCapacity = fullCapacity - usedCapacity; + if (freeCapacity > 0) { + if (maxFreeCapacityLbdevice == null) { + maxFreeCapacityLbdevice = lbdevice; + maxFreeCapacity = freeCapacity; + } else if (freeCapacity > maxFreeCapacity) { + maxFreeCapacityLbdevice = lbdevice; + maxFreeCapacity = freeCapacity; + } + } + } + + // return the device with maximum free capacity and is meant for shared use + if (maxFreeCapacityLbdevice != null) { + return maxFreeCapacityLbdevice; + } + } + + // 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 + // 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()) { + for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) { + if (lbdevice.getState() == LBDeviceState.Enabled && !lbdevice.getIsDedicatedDevice()) { + return lbdevice; + } + } + } + } + + // there are no devices which capacity + throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " + + " to implement the network", Network.class, network.getId()); + } + + @DB + protected boolean freeLoadBalancerForNetwork(Network guestConfig) { + Transaction txn = Transaction.currentTxn(); + GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); + + try { + if (deviceMapLock.lock(120)) { + txn.start(); + // since network is shutdown remove the network mapping to the load balancer device + NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId()); + long lbDeviceId = networkLBDevice.getExternalLBDeviceId(); + _networkExternalLBDao.remove(networkLBDevice.getId()); + + List ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId()); + ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId); + boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty()); + boolean lbCloudManaged = lbDevice.getIsManagedDevice(); + + if (!lbInUse && !lbCloudManaged) { + // this is the last network mapped to the load balancer device so set device allocation state to be +// free + lbDevice.setAllocationState(LBDeviceAllocationState.Free); + _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice); + } + + // commit the changes before sending agent command to destroy cloudstack managed LB + txn.commit(); + + if (!lbInUse && lbCloudManaged) { + // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned + Host lbHost = _hostDao.findById(lbDevice.getHostId()); + String lbIP = lbHost.getPrivateIpAddress(); + DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP); + DestroyLoadBalancerApplianceAnswer answer = null; + try { + answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd); + if (answer == null || !answer.getResult()) { + s_logger.warn("Failed to destoy load balancer appliance used by the network" + guestConfig.getId() + " due to " + answer.getDetails()); + } + } catch (Exception e) { + s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage()); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId()); + } + deviceMapLock.unlock(); + + // remove the provisioned load balancer appliance from cloudstack + deleteExternalLoadBalancer(lbHost.getId()); + + // release the private IP back to dc pool, as the load balancer appliance is now destroyed + _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null); + + // release the public IP allocated for this LB appliance + DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip"); + IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString()); + _networkMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + } else { + deviceMapLock.unlock(); + } + + return true; + } else { + s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock "); + return false; + } + } catch (Exception exception) { + txn.rollback(); + s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage()); + } finally { + deviceMapLock.releaseRef(); + } + + return false; + } + + HostVO getFirewallProviderForNetwork(Network network) { + HostVO fwHost = null; + + // get the firewall provider (could be either virtual router or external firewall device) for the network + String fwProvider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Firewall); + + if (fwProvider.equalsIgnoreCase("VirtualRouter")) { + // FIXME: use network service provider container framework support to implement on virtual router + } else { + NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId()); + assert (fwDeviceForNetwork != null) : "Why firewall provider is not ready for the network to apply static nat rules?"; + long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId(); + ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId); + fwHost = _hostDao.findById(fwDevice.getHostId()); + } + + return fwHost; + } + + private boolean externalLoadBalancerIsInline(HostVO externalLoadBalancer) { + DetailVO detail = _hostDetailDao.findDetail(externalLoadBalancer.getId(), "inline"); + return (detail != null && detail.getValue().equals("true")); + } + + private NicVO savePlaceholderNic(Network network, String ipAddress) { + NicVO nic = new NicVO(null, null, network.getId(), null); + nic.setIp4Address(ipAddress); + nic.setReservationStrategy(ReservationStrategy.PlaceHolder); + nic.setState(State.Reserved); + return _nicDao.persist(nic); + } + + private NicVO getPlaceholderNic(Network network) { + List guestIps = _nicDao.listByNetworkId(network.getId()); + for (NicVO guestIp : guestIps) { + // only external firewall and external load balancer will create NicVO with PlaceHolder reservation strategy + if (guestIp.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && guestIp.getVmType() == null + && guestIp.getReserver() == null && !guestIp.getIp4Address().equals(network.getGateway())) { + return guestIp; + } + } + return null; + } + + private void applyStaticNatRuleForInlineLBRule(DataCenterVO zone, Network network, HostVO firewallHost, boolean revoked, String publicIp, String privateIp) throws ResourceUnavailableException { + List staticNatRules = new ArrayList(); + IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0); + VlanVO vlan = _vlanDao.findById(ipVO.getVlanId()); + FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null, null); + FirewallRule.State state = !revoked ? FirewallRule.State.Add : FirewallRule.State.Revoke; + fwRule.setState(state); + StaticNatRule rule = new StaticNatRuleImpl(fwRule, privateIp); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, vlan.getVlanTag(), publicIp, privateIp); + staticNatRules.add(ruleTO); + + applyStaticNatRules(staticNatRules, network, firewallHost.getId()); + } + + protected void applyStaticNatRules(List staticNatRules, Network network, long firewallHostId) throws ResourceUnavailableException { + if (!staticNatRules.isEmpty()) { + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null); + Answer answer = _agentMgr.easySend(firewallHostId, cmd); + if (answer == null || !answer.getResult()) { + String details = (answer != null) ? answer.getDetails() : "details unavailable"; + String msg = "firewall provider for the network was unable to apply static nat rules due to: " + details + "."; + s_logger.error(msg); + throw new ResourceUnavailableException(msg, Network.class, network.getId()); + } + } + } + + @Override + public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { + // Find the external load balancer in this zone + long zoneId = network.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); + + List loadBalancingRules = new ArrayList(); + + for (FirewallRule rule : rules) { + if (rule.getPurpose().equals(Purpose.LoadBalancing)) { + loadBalancingRules.add((LoadBalancingRule) rule); + } + } + + if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { + return true; + } + + ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); + if (lbDeviceVO == null) { + s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); + return true; + } + + HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + + boolean externalLoadBalancerIsInline = externalLoadBalancerIsInline(externalLoadBalancer); + + if (network.getState() == Network.State.Allocated) { + s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands."); + return true; + } + + List loadBalancersToApply = new ArrayList(); + for (int i = 0; i < loadBalancingRules.size(); i++) { + LoadBalancingRule rule = loadBalancingRules.get(i); + + boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + String protocol = rule.getProtocol(); + String algorithm = rule.getAlgorithm(); + Long lbId = rule.getId(); + String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + List sourceCidrs = rule.getSourceCidrList(); + + if (externalLoadBalancerIsInline) { + InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(srcIp); + NicVO loadBalancingIpNic = null; + HostVO firewallProviderHost = null; + + if (externalLoadBalancerIsInline) { + firewallProviderHost = getFirewallProviderForNetwork(network); + } + + if (!revoked) { + if (mapping == null) { + // Acquire a new guest IP address and save it as the load balancing IP address + String loadBalancingIpAddress = _networkMgr.acquireGuestIpAddress(network, null); + + if (loadBalancingIpAddress == null) { + String msg = "Ran out of guest IP addresses."; + s_logger.error(msg); + throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); + } + + // If a NIC doesn't exist for the load balancing IP address, create one + loadBalancingIpNic = _nicDao.findByIp4AddressAndNetworkId(loadBalancingIpAddress, network.getId()); + if (loadBalancingIpNic == null) { + loadBalancingIpNic = savePlaceholderNic(network, loadBalancingIpAddress); + } + + // Save a mapping between the source IP address and the load balancing IP address NIC + mapping = new InlineLoadBalancerNicMapVO(rule.getId(), srcIp, loadBalancingIpNic.getId()); + _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 + applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); + } else { + loadBalancingIpNic = _nicDao.findById(mapping.getNicId()); + } + } else { + if (mapping != null) { + // Find the NIC that the mapping refers to + 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 + applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); + + // Delete the mapping between the source IP address and the load balancing IP address + _inlineLoadBalancerNicMapDao.expunge(mapping.getId()); + + // Delete the NIC + _nicDao.expunge(loadBalancingIpNic.getId()); + } else { + s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet."); + continue; + } + } + + // Change the source IP address for the load balancing rule to be the load balancing IP address + srcIp = loadBalancingIpNic.getIp4Address(); + } + + 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); + } + } + + if (loadBalancersToApply.size() > 0) { + int numLoadBalancersForCommand = loadBalancersToApply.size(); + LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); + long guestVlanTag = Integer.parseInt(network.getBroadcastUri().getHost()); + cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); + Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); + if (answer == null || !answer.getResult()) { + String details = (answer != null) ? answer.getDetails() : "details unavailable"; + String msg = "Unable to apply load balancer rules to the external load balancer appliance in zone " + zone.getName() + " due to: " + details + "."; + s_logger.error(msg); + throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); + } + } + + return true; + } + + @Override + public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException { + if (guestConfig.getTrafficType() != TrafficType.Guest) { + s_logger.trace("External load balancer can only be used for guest networks."); + return false; + } + + long zoneId = guestConfig.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); + HostVO externalLoadBalancer = null; + + if (add) { + ExternalLoadBalancerDeviceVO lbDeviceVO = allocateLoadBalancerForNetwork(guestConfig); + if (lbDeviceVO == null) { + String msg = "failed to alloacate a external load balancer for the network " + guestConfig.getId(); + s_logger.error(msg); + throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId()); + } + externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + s_logger.debug("Allocated external load balancer device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId()); + } else { + // find the load balancer device allocated for the network + 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."); + return true; + } + + externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??"; + } + + // Send a command to the external load balancer to implement or shutdown the guest network + long guestVlanTag = Long.parseLong(guestConfig.getBroadcastUri().getHost()); + String selfIp = null; + String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr()); + Integer networkRate = _networkMgr.getNetworkRate(guestConfig.getId(), null); + + if (add) { + // Acquire a self-ip address from the guest network IP address range + selfIp = _networkMgr.acquireGuestIpAddress(guestConfig, null); + if (selfIp == null) { + String msg = "failed to acquire guest IP address so not implementing the network on the external load balancer "; + s_logger.error(msg); + throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId()); + } + } else { + // get the self-ip used by the load balancer + 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."); + return true; + } + selfIp = selfipNic.getIp4Address(); + } + + IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, null, networkRate, false); + IpAddressTO[] ips = new IpAddressTO[1]; + ips[0] = ip; + IpAssocCommand cmd = new IpAssocCommand(ips); + Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); + + if (answer == null || !answer.getResult()) { + String action = add ? "implement" : "shutdown"; + String answerDetails = (answer != null) ? answer.getDetails() : "answer was null"; + String msg = "External load balancer was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + " due to " + answerDetails; + s_logger.error(msg); + throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId()); + } + + if (add) { + // Insert a new NIC for this guest network to reserve the self IP + savePlaceholderNic(guestConfig, selfIp); + } else { + // release the self-ip obtained from guest network + NicVO selfipNic = getPlaceholderNic(guestConfig); + _nicDao.remove(selfipNic.getId()); + + // release the load balancer allocated for the network + boolean releasedLB = freeLoadBalancerForNetwork(guestConfig); + if (!releasedLB) { + String msg = "Failed to release the external load balancer used for the network: " + guestConfig.getId(); + s_logger.error(msg); + } + } + + if (s_logger.isDebugEnabled()) { + Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId()); + String action = add ? "implemented" : "shut down"; + s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag); + } + + return true; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); + _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, + Map details, List hostTags) { + if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) { + return null; + } + host.setType(Host.Type.ExternalLoadBalancer); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (host.getType() != com.cloud.host.Host.Type.ExternalLoadBalancer) { + return null; + } + return new DeleteHostAnswer(true); + } + +} 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..fbfdc085665 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleManager.java @@ -0,0 +1,16 @@ +// 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; + +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..df38f0ace73 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -0,0 +1,909 @@ +// 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; + +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.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.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.LoadBalancerVMMapVO; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network.Capability; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.network.as.AutoScalePolicyVO; +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.AutoScaleVmProfileVO; +import com.cloud.network.as.Condition; +import com.cloud.network.as.ConditionVO; +import com.cloud.network.as.Counter; +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.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.projects.Project.ListProjectResourcesCriteria; +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.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 + 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 + 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())) { + throw new InvalidParameterException("AutoScale counter with source='" + counter.getSource() + "' is not supported " + + "in the network where lb is configured"); + } + } + } + + + private VO getEntityInDatabase(String paramName, Long id, GenericDao dao) + { + + VO vo = dao.findById(id); + + if (vo == null) { + throw new InvalidParameterValueException("Unable to find " + paramName); + } + + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, (ControlledEntity) vo); + + return vo; + } + + private boolean isAutoScaleScaleUpPolicy(AutoScalePolicy policyVO) + { + return policyVO.getAction().equals("scaleup"); + } + + private List getAutoScalePolicies(String paramName, List policyIds, List counters, Integer 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); + + Integer prevQuietTime = 0; + + for (AutoScalePolicyVO policy : policies) { + Integer quietTime = policy.getQuietTime(); + if (prevQuietTime == 0) + prevQuietTime = quietTime; + Integer duration = policy.getDuration(); + if (interval != null && duration < interval) { + throw new InvalidParameterValueException("duration - " + duration + " specified in a policy cannot be less than vm group's interval - " + interval); + } + + if (interval != null && 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 provision policies can be specified in scaleuppolicyids"); + } + } + else { + if (isAutoScaleScaleUpPolicy(policy)) { + throw new InvalidParameterValueException("Only de-provision 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); + } + policies.add(policy); + } + return policies; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, eventDescription = "creating autoscale vm profile") + public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd) { + + Account owner = _accountDao.findById(cmd.getAccountId()); + Account caller = UserContext.current().getCaller(); + _accountMgr.checkAccess(caller, null, true, owner); + + // 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); + Long autoscaleUserId = cmd.getAutoscaleUserId(); + + if (autoscaleUserId != null) { + User autoscaleUser = _userDao.findById(autoscaleUserId); + if (autoscaleUser.getAccountId() != cmd.getEntityOwnerId()) { + throw new InvalidParameterValueException("AutoScale User id does not belong to the same account"); + } + } + else { + 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); + _autoScaleVmProfileDao.persist(profileVO); + return profileVO; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE, eventDescription = "deleting autoscale vm profile") + public boolean deleteAutoScaleVmProfile(long id) { + /* Check if entity is in database */ + getEntityInDatabase("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"); + } + return _autoScaleVmProfileDao.remove(id); + } + + @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(); + } + + @Override + public AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd) { + Long profileId = cmd.getId(); + Long templateId = cmd.getTemplateId(); + String otherDeployParams = cmd.getOtherDeployParams(); + AutoScaleVmProfileVO vmProfile = getEntityInDatabase("Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao); + + if (templateId != null) { + vmProfile.setTemplateId(templateId); + } + + if (otherDeployParams != null) { + vmProfile.setOtherDeployParams(otherDeployParams); + } + + List vmGroupList = _autoScaleVmGroupDao.listByAll(null, profileId); + for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) { + if (vmGroupVO.getState() != "disabled") { + throw new InvalidParameterValueException("Cannot delete AutoScale Vm Profile when it is being used in one or more Enabled AutoScale Vm Groups."); + } + } + boolean success = _autoScaleVmProfileDao.update(profileId, vmProfile); + + if (success) { + s_logger.debug("Updated Auto Scale Vm Profile id=" + profileId); + return vmProfile; + } else + return null; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_CREATE, eventDescription = "creating autoscale policy") + public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd cmd) { + + // Account owner = _accountDao.findById(cmd.getAccountId()); + // Account caller = UserContext.current().getCaller(); + // _accountMgr.checkAccess(caller, null, true, owner); + + Integer duration = cmd.getDuration(); + Integer quietTime = cmd.getQuietTime(); + String action = cmd.getAction(); + + if (duration != null && duration < 0) { + throw new InvalidParameterValueException("duration is an invalid value: " + duration); + } + + if (quietTime != null && quietTime < 0) { + throw new InvalidParameterValueException("quiettime is an invalid value: " + quietTime); + } + + if (!NetUtils.isValidAutoScaleAction(action)) { + throw new InvalidParameterValueException("action is invalid, only 'provision' and 'de-provision' is supported"); + } + action = action.toLowerCase(); + + SearchBuilder policySearch = _conditionDao.createSearchBuilder(); + policySearch.and("ids", policySearch.entity().getId(), Op.IN); + policySearch.done(); + SearchCriteria sc = policySearch.create(); + + List conditionIds = cmd.getConditionIds(); + sc.setParameters("ids", conditionIds.toArray(new Object[0])); + List conditions = _conditionDao.search(sc, null); + + ArrayList counterIds = new ArrayList(); + ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]); + AutoScalePolicyVO policyVO = new AutoScalePolicyVO(cmd.getDomainId(), cmd.getAccountId(), duration, quietTime, action); + sameOwnerEntities[sameOwnerEntities.length - 1] = policyVO; + _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 a condition specified"); + } + 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"); + } + } + + final Transaction txn = Transaction.currentTxn(); + txn.start(); + + policyVO = _autoScalePolicyDao.persist(policyVO); + + for (Long conditionId : conditionIds) { + AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(policyVO.getId(), conditionId); + _autoScalePolicyConditionMapDao.persist(policyConditionMapVO); + } + + txn.commit(); + + 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("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) { + success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id); + } + if (success) { + txn.commit(); + } + return success; // successful + } + + public void checkCallerAccess(String accountName, Long domainId) + { + Account caller = UserContext.current().getCaller(); + Account owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + _accountMgr.checkAccess(caller, null, true, 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(); + + sb.and("id", sb.entity().getId(), 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); + } + + SearchCriteria sc = searchWrapper.buildSearchCriteria(); + + if (id != null) { + sc.setParameters("id", id); + } + + if (conditionId != null) { + sc.setJoinParameters("asPolicyConditionSearch", "conditionId", conditionId); + } + return searchWrapper.search(); + } + + @Override + public AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd) { + Long policyId = cmd.getId(); + Integer duration = cmd.getDuration(); + Integer quietTime = cmd.getQuietTime(); + AutoScalePolicyVO policy = getEntityInDatabase("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.getState() != "disabled") { + throw new InvalidParameterValueException("Cannot delete AutoScale Policy when it is being used in one or more Enabled AutoScale Vm Groups."); + } + } + boolean success = _autoScalePolicyDao.update(policyId, policy); + + if (success) { + s_logger.debug("Updated Auto Scale Policy id=" + policyId); + return policy; + } else + return null; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group") + public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) { + int minMembers = cmd.getMinMembers(); + int maxMembers = cmd.getMaxMembers(); + + 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: " + maxMembers); + } + if (minMembers > maxMembers) { + throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " cannot be greater than " + ApiConstants.MAX_MEMBERS + ", range is invalid: " + minMembers + "-" + maxMembers); + } + + Integer interval = cmd.getInterval(); + if (interval != null && interval < 0) { + throw new InvalidParameterValueException("interval is an invalid value: " + interval); + } + + LoadBalancerVO loadBalancer = getEntityInDatabase(ApiConstants.LBID, cmd.getLbRuleId(), _lbDao); + + // Account owner = _accountDao.findById(loadBalancer.getAccountId()); + // Account caller = UserContext.current().getCaller(); + // _accountMgr.checkAccess(caller, null, true, owner); + + Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId(); + + AutoScaleVmProfileVO profileVO = getEntityInDatabase(ApiConstants.VMPROFILE_ID, cmd.getProfileId(), _autoScaleVmProfileDao); + + List existingVmGroupVO = _autoScaleVmGroupDao.listByAll(loadBalancer.getId(), null); + if (existingVmGroupVO.size() > 0) { + throw new InvalidParameterValueException("an AutoScaleVmGroup is already attached to the lb rule, the existing vm group has to be first deleted"); + } + + List mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancer.getId(), false); + if (mappedInstances.size() > 0) { + 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"); + } + + List counters = new ArrayList(); + List policies = new ArrayList(); + policies.addAll(getAutoScalePolicies("scaleuppolicyid", cmd.getScaleUpPolicyIds(), counters, interval, true)); + policies.addAll(getAutoScalePolicies("scaledownpolicyid", cmd.getScaleDownPolicyIds(), counters, interval, false)); + + 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); + + // validateAutoScaleCounters(loadBalancer.getNetworkId(), counters); + + final Transaction txn = Transaction.currentTxn(); + txn.start(); + + AutoScaleVmGroupVO vmGroupVO = new AutoScaleVmGroupVO(cmd.getLbRuleId(), zoneId, loadBalancer.getDomainId(), loadBalancer.getAccountId(), minMembers, maxMembers, loadBalancer.getDefaultPortStart(), interval, + cmd.getProfileId(), "enabled"); + vmGroupVO = _autoScaleVmGroupDao.persist(vmGroupVO); + + for (AutoScalePolicyVO autoScalePolicyVO : policies) { + _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroupVO.getId(), autoScalePolicyVO.getId())); + } + txn.commit(); + return vmGroupVO; + } + + @Override + public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) { + return _lbRulesMgr.configureLbAutoScaleVmGroup(cmd.getEntityId(), true); + } + + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group") + public boolean deleteAutoScaleVmGroup(long id) { + /* Check if entity is in database */ + AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase("AutoScale Vm Group", id, _autoScaleVmGroupDao); + autoScaleVmGroupVO.setRevoke(true); + + // TODO: call configureAutoScaleVmGroup + + Transaction txn = Transaction.currentTxn(); + txn.start(); + boolean success = _autoScaleVmGroupDao.remove(id); + if (success) + success = _autoScaleVmGroupPolicyMapDao.remove(id); + if (success) + txn.commit(); + return success; + } + + @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(); + } + + @Override + public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) { + Long vmGroupId = cmd.getId(); + Integer minMembers = cmd.getMinMembers(); + Integer maxMembers = cmd.getMaxMembers(); + List scaleUpPolicyIds = cmd.getScaleUpPolicyIds(); + List scaleDownPolicyIds = cmd.getScaleDownPolicyIds(); + + AutoScaleVmGroupVO vmGroupVO = getEntityInDatabase("Auto Scale Vm Group", vmGroupId, _autoScaleVmGroupDao); + + 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: " + maxMembers); + } + if (minMembers > maxMembers) { + throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " cannot be greater than " + ApiConstants.MAX_MEMBERS + ", range is invalid: " + minMembers + "-" + maxMembers); + } + + if (vmGroupVO.getState() == "enabled") { + throw new InvalidParameterValueException("Cannot delete AutoScale Vm Groups when it is in Enabled state."); + } + + if (minMembers != null) { + vmGroupVO.setMinMembers(minMembers); + } + + if (maxMembers != null) { + vmGroupVO.setMaxMembers(maxMembers); + } + if (scaleDownPolicyIds != null) { + // TODO - checkIDs and set + } + + if (scaleUpPolicyIds != null) { + // TODO - checkIDs and set + } + + boolean success = _autoScaleVmGroupDao.update(vmGroupId, vmGroupVO); + + if (success) { + s_logger.debug("Updated Auto Scale VmGroup id=" + vmGroupId); + return vmGroupVO; + } else + return null; + } + + @Override + public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) { + AutoScaleVmGroupVO vmGroup = getEntityInDatabase("Auto Scale Vm Group", id, _autoScaleVmGroupDao); + boolean success = false; + if (vmGroup.getState() == "enabled") { + throw new InvalidParameterValueException("The AutoScale Vm Group is already in Enabled state."); + } else { + vmGroup.setState("enabled"); + success = _lbRulesMgr.configureLbAutoScaleVmGroup(id, false); + } + if (success) + return vmGroup; + else + return null; + } + + @Override + public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) { + AutoScaleVmGroupVO vmGroup = getEntityInDatabase("Auto Scale Vm Group", id, _autoScaleVmGroupDao); + boolean success = false; + if (vmGroup.getState() == "disabled") { + throw new InvalidParameterValueException("The AutoScale Vm Group is already in Disabled state."); + } else { + vmGroup.setState("disabled"); + success = _lbRulesMgr.configureLbAutoScaleVmGroup(id, false); + } + if (success) + return vmGroup; + else + return null; + } + + @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) + @DB + 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 condition - " + cid); + } + ConditionVO condition = null; + + s_logger.debug("Adding Condition "); + condition = _conditionDao.persist(new ConditionVO(cid, threshold, cmd.getEntityOwnerId(), cmd.getDomainId(), op)); + + 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(); + SearchWrapper searchWrapper = new SearchWrapper(_conditionDao, ConditionVO.class, cmd, cmd.getId()); + SearchBuilder sb = searchWrapper.getSearchBuilder(); + + 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.addAnd("id", SearchCriteria.Op.EQ, id); + } + + if (counterId != null) { + sc.addAnd("counterId", SearchCriteria.Op.EQ, counterId); + } + + 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."); + } + + s_logger.debug("Deleting Counter " + counter.getName()); + return _counterDao.remove(counterId); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_COUNTER_DELETE, eventDescription = "condition") + public boolean deleteCondition(long conditionId) throws ResourceInUseException { + /* Check if entity is in database */ + ConditionVO condition = getEntityInDatabase("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."); + } + s_logger.debug("Deleting Condition " + condition.getId()); + return _conditionDao.remove(conditionId); + } + +} 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..434f7cd21f7 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java @@ -0,0 +1,71 @@ +// 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; + +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; + + @Column(name="revoke") + private boolean revoke = false; + + public AutoScalePolicyConditionMapVO() { } + + public AutoScalePolicyConditionMapVO(long policyId, long conditionId) { + this.policyId = policyId; + this.conditionId = conditionId; + } + + public AutoScalePolicyConditionMapVO(long policyId, long conditionId, boolean revoke) { + this(policyId, conditionId); + this.revoke = revoke; + } + + public long getId() { + return id; + } + + public long getPolicyId() { + return policyId; + } + + public long getConditionId() { + return conditionId; + } + + public boolean isRevoke() { + return revoke; + } + + public void setRevoke(boolean revoke) { + this.revoke = revoke; + } +} 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..3417a0939a0 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScalePolicyVO.java @@ -0,0 +1,132 @@ +// 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; + +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; +import com.cloud.utils.net.NetUtils; + +@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 Integer duration; + + @Column(name = "quiet_time", updatable = true, nullable = false) + private Integer quietTime = NetUtils.DEFAULT_AUTOSCALE_POLICY_QUIET_TIME; + + @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, Integer duration, Integer quietTime, String action) { + this.uuid = UUID.randomUUID().toString(); + this.domainId = domainId; + this.accountId = accountId; + this.duration = duration; + if (quietTime != null) { + 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 Integer getDuration() { + return duration; + } + + @Override + public Integer 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..07c6c917770 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java @@ -0,0 +1,70 @@ +// 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; + +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; + + @Column(name="revoke") + private boolean revoke = false; + + 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); + this.revoke = revoke; + } + + public long getId() { + return id; + } + + public long getVmGroupId() { + return vmGroupId; + } + + public long getPolicyId() { + return policyId; + } + + public boolean isRevoke() { + return revoke; + } + + public void setRevoke(boolean revoke) { + this.revoke = revoke; + } +} 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..fb4a5c68ddb --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmGroupVO.java @@ -0,0 +1,187 @@ +// 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; + +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; +import com.cloud.utils.net.NetUtils; + +@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 Integer interval = NetUtils.DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME; + + @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 = "revoke") + private boolean revoke = false; + + @Column(name = "state") + private String state; + + public AutoScaleVmGroupVO() { + } + + public AutoScaleVmGroupVO(long lbRuleId, long zoneId, long domainId, long accountId, Integer minMembers, Integer maxMembers, Integer memberPort, Integer interval, long profileId, String state) { + this.uuid = UUID.randomUUID().toString(); + this.minMembers = minMembers; + this.maxMembers = maxMembers; + this.memberPort = memberPort; + this.profileId = profileId; + this.accountId = accountId; + this.domainId = domainId; + this.zoneId = zoneId; + this.state = state; + if (interval != null) { + 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 boolean isRevoke() { + return false; + } + + public void setRevoke(boolean revoke) { + this.revoke = revoke; + } + + @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; + } +} 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..ecda5e65e88 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java @@ -0,0 +1,212 @@ +// 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; + +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(); + setZoneId(zoneId); + setDomainId(domainId); + setAccountId(accountId); + setServiceOfferingId(serviceOfferingId); + setTemplateId(templateId); + setOtherDeployParams(otherDeployParams); + setAutoscaleUserId(autoscaleUserId); + if (destroyVmGraceperiod != null) { + setDestroyVmGraceperiod(destroyVmGraceperiod); + } + if (snmpCommunity != null) { + setSnmpCommunity(snmpCommunity); + } + if (snmpPort != null) { + setSnmpPort(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; + } + + public void setServiceOfferingId(Long serviceOfferingId) { + this.serviceOfferingId = 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 setUuid(String uuid) { + this.uuid = uuid; + } + + public void setZoneId(long zoneId) { + this.zoneId = zoneId; + } + + public void setAutoscaleUserId(long autoscaleUserId) { + this.autoscaleUserId = autoscaleUserId; + } + + @Override + public Long getZoneId() { + return zoneId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + @Override + public long getAccountId() { + return accountId; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + @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..7c004cf0894 --- /dev/null +++ b/server/src/com/cloud/network/as/ConditionVO.java @@ -0,0 +1,132 @@ +// 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(); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @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..aad81aaf817 --- /dev/null +++ b/server/src/com/cloud/network/as/CounterVO.java @@ -0,0 +1,114 @@ +// 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 void setUuid(String uuid) { + this.uuid = 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..13624aa8b1f --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java @@ -0,0 +1,24 @@ +// 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.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..886b3ec931b --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java @@ -0,0 +1,54 @@ +// 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 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..646fa364a7e --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java @@ -0,0 +1,19 @@ +// 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 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..868398dc35e --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java @@ -0,0 +1,22 @@ +// 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 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..d98093a4ba1 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java @@ -0,0 +1,24 @@ +// 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.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..5735272b2f6 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java @@ -0,0 +1,58 @@ +// 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 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..83c5e1546f4 --- /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.LoadBalancerVMMapVO; +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmGroupPolicyMapDao extends GenericDao { + boolean removeByGroupId(long vmGroupId); + 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..e4d42e98a91 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java @@ -0,0 +1,55 @@ +// 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 javax.ejb.Local; + +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchCriteria; + +@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 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); + } + + 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..c45e71ec4fd --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java @@ -0,0 +1,19 @@ +// 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 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..38d0f6d44d0 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java @@ -0,0 +1,22 @@ +// 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 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/element/NetscalerElement.java b/server/src/com/cloud/network/element/NetscalerElement.java index 3febd9aaa64..16c1970e126 100644 --- a/server/src/com/cloud/network/element/NetscalerElement.java +++ b/server/src/com/cloud/network/element/NetscalerElement.java @@ -1,675 +1,675 @@ -// 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.element; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.api.ApiConstants; -import com.cloud.api.commands.AddNetscalerLoadBalancerCmd; -import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd; -import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd; -import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd; -import com.cloud.api.commands.ListNetscalerLoadBalancersCmd; -import com.cloud.api.response.NetscalerLoadBalancerResponse; -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.DataCenter.NetworkType; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.deploy.DeployDestination; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientNetworkCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.host.dao.HostDetailsDao; -import com.cloud.network.ExternalLoadBalancerDeviceManager; -import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl; -import com.cloud.network.ExternalLoadBalancerDeviceVO; -import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState; -import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; -import com.cloud.network.Network.Capability; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; -import com.cloud.network.NetworkExternalLoadBalancerVO; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkVO; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.PublicIpAddress; -import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkExternalLoadBalancerDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.resource.NetscalerResource; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.LbStickinessMethod; -import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; -import com.cloud.network.rules.StaticNat; -import com.cloud.offering.NetworkOffering; -import com.cloud.resource.ServerResource; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.Inject; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.UrlUtil; -import com.cloud.vm.NicProfile; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachineProfile; -import com.google.gson.Gson; - -@Local(value = NetworkElement.class) -public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer, - StaticNatServiceProvider { - - private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); - - @Inject - NetworkManager _networkManager; - @Inject - ConfigurationManager _configMgr; - @Inject - NetworkServiceMapDao _ntwkSrvcDao; - @Inject - AgentManager _agentMgr; - @Inject - NetworkManager _networkMgr; - @Inject - HostDao _hostDao; - @Inject - DataCenterDao _dcDao; - @Inject - ExternalLoadBalancerDeviceDao _lbDeviceDao; - @Inject - NetworkExternalLoadBalancerDao _networkLBDao; - @Inject - PhysicalNetworkDao _physicalNetworkDao; - @Inject - NetworkDao _networkDao; - @Inject - HostDetailsDao _detailsDao; - @Inject - ConfigurationDao _configDao; - - 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); - boolean handleInBasicZone = (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); - - if (!(handleInAdvanceZone || handleInBasicZone)) { - s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + config.getTrafficType() + " in zone of type " + zone.getNetworkType()); - return false; - } - - return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao.canProviderSupportServiceInNetwork(config.getId(), service, Network.Provider.Netscaler)); - } - - private boolean isBasicZoneNetwok(Network config) { - DataCenter zone = _dcDao.findById(config.getDataCenterId()); - return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); - } - - @Override - public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, - 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() + - " and traffic type " + guestConfig.getTrafficType()); - return false; - } - - try { - return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig); - } catch (InsufficientCapacityException capacityException) { - throw new ResourceUnavailableException("There are no NetScaler load balancer devices with the free capacity for implementing this network", DataCenter.class, guestConfig.getDataCenterId()); - } - } - - @Override - public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, - InsufficientNetworkCapacityException, ResourceUnavailableException { - return true; - } - - @Override - public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) { - return true; - } - - @Override - public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup) throws ResourceUnavailableException, ConcurrentOperationException { - if (!canHandle(guestConfig, Service.Lb)) { - return false; - } - - try { - return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig); - } catch (InsufficientCapacityException capacityException) { - // TODO: handle out of capacity exception gracefully in case of multple providers available - return false; - } - } - - @Override - public boolean destroy(Network config) { - return true; - } - - @Override - public boolean validateLBRule(Network network, LoadBalancingRule rule) { - return true; - } - - @Override - public boolean applyLBRules(Network config, List rules) throws ResourceUnavailableException { - if (!canHandle(config, Service.Lb)) { - return false; - } - - if (isBasicZoneNetwok(config)) { - return applyElasticLoadBalancerRules(config, rules); - } else { - return applyLoadBalancerRules(config, rules); - } - } - - @Override - public Map> getCapabilities() { - Map> capabilities = new HashMap>(); - - // Set capabilities for LB service - Map lbCapabilities = new HashMap(); - - // Specifies that the RoundRobin and Leastconn algorithms are supported for load balancing rules - lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn"); - - // specifies that Netscaler network element can provided both shared and isolation modes - lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated, shared"); - - // Specifies that load balancing rules can be made for either TCP or UDP traffic - lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); - - // Specifies that this element can measure network usage on a per public IP basis - lbCapabilities.put(Capability.TrafficStatistics, "per public ip"); - - // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs - lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); - - LbStickinessMethod method; - List methodList = new ArrayList(); - method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http"); - methodList.add(method); - method.addParam("holdtime", false, "time period in minutes for which persistence is in effect.", false); - - method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, "This is app session based sticky method, can be used only for http"); - methodList.add(method); - method.addParam("name", true, "cookie name passed in http header by apllication to the client", false); - - method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based sticky method, can be used for any type of protocol."); - methodList.add(method); - method.addParam("holdtime", false, "time period for which persistence is in effect.", false); - - Gson gson = new Gson(); - String stickyMethodList = gson.toJson(methodList); - lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList); - - lbCapabilities.put(Capability.ElasticLb, "true"); - - capabilities.put(Service.Lb, lbCapabilities); - - Map staticNatCapabilities = new HashMap(); - staticNatCapabilities.put(Capability.ElasticIp, "true"); - capabilities.put(Service.StaticNat, staticNatCapabilities); - - // TODO - Murali, please put correct capabilities here - Map firewallCapabilities = new HashMap(); - firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); - firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); - firewallCapabilities.put(Capability.MultipleIps, "true"); - capabilities.put(Service.Firewall, firewallCapabilities); - - return capabilities; - } - - @Override - public ExternalLoadBalancerDeviceVO addNetscalerLoadBalancer(AddNetscalerLoadBalancerCmd cmd) { - String deviceName = cmd.getDeviceType(); - - if (!isNetscalerDevice(deviceName)) { - throw new InvalidParameterValueException("Invalid Netscaler device type"); - } - - URI uri; - try { - uri = new URI(cmd.getUrl()); - } catch (Exception e) { - String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to " + e.getMessage(); - s_logger.debug(msg); - throw new InvalidParameterValueException(msg); - } - Map configParams = new HashMap(); - UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); - boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; - - if (dedicatedUse && !deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())) { - String msg = "Only Netscaler VPX load balancers can be specified for dedicated use"; - s_logger.debug(msg); - throw new InvalidParameterValueException(msg); - } - - ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceName, (ServerResource) new NetscalerResource()); - return lbDeviceVO; - } - - @Override - public boolean deleteNetscalerLoadBalancer(DeleteNetscalerLoadBalancerCmd cmd) { - Long lbDeviceId = cmd.getLoadBalancerDeviceId(); - - ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); - if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId); - } - - return deleteExternalLoadBalancer(lbDeviceVo.getHostId()); - } - - @Override - public ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(ConfigureNetscalerLoadBalancerCmd cmd) { - Long lbDeviceId = cmd.getLoadBalancerDeviceId(); - Boolean dedicatedUse = cmd.getLoadBalancerDedicated(); - Boolean inline = cmd.getLoadBalancerInline(); - Long capacity = cmd.getLoadBalancerCapacity(); - - try { - return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse); - } catch (Exception e) { - throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage()); - } - } - - @DB - private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean inline, Boolean dedicatedUse) { - ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); - Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); - - if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId); - } - - String deviceName = lbDeviceVo.getDeviceName(); - if (dedicatedUse != null || capacity != null || inline != null) { - if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) || - NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { - if (dedicatedUse != null && dedicatedUse == true) { - throw new InvalidParameterValueException("Netscaler MPX and SDX device should be shared and can not be dedicated to a single account."); - } - } - - // check if any networks are using this netscaler device - List networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); - if ((networks != null) && !networks.isEmpty()) { - if (capacity != null && capacity < networks.size()) { - throw new CloudRuntimeException("There are more number of networks already using this netscaler device than configured capacity"); - } - - if (dedicatedUse != null && dedicatedUse == true) { - throw new CloudRuntimeException("There are networks already using this netscaler device to make device dedicated"); - } - - if (inline != null) { - boolean _setInline = Boolean.parseBoolean((String) 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"); - } - } - } - } - - if (!NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { - if (capacity != null) { - lbDeviceVo.setCapacity(capacity); - } - } else { - // FIXME how to interpret configured capacity of the SDX device - } - - if (dedicatedUse != null) { - lbDeviceVo.setIsDedicatedDevice(dedicatedUse); - } - - if (inline != null && inline == true) { - lbDeviceVo.setIsInlineMode(true); - lbDetails.put("inline", "true"); - } else { - lbDeviceVo.setIsInlineMode(false); - lbDetails.put("inline", "false"); - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - _lbDeviceDao.update(lbDeviceId, lbDeviceVo); - - // FIXME get the row lock to avoid race condition - _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails); - HostVO host = _hostDao.findById(lbDeviceVo.getHostId()); - txn.commit(); - - _agentMgr.reconnect(host.getId()); - return lbDeviceVo; - } - - @Override - public String getPropertiesFile() { - return "netscalerloadbalancer_commands.properties"; - } - - @Override - public List listNetworks(ListNetscalerLoadBalancerNetworksCmd cmd) { - Long lbDeviceId = cmd.getLoadBalancerDeviceId(); - List networks = new ArrayList(); - - ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); - if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID " + lbDeviceId); - } - - List networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); - if (networkLbMaps != null && !networkLbMaps.isEmpty()) { - for (NetworkExternalLoadBalancerVO networkLbMap : networkLbMaps) { - NetworkVO network = _networkDao.findById(networkLbMap.getNetworkId()); - networks.add(network); - } - } - - return networks; - } - - @Override - public List listNetscalerLoadBalancers(ListNetscalerLoadBalancersCmd cmd) { - Long physcialNetworkId = cmd.getPhysicalNetworkId(); - Long lbDeviceId = cmd.getLoadBalancerDeviceId(); - PhysicalNetworkVO pNetwork = null; - List lbDevices = new ArrayList(); - - if (physcialNetworkId == null && lbDeviceId == null) { - throw new InvalidParameterValueException("Either physical network Id or load balancer device Id must be specified"); - } - - if (lbDeviceId != null) { - ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); - if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID: " + lbDeviceId); - } - lbDevices.add(lbDeviceVo); - return lbDevices; - } - - if (physcialNetworkId != null) { - pNetwork = _physicalNetworkDao.findById(physcialNetworkId); - if (pNetwork == null) { - throw new InvalidParameterValueException("Could not find phyical network with ID: " + physcialNetworkId); - } - lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName()); - return lbDevices; - } - - return null; - } - - @Override - public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO) { - NetscalerLoadBalancerResponse response = new NetscalerLoadBalancerResponse(); - Host lbHost = _hostDao.findById(lbDeviceVO.getHostId()); - Map lbDetails = _detailsDao.findDetails(lbDeviceVO.getHostId()); - - response.setId(lbDeviceVO.getId()); - response.setIpAddress(lbHost.getPrivateIpAddress()); - response.setPhysicalNetworkId(lbDeviceVO.getPhysicalNetworkId()); - response.setPublicInterface(lbDetails.get("publicInterface")); - response.setPrivateInterface(lbDetails.get("privateInterface")); - response.setDeviceName(lbDeviceVO.getDeviceName()); - if (lbDeviceVO.getCapacity() == 0) { - long defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); - response.setDeviceCapacity(defaultLbCapacity); - } else { - response.setDeviceCapacity(lbDeviceVO.getCapacity()); - } - response.setInlineMode(lbDeviceVO.getIsInLineMode()); - response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice()); - response.setProvider(lbDeviceVO.getProviderName()); - response.setDeviceState(lbDeviceVO.getState().name()); - response.setObjectName("netscalerloadbalancer"); - return response; - } - - @Override - public Provider getProvider() { - return Provider.Netscaler; - } - - @Override - public boolean isReady(PhysicalNetworkServiceProvider provider) { - 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 - if (lbDevices != null && !lbDevices.isEmpty()) { - for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { - if (lbDevice.getState() == LBDeviceState.Enabled) { - return true; - } - } - } - return false; - } - - @Override - public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { - // TODO reset the configuration on all of the netscaler devices in this physical network - return true; - } - - @Override - public boolean canEnableIndividualServices() { - return true; - } - - private boolean isNetscalerDevice(String deviceName) { - if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName())) && - (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName())) && - (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) { - return false; - } else { - return true; - } - } - - @Override - public boolean verifyServicesCombination(List services) { - List netscalerServices = new ArrayList(); - netscalerServices.add(Service.Lb.getName()); - netscalerServices.add(Service.StaticNat.getName()); - - // 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."); - return false; - } - - return true; - } - - @Override - public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { - // return true, as IP will be associated as part of LB rule configuration - return false; - } - - @Override - public IpDeployer getIpDeployer(Network network) { - return this; - } - - public boolean applyElasticLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { - - List loadBalancingRules = new ArrayList(); - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } - - if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { - return true; - } - - String errMsg = null; - ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); - if (lbDeviceVO == null) { - try { - lbDeviceVO = allocateLoadBalancerForNetwork(network); - } catch (Exception e) { - errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to " + e.getMessage(); - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - } - - if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) { - errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules."; - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - - List loadBalancersToApply = new ArrayList(); - for (int i = 0; i < loadBalancingRules.size(); i++) { - LoadBalancingRule rule = loadBalancingRules.get(i); - boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); - String protocol = rule.getProtocol(); - String algorithm = rule.getAlgorithm(); - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); - 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()); - loadBalancersToApply.add(loadBalancer); - } - } - - if (loadBalancersToApply.size() > 0) { - int numLoadBalancersForCommand = loadBalancersToApply.size(); - LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); - - HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); - Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "Unable to apply elastic load balancer rules to the external load balancer appliance in zone " + network.getDataCenterId() + " due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); - } - } - - return true; - } - - @Override - public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { - - if (!canHandle(config, Service.StaticNat)) { - return false; - } - - String errMsg; - ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config); - if (lbDevice == null) { - try { - lbDevice = allocateLoadBalancerForNetwork(config); - } catch (Exception e) { - errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage(); - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - } - - if (!isNetscalerDevice(lbDevice.getDeviceName())) { - errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules."; - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - - SetStaticNatRulesAnswer answer = null; - try { - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (StaticNat rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); - rulesTO.add(ruleTO); - } - } - - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null); - answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd); - if (answer == null) { - return false; - } else { - return answer.getResult(); - } - } catch (Exception e) { - s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage()); - return false; - } - } - -} \ No newline at end of file +// 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.element; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.api.ApiConstants; +import com.cloud.api.commands.AddNetscalerLoadBalancerCmd; +import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd; +import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd; +import com.cloud.api.commands.ListNetscalerLoadBalancersCmd; +import com.cloud.api.response.NetscalerLoadBalancerResponse; +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.DataCenter.NetworkType; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.network.ExternalLoadBalancerDeviceManager; +import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl; +import com.cloud.network.ExternalLoadBalancerDeviceVO; +import com.cloud.network.ExternalLoadBalancerDeviceVO.LBDeviceState; +import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkExternalLoadBalancerVO; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkVO; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkExternalLoadBalancerDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.resource.NetscalerResource; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.LbStickinessMethod; +import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; +import com.cloud.network.rules.StaticNat; +import com.cloud.offering.NetworkOffering; +import com.cloud.resource.ServerResource; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.UrlUtil; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; +import com.google.gson.Gson; + +@Local(value = NetworkElement.class) +public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer, + StaticNatServiceProvider { + + private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); + + @Inject + NetworkManager _networkManager; + @Inject + ConfigurationManager _configMgr; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + AgentManager _agentMgr; + @Inject + NetworkManager _networkMgr; + @Inject + HostDao _hostDao; + @Inject + DataCenterDao _dcDao; + @Inject + ExternalLoadBalancerDeviceDao _lbDeviceDao; + @Inject + NetworkExternalLoadBalancerDao _networkLBDao; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + NetworkDao _networkDao; + @Inject + HostDetailsDao _detailsDao; + @Inject + ConfigurationDao _configDao; + + 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); + boolean handleInBasicZone = (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); + + if (!(handleInAdvanceZone || handleInBasicZone)) { + s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + config.getTrafficType() + " in zone of type " + zone.getNetworkType()); + return false; + } + + return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao.canProviderSupportServiceInNetwork(config.getId(), service, Network.Provider.Netscaler)); + } + + private boolean isBasicZoneNetwok(Network config) { + DataCenter zone = _dcDao.findById(config.getDataCenterId()); + return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); + } + + @Override + public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, + 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() + + " and traffic type " + guestConfig.getTrafficType()); + return false; + } + + try { + return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig); + } catch (InsufficientCapacityException capacityException) { + throw new ResourceUnavailableException("There are no NetScaler load balancer devices with the free capacity for implementing this network", DataCenter.class, guestConfig.getDataCenterId()); + } + } + + @Override + public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + InsufficientNetworkCapacityException, ResourceUnavailableException { + return true; + } + + @Override + public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) { + return true; + } + + @Override + public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup) throws ResourceUnavailableException, ConcurrentOperationException { + if (!canHandle(guestConfig, Service.Lb)) { + return false; + } + + try { + return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig); + } catch (InsufficientCapacityException capacityException) { + // TODO: handle out of capacity exception gracefully in case of multple providers available + return false; + } + } + + @Override + public boolean destroy(Network config) { + return true; + } + + @Override + public boolean validateLBRule(Network network, LoadBalancingRule rule) { + return true; + } + + @Override + public boolean applyLBRules(Network config, List rules) throws ResourceUnavailableException { + if (!canHandle(config, Service.Lb)) { + return false; + } + + if (isBasicZoneNetwok(config)) { + return applyElasticLoadBalancerRules(config, rules); + } else { + return applyLoadBalancerRules(config, rules); + } + } + + @Override + public Map> getCapabilities() { + Map> capabilities = new HashMap>(); + + // Set capabilities for LB service + Map lbCapabilities = new HashMap(); + + // Specifies that the RoundRobin and Leastconn algorithms are supported for load balancing rules + lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn"); + + // specifies that Netscaler network element can provided both shared and isolation modes + lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated, shared"); + + // Specifies that load balancing rules can be made for either TCP or UDP traffic + lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); + + // Specifies that this element can measure network usage on a per public IP basis + lbCapabilities.put(Capability.TrafficStatistics, "per public ip"); + + // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs + lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); + + LbStickinessMethod method; + List methodList = new ArrayList(); + method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http"); + methodList.add(method); + method.addParam("holdtime", false, "time period in minutes for which persistence is in effect.", false); + + method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, "This is app session based sticky method, can be used only for http"); + methodList.add(method); + method.addParam("name", true, "cookie name passed in http header by apllication to the client", false); + + method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based sticky method, can be used for any type of protocol."); + methodList.add(method); + method.addParam("holdtime", false, "time period for which persistence is in effect.", false); + + Gson gson = new Gson(); + String stickyMethodList = gson.toJson(methodList); + lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList); + + lbCapabilities.put(Capability.ElasticLb, "true"); + + capabilities.put(Service.Lb, lbCapabilities); + + Map staticNatCapabilities = new HashMap(); + staticNatCapabilities.put(Capability.ElasticIp, "true"); + capabilities.put(Service.StaticNat, staticNatCapabilities); + + // TODO - Murali, please put correct capabilities here + Map firewallCapabilities = new HashMap(); + firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); + firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); + firewallCapabilities.put(Capability.MultipleIps, "true"); + capabilities.put(Service.Firewall, firewallCapabilities); + + return capabilities; + } + + @Override + public ExternalLoadBalancerDeviceVO addNetscalerLoadBalancer(AddNetscalerLoadBalancerCmd cmd) { + String deviceName = cmd.getDeviceType(); + + if (!isNetscalerDevice(deviceName)) { + throw new InvalidParameterValueException("Invalid Netscaler device type"); + } + + URI uri; + try { + uri = new URI(cmd.getUrl()); + } catch (Exception e) { + String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to " + e.getMessage(); + s_logger.debug(msg); + throw new InvalidParameterValueException(msg); + } + Map configParams = new HashMap(); + UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); + boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; + + if (dedicatedUse && !deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())) { + String msg = "Only Netscaler VPX load balancers can be specified for dedicated use"; + s_logger.debug(msg); + throw new InvalidParameterValueException(msg); + } + + ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceName, (ServerResource) new NetscalerResource()); + return lbDeviceVO; + } + + @Override + public boolean deleteNetscalerLoadBalancer(DeleteNetscalerLoadBalancerCmd cmd) { + Long lbDeviceId = cmd.getLoadBalancerDeviceId(); + + ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); + if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { + throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId); + } + + return deleteExternalLoadBalancer(lbDeviceVo.getHostId()); + } + + @Override + public ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(ConfigureNetscalerLoadBalancerCmd cmd) { + Long lbDeviceId = cmd.getLoadBalancerDeviceId(); + Boolean dedicatedUse = cmd.getLoadBalancerDedicated(); + Boolean inline = cmd.getLoadBalancerInline(); + Long capacity = cmd.getLoadBalancerCapacity(); + + try { + return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse); + } catch (Exception e) { + throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage()); + } + } + + @DB + private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean inline, Boolean dedicatedUse) { + ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); + Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); + + if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { + throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId); + } + + String deviceName = lbDeviceVo.getDeviceName(); + if (dedicatedUse != null || capacity != null || inline != null) { + if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) || + NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { + if (dedicatedUse != null && dedicatedUse == true) { + throw new InvalidParameterValueException("Netscaler MPX and SDX device should be shared and can not be dedicated to a single account."); + } + } + + // check if any networks are using this netscaler device + List networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); + if ((networks != null) && !networks.isEmpty()) { + if (capacity != null && capacity < networks.size()) { + throw new CloudRuntimeException("There are more number of networks already using this netscaler device than configured capacity"); + } + + if (dedicatedUse != null && dedicatedUse == true) { + throw new CloudRuntimeException("There are networks already using this netscaler device to make device dedicated"); + } + + if (inline != null) { + boolean _setInline = Boolean.parseBoolean((String) 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"); + } + } + } + } + + if (!NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { + if (capacity != null) { + lbDeviceVo.setCapacity(capacity); + } + } else { + // FIXME how to interpret configured capacity of the SDX device + } + + if (dedicatedUse != null) { + lbDeviceVo.setIsDedicatedDevice(dedicatedUse); + } + + if (inline != null && inline == true) { + lbDeviceVo.setIsInlineMode(true); + lbDetails.put("inline", "true"); + } else { + lbDeviceVo.setIsInlineMode(false); + lbDetails.put("inline", "false"); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + _lbDeviceDao.update(lbDeviceId, lbDeviceVo); + + // FIXME get the row lock to avoid race condition + _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails); + HostVO host = _hostDao.findById(lbDeviceVo.getHostId()); + txn.commit(); + + _agentMgr.reconnect(host.getId()); + return lbDeviceVo; + } + + @Override + public String getPropertiesFile() { + return "netscalerloadbalancer_commands.properties"; + } + + @Override + public List listNetworks(ListNetscalerLoadBalancerNetworksCmd cmd) { + Long lbDeviceId = cmd.getLoadBalancerDeviceId(); + List networks = new ArrayList(); + + ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); + if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { + throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID " + lbDeviceId); + } + + List networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); + if (networkLbMaps != null && !networkLbMaps.isEmpty()) { + for (NetworkExternalLoadBalancerVO networkLbMap : networkLbMaps) { + NetworkVO network = _networkDao.findById(networkLbMap.getNetworkId()); + networks.add(network); + } + } + + return networks; + } + + @Override + public List listNetscalerLoadBalancers(ListNetscalerLoadBalancersCmd cmd) { + Long physcialNetworkId = cmd.getPhysicalNetworkId(); + Long lbDeviceId = cmd.getLoadBalancerDeviceId(); + PhysicalNetworkVO pNetwork = null; + List lbDevices = new ArrayList(); + + if (physcialNetworkId == null && lbDeviceId == null) { + throw new InvalidParameterValueException("Either physical network Id or load balancer device Id must be specified"); + } + + if (lbDeviceId != null) { + ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); + if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { + throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID: " + lbDeviceId); + } + lbDevices.add(lbDeviceVo); + return lbDevices; + } + + if (physcialNetworkId != null) { + pNetwork = _physicalNetworkDao.findById(physcialNetworkId); + if (pNetwork == null) { + throw new InvalidParameterValueException("Could not find phyical network with ID: " + physcialNetworkId); + } + lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName()); + return lbDevices; + } + + return null; + } + + @Override + public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO) { + NetscalerLoadBalancerResponse response = new NetscalerLoadBalancerResponse(); + Host lbHost = _hostDao.findById(lbDeviceVO.getHostId()); + Map lbDetails = _detailsDao.findDetails(lbDeviceVO.getHostId()); + + response.setId(lbDeviceVO.getId()); + response.setIpAddress(lbHost.getPrivateIpAddress()); + response.setPhysicalNetworkId(lbDeviceVO.getPhysicalNetworkId()); + response.setPublicInterface(lbDetails.get("publicInterface")); + response.setPrivateInterface(lbDetails.get("privateInterface")); + response.setDeviceName(lbDeviceVO.getDeviceName()); + if (lbDeviceVO.getCapacity() == 0) { + long defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); + response.setDeviceCapacity(defaultLbCapacity); + } else { + response.setDeviceCapacity(lbDeviceVO.getCapacity()); + } + response.setInlineMode(lbDeviceVO.getIsInLineMode()); + response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice()); + response.setProvider(lbDeviceVO.getProviderName()); + response.setDeviceState(lbDeviceVO.getState().name()); + response.setObjectName("netscalerloadbalancer"); + return response; + } + + @Override + public Provider getProvider() { + return Provider.Netscaler; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + 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 + if (lbDevices != null && !lbDevices.isEmpty()) { + for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { + if (lbDevice.getState() == LBDeviceState.Enabled) { + return true; + } + } + } + return false; + } + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException { + // TODO reset the configuration on all of the netscaler devices in this physical network + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return true; + } + + private boolean isNetscalerDevice(String deviceName) { + if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName())) && + (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName())) && + (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) { + return false; + } else { + return true; + } + } + + @Override + public boolean verifyServicesCombination(List services) { + List netscalerServices = new ArrayList(); + netscalerServices.add(Service.Lb.getName()); + netscalerServices.add(Service.StaticNat.getName()); + + // 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."); + return false; + } + + return true; + } + + @Override + public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { + // return true, as IP will be associated as part of LB rule configuration + return false; + } + + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + public boolean applyElasticLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { + + List loadBalancingRules = new ArrayList(); + for (FirewallRule rule : rules) { + if (rule.getPurpose().equals(Purpose.LoadBalancing)) { + loadBalancingRules.add((LoadBalancingRule) rule); + } + } + + if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { + return true; + } + + String errMsg = null; + ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); + if (lbDeviceVO == null) { + try { + lbDeviceVO = allocateLoadBalancerForNetwork(network); + } catch (Exception e) { + errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to " + e.getMessage(); + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } + } + + if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) { + errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules."; + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } + + List loadBalancersToApply = new ArrayList(); + for (int i = 0; i < loadBalancingRules.size(); i++) { + LoadBalancingRule rule = loadBalancingRules.get(i); + boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + String protocol = rule.getProtocol(); + String algorithm = rule.getAlgorithm(); + String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + + if (destinations != null && !destinations.isEmpty()) { + LoadBalancerTO loadBalancer = new LoadBalancerTO(rule.getId(), srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + loadBalancersToApply.add(loadBalancer); + } + } + + if (loadBalancersToApply.size() > 0) { + int numLoadBalancersForCommand = loadBalancersToApply.size(); + LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); + + HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); + if (answer == null || !answer.getResult()) { + String details = (answer != null) ? answer.getDetails() : "details unavailable"; + String msg = "Unable to apply elastic load balancer rules to the external load balancer appliance in zone " + network.getDataCenterId() + " due to: " + details + "."; + s_logger.error(msg); + throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); + } + } + + return true; + } + + @Override + public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { + + if (!canHandle(config, Service.StaticNat)) { + return false; + } + + String errMsg; + ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config); + if (lbDevice == null) { + try { + lbDevice = allocateLoadBalancerForNetwork(config); + } catch (Exception e) { + errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage(); + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } + } + + if (!isNetscalerDevice(lbDevice.getDeviceName())) { + errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules."; + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } + + SetStaticNatRulesAnswer answer = null; + try { + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (StaticNat rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + rulesTO.add(ruleTO); + } + } + + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null); + answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd); + if (answer == null) { + return false; + } else { + return answer.getResult(); + } + } catch (Exception e) { + s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage()); + return false; + } + } + +} diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 7285da80519..06a44f15707 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -1,1038 +1,1038 @@ -// 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.lb; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.AgentManager.OnError; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.check.CheckSshAnswer; -import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.manager.Commands; -import com.cloud.api.commands.CreateLoadBalancerRuleCmd; -import com.cloud.configuration.Config; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.Pod; -import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.PodVlanMapDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.deploy.DataCenterDeployment; -import com.cloud.deploy.DeployDestination; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.NetworkRuleConflictException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.ElasticLbVmMapVO; -import com.cloud.network.IPAddressVO; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; -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.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; -import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.VirtualRouterProviderDao; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.lb.dao.ElasticLbVmMapDao; -import com.cloud.network.router.VirtualNetworkApplianceManager; -import com.cloud.network.router.VirtualRouter; -import com.cloud.network.router.VirtualRouter.RedundantState; -import com.cloud.network.router.VirtualRouter.Role; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.offering.ServiceOffering; -import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.user.Account; -import com.cloud.user.AccountService; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.component.Inject; -import com.cloud.utils.component.Manager; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineGuru; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineName; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfile.Param; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; - -@Local(value = { ElasticLoadBalancerManager.class }) -public class ElasticLoadBalancerManagerImpl implements - ElasticLoadBalancerManager, Manager, VirtualMachineGuru { - private static final Logger s_logger = Logger - .getLogger(ElasticLoadBalancerManagerImpl.class); - - @Inject - IPAddressDao _ipAddressDao; - @Inject - AgentManager _agentMgr; - @Inject - NetworkManager _networkMgr; - @Inject - LoadBalancerDao _loadBalancerDao = null; - @Inject - LoadBalancingRulesManager _lbMgr; - @Inject - VirtualNetworkApplianceManager _routerMgr; - @Inject - DomainRouterDao _routerDao = null; - @Inject - protected HostPodDao _podDao = null; - @Inject - protected ClusterDao _clusterDao; - @Inject - DataCenterDao _dcDao = null; - @Inject - protected NetworkDao _networkDao; - @Inject - protected NetworkOfferingDao _networkOfferingDao; - @Inject - VMTemplateDao _templateDao = null; - @Inject - VirtualMachineManager _itMgr; - @Inject - ConfigurationDao _configDao; - @Inject - ServiceOfferingDao _serviceOfferingDao = null; - @Inject - AccountService _accountService; - @Inject - LoadBalancerDao _lbDao; - @Inject - VlanDao _vlanDao; - @Inject - PodVlanMapDao _podVlanMapDao; - @Inject - ElasticLbVmMapDao _elbVmMapDao; - @Inject - NetworkDao _networksDao; - @Inject - AccountDao _accountDao; - @Inject - PhysicalNetworkServiceProviderDao _physicalProviderDao; - @Inject - VirtualRouterProviderDao _vrProviderDao; - @Inject - NicDao _nicDao; - - - String _name; - String _instance; - static final private String _elbVmNamePrefix = "l"; - static final private String _systemVmType = "elbvm"; - - boolean _enabled; - TrafficType _frontendTrafficType = TrafficType.Guest; - - Account _systemAcct; - ServiceOfferingVO _elasticLbVmOffering; - 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) { - return null; - } else { - return podVlanMaps.getPodId(); - } - } - - - public DomainRouterVO deployLoadBalancerVM(Long networkId, IPAddressVO ipAddr, Long accountId) { - NetworkVO network = _networkDao.findById(networkId); - DataCenter dc = _dcDao.findById(network.getDataCenterId()); - Long podId = getPodIdForDirectIp(ipAddr); - Pod pod = podId == null?null:_podDao.findById(podId); - Map params = new HashMap( - 1); - params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - Account owner = _accountService.getActiveAccountByName("system", new Long(1)); - DeployDestination dest = new DeployDestination(dc, pod, null, null); - s_logger.debug("About to deploy ELB vm "); - - try { - DomainRouterVO elbVm = deployELBVm(network, dest, owner, params); - if (elbVm == null) { - throw new InvalidParameterValueException("Could not deploy or find existing ELB VM"); - } - 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; - try { - answers = _agentMgr.send(elbVm.getHostId(), cmds); - } catch (OperationTimedoutException e) { - s_logger.warn("ELB: Timed Out", e); - throw new AgentUnavailableException( - "Unable to send commands to virtual elbVm ", - elbVm.getHostId(), e); - } - - if (answers == null) { - return false; - } - - if (answers.length != cmds.size()) { - return false; - } - - // FIXME: Have to return state for individual command in the future - if (answers.length > 0) { - Answer ans = answers[0]; - return ans.getResult(); - } - return true; - } - - private void createApplyLoadBalancingRulesCommands( - List rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) { - - - LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; - int i = 0; - for (LoadBalancingRule rule : rules) { - boolean revoked = (rule.getState() - .equals(FirewallRule.State.Revoke)); - String protocol = rule.getProtocol(); - String algorithm = rule.getAlgorithm(); - - String elbIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress() - .addr(); - int srcPort = rule.getSourcePortStart(); - List destinations = rule.getDestinations(); - LoadBalancerTO lb = new LoadBalancerTO(elbIp, srcPort, protocol, algorithm, revoked, false, destinations); - lbs[i++] = lb; - } - - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), - _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress(), null, null); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, - elbVm.getPrivateIpAddress()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, - elbVm.getInstanceName()); - //FIXME: why are we setting attributes directly? Ick!! There should be accessors and - //the constructor should set defaults. - cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); - cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); - cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); - cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); - - cmds.addCommand(cmd); - - } - - protected boolean applyLBRules(DomainRouterVO elbVm, - List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, elbVm, cmds, guestNetworkId); - // 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) { - return null; - } - DomainRouterVO elbVm = _routerDao.findById(map.getElbVmId()); - return elbVm; - } - - public boolean applyLoadBalancerRules(Network network, - List rules) - throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - return true; - } - if (rules.get(0).getPurpose() != Purpose.LoadBalancing) { - 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()); - throw new ResourceUnavailableException("Unable to apply lb rules", - DataCenter.class, network.getDataCenterId()); - } - - if (elbVm.getState() == State.Running) { - //resend all rules for the public ip - List lbs = _lbDao.listByIpAddress(rules.get(0).getSourceIpAddressId()); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule( - lb, dstList, policyList); - lbRules.add(loadBalancing); - } - return applyLBRules(elbVm, lbRules, network.getId()); - } else if (elbVm.getState() == State.Stopped - || elbVm.getState() == State.Stopping) { - s_logger.debug("ELB VM is in " - + elbVm.getState() - + ", so not sending apply LoadBalancing rules commands to the backend"); - return true; - } else { - s_logger.warn("Unable to apply loadbalancing rules, ELB VM is not in the right state " - + elbVm.getState()); - throw new ResourceUnavailableException( - "Unable to apply loadbalancing rules, ELB VM is not in the right state", - VirtualRouter.class, elbVm.getId()); - } - } - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - _name = name; - final Map configs = _configDao.getConfiguration("AgentManager", params); - _systemAcct = _accountService.getSystemAccount(); - _instance = configs.get("instance.name"); - if (_instance == null) { - _instance = "VM"; - } - _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, - 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); - if (_enabled) { - String traffType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key()); - if ("guest".equalsIgnoreCase(traffType)) { - _frontendTrafficType = TrafficType.Guest; - } else if ("public".equalsIgnoreCase(traffType)){ - _frontendTrafficType = TrafficType.Public; - } else - 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) - 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; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public String getName() { - return _name; - } - - private DomainRouterVO findELBVmWithCapacity(Network guestNetwork, IPAddressVO ipAddr) { - List unusedElbVms = _elbVmMapDao.listUnusedElbVms(); - if (unusedElbVms.size() > 0) { - List candidateVms = new ArrayList(); - for (DomainRouterVO candidateVm: unusedElbVms) { - if (candidateVm.getPodIdToDeployIn() == getPodIdForDirectIp(ipAddr)) - candidateVms.add(candidateVm); - } - return candidateVms.size()==0?null:candidateVms.get(new Random().nextInt(candidateVms.size())); - } - return null; - } - - public DomainRouterVO deployELBVm(Network guestNetwork, DeployDestination dest, Account owner, Map params) throws - ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - long dcId = dest.getDataCenter().getId(); - - // lock guest network - Long guestNetworkId = guestNetwork.getId(); - guestNetwork = _networkDao.acquireInLockTable(guestNetworkId); - - if (guestNetwork == null) { - throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId); - } - - try { - - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountService.getSystemAccount(); - } - - 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; - - DataCenterDeployment plan = null; - DomainRouterVO elbVm = null; - - plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null); - - if (elbVm == null) { - long id = _routerDao.getNextInSequence(Long.class, "id"); - 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); - - List> networks = new ArrayList>(2); - NicProfile guestNic = new NicProfile(); - guestNic.setDefaultNic(true); - networks.add(new Pair(controlConfig, null)); - networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); - - - VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId); - - String typeString = "ElasticLoadBalancerVm"; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + typeString + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), VirtualRouterProviderType.ElasticLoadBalancerVm); - 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, - _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm, null); - elbVm.setRole(Role.LB); - elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner); - //TODO: create usage stats - } - - State state = elbVm.getState(); - if (state != State.Running) { - elbVm = this.start(elbVm, _accountService.getSystemUser(), _accountService.getSystemAccount(), params); - } - - - return elbVm; - } finally { - _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); - if (_itMgr.start(elbVm, params, user, caller) != null) { - return _routerDao.findById(elbVm.getId()); - } else { - return null; - } - } - - - private DomainRouterVO stop(DomainRouterVO elbVm, boolean forced, User user, Account caller) throws ConcurrentOperationException, ResourceUnavailableException { - s_logger.debug("Stopping ELB vm " + elbVm); - try { - if (_itMgr.advanceStop( elbVm, forced, user, caller)) { - return _routerDao.findById(elbVm.getId()); - } else { - return null; - } - } catch (OperationTimedoutException e) { - 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("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); - sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ); - if (ipId != null) { - sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ); - } - if (domainId != null) { - sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); - } - if (publicPort != null) { - sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ); - } - SearchCriteria sc = sb.create(); - sc.setParameters("name", lbName); - sc.setParameters("accountId", accountId); - if (ipId != null) { - sc.setParameters("sourceIpAddress", ipId); - } - if (domainId != null) { - sc.setParameters("domainId",domainId); - } - if (publicPort != null) { - 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()); - _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); - _ipAddressDao.update(ipvo.getId(), ipvo); - _networkMgr.disassociatePublicIpAddress(ipId, userId, caller); - _ipAddressDao.unassignIpAddress(ipId); - } - - @Override - @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 (ipId != null) { - return null; - } - boolean newIp = false; - account = _accountDao.acquireInLockTable(account.getId()); - if (account == null) { - s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account"); - throw new CloudRuntimeException("Failed to acquire lock on account"); - } - try { - List existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), lb.getSourcePortStart()); - if (existingLbs == null ){ - existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null); - if (existingLbs == null) { - if (lb.getSourceIpAddressId() != null) { - 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); - ipId = ip.getId(); - newIp = true; - } - } else { - ipId = existingLbs.get(0).getSourceIpAddressId(); - s_logger.debug("ELB: Found existing frontend ip for this account for this LB rule " + ipId); - } - } else { - s_logger.warn("ELB: Found existing load balancers matching requested new LB"); - throw new NetworkRuleConflictException("ELB: Found existing load balancers matching requested new LB"); - } - - Network network = _networkMgr.getNetwork(networkId); - IPAddressVO ipAddr = _ipAddressDao.findById(ipId); - - LoadBalancer result = null; - try { - lb.setSourceIpAddressId(ipId); - result = _lbMgr.createLoadBalancer(lb, false); - } catch (NetworkRuleConflictException e) { - s_logger.warn("Failed to create LB rule, not continuing with ELB deployment"); - if (newIp) { - releaseIp(ipId, UserContext.current().getCallerUserId(), account); - } - throw e; - } - - DomainRouterVO elbVm = null; - - - if (existingLbs == null) { - elbVm = findELBVmWithCapacity(network, ipAddr); - if (elbVm == null) { - elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId()); - if (elbVm == null) { - s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName()); - if (newIp) - releaseIp(ipId, UserContext.current().getCallerUserId(), account); - } - } - - } else { - ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId); - if (elbVmMap != null) { - 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) - s_logger.info("Found " + unusedElbVms.size() + " unused ELB vms"); - Set currentGcCandidates = new HashSet(); - for (DomainRouterVO elbVm: unusedElbVms) { - currentGcCandidates.add(elbVm.getId()); - } - _gcCandidateElbVmIds.retainAll(currentGcCandidates); - currentGcCandidates.removeAll(_gcCandidateElbVmIds); - User user = _accountService.getSystemUser(); - for (Long elbVmId : _gcCandidateElbVmIds) { - DomainRouterVO elbVm = _routerDao.findById(elbVmId); - boolean gceed = false; - - try { - s_logger.info("Attempting to stop ELB VM: " + elbVm); - stop(elbVm, true, user, _systemAcct); - gceed = true; - } catch (ConcurrentOperationException e) { - s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e); - } catch (ResourceUnavailableException e) { - s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e); - continue; - } - if (gceed) { - try { - s_logger.info("Attempting to destroy ELB VM: " + elbVm); - _itMgr.expunge(elbVm, user, _systemAcct); - } catch (ResourceUnavailableException e) { - s_logger.warn("Unable to destroy unused ELB vm " + elbVm + " due to ", e); - gceed = false; - } - } - if (!gceed) { - currentGcCandidates.add(elbVm.getId()); - } - - } - _gcCandidateElbVmIds = currentGcCandidates; - } - - public class CleanupThread implements Runnable { - @Override - public void run() { - garbageCollectUnusedElbVms(); - - } - - CleanupThread() { - - } - } - - @Override - public void handleDeleteLoadBalancerRule(LoadBalancer lb, long userId, Account caller) { - if (!_enabled) { - return; - } - List remainingLbs = _loadBalancerDao.listByIpAddress(lb.getSourceIpAddressId()); - if (remainingLbs.size() == 0) { - s_logger.debug("ELB mgr: releasing ip " + lb.getSourceIpAddressId() + " since no LB rules remain for this ip address"); - releaseIp(lb.getSourceIpAddressId(), userId, caller); - } - } - - - @Override - public DomainRouterVO findByName(String name) { - if (!VirtualMachineName.isValidSystemVmName(name, _instance, _elbVmNamePrefix)) { - return null; - } - - return _routerDao.findById(VirtualMachineName.getSystemVmId(name)); - } - - - @Override - public DomainRouterVO findById(long id) { - return _routerDao.findById(id); - } - - - @Override - public DomainRouterVO persist(DomainRouterVO elbVm) { - return _routerDao.persist(elbVm); - } - - - @Override - public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { - DomainRouterVO elbVm = profile.getVirtualMachine(); - - List elbNics = profile.getNics(); - Long guestNtwkId = null; - for (NicProfile routerNic : elbNics) { - if (routerNic.getTrafficType() == TrafficType.Guest) { - guestNtwkId = routerNic.getNetworkId(); - break; - } - } - - NetworkVO guestNetwork = _networkDao.findById(guestNtwkId); - - DataCenter dc = dest.getDataCenter(); - - StringBuilder buf = profile.getBootArgsBuilder(); - buf.append(" template=domP type=" + _systemVmType); - buf.append(" name=").append(profile.getHostName()); - NicProfile controlNic = null; - String defaultDns1 = null; - String defaultDns2 = null; - - for (NicProfile nic : profile.getNics()) { - int deviceId = nic.getDeviceId(); - buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); - buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); - if (nic.isDefaultNic()) { - buf.append(" gateway=").append(nic.getGateway()); - defaultDns1 = nic.getDns1(); - defaultDns2 = nic.getDns2(); - } - if (nic.getTrafficType() == TrafficType.Management) { - buf.append(" localgw=").append(dest.getPod().getGateway()); - } else if (nic.getTrafficType() == TrafficType.Control) { - // control command is sent over management network in VMware - if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Check if we need to add management server explicit route to ELB vm. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() - + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmtHost); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Added management server explicit route to ELB vm."); - } - // always add management explicit route, for basic networking setup - buf.append(" mgmtcidr=").append(_mgmtCidr); - buf.append(" localgw=").append(dest.getPod().getGateway()); - - if (dc.getNetworkType() == NetworkType.Basic) { - // ask elb vm to setup SSH on guest network - buf.append(" sshonguest=true"); - } - - } - - controlNic = nic; - } - } - 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()); - } - - if (controlNic == null) { - throw new CloudRuntimeException("Didn't start a control port"); - } - - return true; - } - - - @Override - public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { - DomainRouterVO elbVm = profile.getVirtualMachine(); - - List nics = profile.getNics(); - for (NicProfile nic : nics) { - if (nic.getTrafficType() == TrafficType.Public) { - elbVm.setPublicIpAddress(nic.getIp4Address()); - elbVm.setPublicNetmask(nic.getNetmask()); - elbVm.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Control) { - elbVm.setPrivateIpAddress(nic.getIp4Address()); - elbVm.setPrivateMacAddress(nic.getMacAddress()); - } - } - _routerDao.update(elbVm.getId(), elbVm); - - finalizeCommandsOnStart(cmds, profile); - return true; - } - - - @Override - public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { - CheckSshAnswer answer = (CheckSshAnswer) cmds.getAnswer("checkSsh"); - if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to ssh to the ELB VM: " + answer.getDetails()); - return false; - } - - return true; - } - - - @Override - public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { - DomainRouterVO elbVm = profile.getVirtualMachine(); - DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterIdToDeployIn()); - - NicProfile controlNic = null; - Long guestNetworkId = null; - - if(profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { - // TODO this is a ugly to test hypervisor type here - // for basic network mode, we will use the guest NIC for control NIC - for (NicProfile nic : profile.getNics()) { - if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { - controlNic = nic; - guestNetworkId = nic.getNetworkId(); - } - } - } else { - for (NicProfile nic : profile.getNics()) { - if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { - controlNic = nic; - } else if (nic.getTrafficType() == TrafficType.Guest) { - guestNetworkId = nic.getNetworkId(); - } - } - } - - if (controlNic == null) { - s_logger.error("Control network doesn't exist for the ELB vm " + elbVm); - return false; - } - - cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); - - // Re-apply load balancing rules - List lbs = _elbVmMapDao.listLbsForElbVm(elbVm.getId()); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); - lbRules.add(loadBalancing); - } - - s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of ELB vm " + elbVm + " start."); - if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId); - } - - return true; - } - - - @Override - public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { - if (answer != null) { - VMInstanceVO vm = profile.getVirtualMachine(); - DomainRouterVO elbVm = _routerDao.findById(vm.getId()); - processStopOrRebootAnswer(elbVm, answer); - } - } - - public void processStopOrRebootAnswer(final DomainRouterVO elbVm, Answer answer) { - //TODO: process network usage stats - } - - - @Override - public void finalizeExpunge(DomainRouterVO vm) { - // no-op - - } - - @Override - public Long convertToId(String vmName) { - if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, _elbVmNamePrefix)) { - return null; - } - - return VirtualMachineName.getSystemVmId(vmName); - } - - @Override - public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, - ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - //not supported - throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); - } - - - @Override - public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, - ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { - //not supported - throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); - } - - - @Override - public void prepareStop(VirtualMachineProfile profile) { - - } - - - @Override - public boolean recreateNeeded( - VirtualMachineProfile profile, long hostId, - Commands cmds, ReservationContext context) { - // TODO Auto-generated method stub - return false; - } -} +// 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.lb; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.api.commands.CreateLoadBalancerRuleCmd; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Pod; +import com.cloud.dc.PodVlanMapVO; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.PodVlanMapDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.ElasticLbVmMapVO; +import com.cloud.network.IPAddressVO; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; +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.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.lb.dao.ElasticLbVmMapDao; +import com.cloud.network.router.VirtualNetworkApplianceManager; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.Account; +import com.cloud.user.AccountService; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineName; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; + +@Local(value = { ElasticLoadBalancerManager.class }) +public class ElasticLoadBalancerManagerImpl implements + ElasticLoadBalancerManager, Manager, VirtualMachineGuru { + private static final Logger s_logger = Logger + .getLogger(ElasticLoadBalancerManagerImpl.class); + + @Inject + IPAddressDao _ipAddressDao; + @Inject + AgentManager _agentMgr; + @Inject + NetworkManager _networkMgr; + @Inject + LoadBalancerDao _loadBalancerDao = null; + @Inject + LoadBalancingRulesManager _lbMgr; + @Inject + VirtualNetworkApplianceManager _routerMgr; + @Inject + DomainRouterDao _routerDao = null; + @Inject + protected HostPodDao _podDao = null; + @Inject + protected ClusterDao _clusterDao; + @Inject + DataCenterDao _dcDao = null; + @Inject + protected NetworkDao _networkDao; + @Inject + protected NetworkOfferingDao _networkOfferingDao; + @Inject + VMTemplateDao _templateDao = null; + @Inject + VirtualMachineManager _itMgr; + @Inject + ConfigurationDao _configDao; + @Inject + ServiceOfferingDao _serviceOfferingDao = null; + @Inject + AccountService _accountService; + @Inject + LoadBalancerDao _lbDao; + @Inject + VlanDao _vlanDao; + @Inject + PodVlanMapDao _podVlanMapDao; + @Inject + ElasticLbVmMapDao _elbVmMapDao; + @Inject + NetworkDao _networksDao; + @Inject + AccountDao _accountDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Inject + VirtualRouterProviderDao _vrProviderDao; + @Inject + NicDao _nicDao; + + + String _name; + String _instance; + static final private String _elbVmNamePrefix = "l"; + static final private String _systemVmType = "elbvm"; + + boolean _enabled; + TrafficType _frontendTrafficType = TrafficType.Guest; + + Account _systemAcct; + ServiceOfferingVO _elasticLbVmOffering; + 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) { + return null; + } else { + return podVlanMaps.getPodId(); + } + } + + + public DomainRouterVO deployLoadBalancerVM(Long networkId, IPAddressVO ipAddr, Long accountId) { + NetworkVO network = _networkDao.findById(networkId); + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + Long podId = getPodIdForDirectIp(ipAddr); + Pod pod = podId == null?null:_podDao.findById(podId); + Map params = new HashMap( + 1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + Account owner = _accountService.getActiveAccountByName("system", new Long(1)); + DeployDestination dest = new DeployDestination(dc, pod, null, null); + s_logger.debug("About to deploy ELB vm "); + + try { + DomainRouterVO elbVm = deployELBVm(network, dest, owner, params); + if (elbVm == null) { + throw new InvalidParameterValueException("Could not deploy or find existing ELB VM"); + } + 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; + try { + answers = _agentMgr.send(elbVm.getHostId(), cmds); + } catch (OperationTimedoutException e) { + s_logger.warn("ELB: Timed Out", e); + throw new AgentUnavailableException( + "Unable to send commands to virtual elbVm ", + elbVm.getHostId(), e); + } + + if (answers == null) { + return false; + } + + if (answers.length != cmds.size()) { + return false; + } + + // FIXME: Have to return state for individual command in the future + if (answers.length > 0) { + Answer ans = answers[0]; + return ans.getResult(); + } + return true; + } + + private void createApplyLoadBalancingRulesCommands( + List rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) { + + + LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; + int i = 0; + for (LoadBalancingRule rule : rules) { + boolean revoked = (rule.getState() + .equals(FirewallRule.State.Revoke)); + String protocol = rule.getProtocol(); + String algorithm = rule.getAlgorithm(); + + String elbIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress() + .addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + LoadBalancerTO lb = new LoadBalancerTO(rule.getId(), elbIp, srcPort, protocol, algorithm, revoked, false, destinations); + lbs[i++] = lb; + } + + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), + _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress(), null, null); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, + elbVm.getPrivateIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, + elbVm.getInstanceName()); + //FIXME: why are we setting attributes directly? Ick!! There should be accessors and + //the constructor should set defaults. + cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); + cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); + cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); + cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); + + cmds.addCommand(cmd); + + } + + protected boolean applyLBRules(DomainRouterVO elbVm, + List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyLoadBalancingRulesCommands(rules, elbVm, cmds, guestNetworkId); + // 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) { + return null; + } + DomainRouterVO elbVm = _routerDao.findById(map.getElbVmId()); + return elbVm; + } + + public boolean applyLoadBalancerRules(Network network, + List rules) + throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + return true; + } + if (rules.get(0).getPurpose() != Purpose.LoadBalancing) { + 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()); + throw new ResourceUnavailableException("Unable to apply lb rules", + DataCenter.class, network.getDataCenterId()); + } + + if (elbVm.getState() == State.Running) { + //resend all rules for the public ip + List lbs = _lbDao.listByIpAddress(rules.get(0).getSourceIpAddressId()); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule( + lb, dstList, policyList); + lbRules.add(loadBalancing); + } + return applyLBRules(elbVm, lbRules, network.getId()); + } else if (elbVm.getState() == State.Stopped + || elbVm.getState() == State.Stopping) { + s_logger.debug("ELB VM is in " + + elbVm.getState() + + ", so not sending apply LoadBalancing rules commands to the backend"); + return true; + } else { + s_logger.warn("Unable to apply loadbalancing rules, ELB VM is not in the right state " + + elbVm.getState()); + throw new ResourceUnavailableException( + "Unable to apply loadbalancing rules, ELB VM is not in the right state", + VirtualRouter.class, elbVm.getId()); + } + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + _name = name; + final Map configs = _configDao.getConfiguration("AgentManager", params); + _systemAcct = _accountService.getSystemAccount(); + _instance = configs.get("instance.name"); + if (_instance == null) { + _instance = "VM"; + } + _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, + 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); + if (_enabled) { + String traffType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key()); + if ("guest".equalsIgnoreCase(traffType)) { + _frontendTrafficType = TrafficType.Guest; + } else if ("public".equalsIgnoreCase(traffType)){ + _frontendTrafficType = TrafficType.Public; + } else + 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) + 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; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + private DomainRouterVO findELBVmWithCapacity(Network guestNetwork, IPAddressVO ipAddr) { + List unusedElbVms = _elbVmMapDao.listUnusedElbVms(); + if (unusedElbVms.size() > 0) { + List candidateVms = new ArrayList(); + for (DomainRouterVO candidateVm: unusedElbVms) { + if (candidateVm.getPodIdToDeployIn() == getPodIdForDirectIp(ipAddr)) + candidateVms.add(candidateVm); + } + return candidateVms.size()==0?null:candidateVms.get(new Random().nextInt(candidateVms.size())); + } + return null; + } + + public DomainRouterVO deployELBVm(Network guestNetwork, DeployDestination dest, Account owner, Map params) throws + ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + long dcId = dest.getDataCenter().getId(); + + // lock guest network + Long guestNetworkId = guestNetwork.getId(); + guestNetwork = _networkDao.acquireInLockTable(guestNetworkId); + + if (guestNetwork == null) { + throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId); + } + + try { + + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountService.getSystemAccount(); + } + + 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; + + DataCenterDeployment plan = null; + DomainRouterVO elbVm = null; + + plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null); + + if (elbVm == null) { + long id = _routerDao.getNextInSequence(Long.class, "id"); + 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); + + List> networks = new ArrayList>(2); + NicProfile guestNic = new NicProfile(); + guestNic.setDefaultNic(true); + networks.add(new Pair(controlConfig, null)); + networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); + + + VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId); + + String typeString = "ElasticLoadBalancerVm"; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + typeString + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), VirtualRouterProviderType.ElasticLoadBalancerVm); + 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, + _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm, null); + elbVm.setRole(Role.LB); + elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner); + //TODO: create usage stats + } + + State state = elbVm.getState(); + if (state != State.Running) { + elbVm = this.start(elbVm, _accountService.getSystemUser(), _accountService.getSystemAccount(), params); + } + + + return elbVm; + } finally { + _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); + if (_itMgr.start(elbVm, params, user, caller) != null) { + return _routerDao.findById(elbVm.getId()); + } else { + return null; + } + } + + + private DomainRouterVO stop(DomainRouterVO elbVm, boolean forced, User user, Account caller) throws ConcurrentOperationException, ResourceUnavailableException { + s_logger.debug("Stopping ELB vm " + elbVm); + try { + if (_itMgr.advanceStop( elbVm, forced, user, caller)) { + return _routerDao.findById(elbVm.getId()); + } else { + return null; + } + } catch (OperationTimedoutException e) { + 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("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); + sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ); + if (ipId != null) { + sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ); + } + if (domainId != null) { + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + } + if (publicPort != null) { + sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ); + } + SearchCriteria sc = sb.create(); + sc.setParameters("name", lbName); + sc.setParameters("accountId", accountId); + if (ipId != null) { + sc.setParameters("sourceIpAddress", ipId); + } + if (domainId != null) { + sc.setParameters("domainId",domainId); + } + if (publicPort != null) { + 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()); + _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); + _ipAddressDao.update(ipvo.getId(), ipvo); + _networkMgr.disassociatePublicIpAddress(ipId, userId, caller); + _ipAddressDao.unassignIpAddress(ipId); + } + + @Override + @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 (ipId != null) { + return null; + } + boolean newIp = false; + account = _accountDao.acquireInLockTable(account.getId()); + if (account == null) { + s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account"); + throw new CloudRuntimeException("Failed to acquire lock on account"); + } + try { + List existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), lb.getSourcePortStart()); + if (existingLbs == null ){ + existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null); + if (existingLbs == null) { + if (lb.getSourceIpAddressId() != null) { + 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); + ipId = ip.getId(); + newIp = true; + } + } else { + ipId = existingLbs.get(0).getSourceIpAddressId(); + s_logger.debug("ELB: Found existing frontend ip for this account for this LB rule " + ipId); + } + } else { + s_logger.warn("ELB: Found existing load balancers matching requested new LB"); + throw new NetworkRuleConflictException("ELB: Found existing load balancers matching requested new LB"); + } + + Network network = _networkMgr.getNetwork(networkId); + IPAddressVO ipAddr = _ipAddressDao.findById(ipId); + + LoadBalancer result = null; + try { + lb.setSourceIpAddressId(ipId); + result = _lbMgr.createLoadBalancer(lb, false); + } catch (NetworkRuleConflictException e) { + s_logger.warn("Failed to create LB rule, not continuing with ELB deployment"); + if (newIp) { + releaseIp(ipId, UserContext.current().getCallerUserId(), account); + } + throw e; + } + + DomainRouterVO elbVm = null; + + + if (existingLbs == null) { + elbVm = findELBVmWithCapacity(network, ipAddr); + if (elbVm == null) { + elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId()); + if (elbVm == null) { + s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName()); + if (newIp) + releaseIp(ipId, UserContext.current().getCallerUserId(), account); + } + } + + } else { + ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId); + if (elbVmMap != null) { + 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) + s_logger.info("Found " + unusedElbVms.size() + " unused ELB vms"); + Set currentGcCandidates = new HashSet(); + for (DomainRouterVO elbVm: unusedElbVms) { + currentGcCandidates.add(elbVm.getId()); + } + _gcCandidateElbVmIds.retainAll(currentGcCandidates); + currentGcCandidates.removeAll(_gcCandidateElbVmIds); + User user = _accountService.getSystemUser(); + for (Long elbVmId : _gcCandidateElbVmIds) { + DomainRouterVO elbVm = _routerDao.findById(elbVmId); + boolean gceed = false; + + try { + s_logger.info("Attempting to stop ELB VM: " + elbVm); + stop(elbVm, true, user, _systemAcct); + gceed = true; + } catch (ConcurrentOperationException e) { + s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e); + continue; + } + if (gceed) { + try { + s_logger.info("Attempting to destroy ELB VM: " + elbVm); + _itMgr.expunge(elbVm, user, _systemAcct); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to destroy unused ELB vm " + elbVm + " due to ", e); + gceed = false; + } + } + if (!gceed) { + currentGcCandidates.add(elbVm.getId()); + } + + } + _gcCandidateElbVmIds = currentGcCandidates; + } + + public class CleanupThread implements Runnable { + @Override + public void run() { + garbageCollectUnusedElbVms(); + + } + + CleanupThread() { + + } + } + + @Override + public void handleDeleteLoadBalancerRule(LoadBalancer lb, long userId, Account caller) { + if (!_enabled) { + return; + } + List remainingLbs = _loadBalancerDao.listByIpAddress(lb.getSourceIpAddressId()); + if (remainingLbs.size() == 0) { + s_logger.debug("ELB mgr: releasing ip " + lb.getSourceIpAddressId() + " since no LB rules remain for this ip address"); + releaseIp(lb.getSourceIpAddressId(), userId, caller); + } + } + + + @Override + public DomainRouterVO findByName(String name) { + if (!VirtualMachineName.isValidSystemVmName(name, _instance, _elbVmNamePrefix)) { + return null; + } + + return _routerDao.findById(VirtualMachineName.getSystemVmId(name)); + } + + + @Override + public DomainRouterVO findById(long id) { + return _routerDao.findById(id); + } + + + @Override + public DomainRouterVO persist(DomainRouterVO elbVm) { + return _routerDao.persist(elbVm); + } + + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + DomainRouterVO elbVm = profile.getVirtualMachine(); + + List elbNics = profile.getNics(); + Long guestNtwkId = null; + for (NicProfile routerNic : elbNics) { + if (routerNic.getTrafficType() == TrafficType.Guest) { + guestNtwkId = routerNic.getNetworkId(); + break; + } + } + + NetworkVO guestNetwork = _networkDao.findById(guestNtwkId); + + DataCenter dc = dest.getDataCenter(); + + StringBuilder buf = profile.getBootArgsBuilder(); + buf.append(" template=domP type=" + _systemVmType); + buf.append(" name=").append(profile.getHostName()); + NicProfile controlNic = null; + String defaultDns1 = null; + String defaultDns2 = null; + + for (NicProfile nic : profile.getNics()) { + int deviceId = nic.getDeviceId(); + buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); + buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + if (nic.isDefaultNic()) { + buf.append(" gateway=").append(nic.getGateway()); + defaultDns1 = nic.getDns1(); + defaultDns2 = nic.getDns2(); + } + if (nic.getTrafficType() == TrafficType.Management) { + buf.append(" localgw=").append(dest.getPod().getGateway()); + } else if (nic.getTrafficType() == TrafficType.Control) { + // control command is sent over management network in VMware + if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Check if we need to add management server explicit route to ELB vm. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmtHost); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Added management server explicit route to ELB vm."); + } + // always add management explicit route, for basic networking setup + buf.append(" mgmtcidr=").append(_mgmtCidr); + buf.append(" localgw=").append(dest.getPod().getGateway()); + + if (dc.getNetworkType() == NetworkType.Basic) { + // ask elb vm to setup SSH on guest network + buf.append(" sshonguest=true"); + } + + } + + controlNic = nic; + } + } + 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()); + } + + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); + } + + return true; + } + + + @Override + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + DomainRouterVO elbVm = profile.getVirtualMachine(); + + List nics = profile.getNics(); + for (NicProfile nic : nics) { + if (nic.getTrafficType() == TrafficType.Public) { + elbVm.setPublicIpAddress(nic.getIp4Address()); + elbVm.setPublicNetmask(nic.getNetmask()); + elbVm.setPublicMacAddress(nic.getMacAddress()); + } else if (nic.getTrafficType() == TrafficType.Control) { + elbVm.setPrivateIpAddress(nic.getIp4Address()); + elbVm.setPrivateMacAddress(nic.getMacAddress()); + } + } + _routerDao.update(elbVm.getId(), elbVm); + + finalizeCommandsOnStart(cmds, profile); + return true; + } + + + @Override + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + CheckSshAnswer answer = (CheckSshAnswer) cmds.getAnswer("checkSsh"); + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to ssh to the ELB VM: " + answer.getDetails()); + return false; + } + + return true; + } + + + @Override + public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + DomainRouterVO elbVm = profile.getVirtualMachine(); + DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterIdToDeployIn()); + + NicProfile controlNic = null; + Long guestNetworkId = null; + + if(profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { + // TODO this is a ugly to test hypervisor type here + // for basic network mode, we will use the guest NIC for control NIC + for (NicProfile nic : profile.getNics()) { + if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { + controlNic = nic; + guestNetworkId = nic.getNetworkId(); + } + } + } else { + for (NicProfile nic : profile.getNics()) { + if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { + controlNic = nic; + } else if (nic.getTrafficType() == TrafficType.Guest) { + guestNetworkId = nic.getNetworkId(); + } + } + } + + if (controlNic == null) { + s_logger.error("Control network doesn't exist for the ELB vm " + elbVm); + return false; + } + + cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); + + // Re-apply load balancing rules + List lbs = _elbVmMapDao.listLbsForElbVm(elbVm.getId()); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + lbRules.add(loadBalancing); + } + + s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of ELB vm " + elbVm + " start."); + if (!lbRules.isEmpty()) { + createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId); + } + + return true; + } + + + @Override + public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { + if (answer != null) { + VMInstanceVO vm = profile.getVirtualMachine(); + DomainRouterVO elbVm = _routerDao.findById(vm.getId()); + processStopOrRebootAnswer(elbVm, answer); + } + } + + public void processStopOrRebootAnswer(final DomainRouterVO elbVm, Answer answer) { + //TODO: process network usage stats + } + + + @Override + public void finalizeExpunge(DomainRouterVO vm) { + // no-op + + } + + @Override + public Long convertToId(String vmName) { + if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, _elbVmNamePrefix)) { + return null; + } + + return VirtualMachineName.getSystemVmId(vmName); + } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public void prepareStop(VirtualMachineProfile profile) { + + } + + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java index b11695b3fd6..708d20e9cbc 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java @@ -8,7 +8,7 @@ // 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.lb; @@ -24,21 +24,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, boolean vmGroupCreation); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 88c3d11dea5..a63fd57c5be 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -1,1365 +1,1550 @@ -// 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.lb; - -import java.security.InvalidParameterException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.api.commands.CreateLBStickinessPolicyCmd; -import com.cloud.api.commands.CreateLoadBalancerRuleCmd; -import com.cloud.api.commands.ListLBStickinessPoliciesCmd; -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.ConfigurationManager; -import com.cloud.dc.dao.VlanDao; -import com.cloud.domain.dao.DomainDao; -import com.cloud.event.ActionEvent; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; -import com.cloud.event.dao.EventDao; -import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.NetworkRuleConflictException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.ExternalLoadBalancerUsageManager; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.LBStickinessPolicyVO; -import com.cloud.network.LoadBalancerVMMapVO; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; -import com.cloud.network.Network.Capability; -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.dao.FirewallRulesCidrsDao; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LBStickinessPolicyDao; -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.LbDestination; -import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.rules.FirewallManager; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.FirewallRuleType; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.LbStickinessMethod; -import com.cloud.network.rules.LbStickinessMethod.LbStickinessMethodParam; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.StickinessPolicy; -import com.cloud.offering.NetworkOffering; -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.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.DomainService; -import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; -import com.cloud.uservm.UserVm; -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.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; -import com.cloud.vm.Nic; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -@Local(value = { LoadBalancingRulesManager.class, LoadBalancingRulesService.class }) -public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, LoadBalancingRulesService, Manager { - private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class); - - String _name; - - @Inject - NetworkManager _networkMgr; - @Inject - RulesManager _rulesMgr; - @Inject - AccountManager _accountMgr; - @Inject - IPAddressDao _ipAddressDao; - @Inject - LoadBalancerDao _lbDao; - @Inject - VlanDao _vlanDao; - @Inject - EventDao _eventDao; - @Inject - LoadBalancerVMMapDao _lb2VmMapDao; - @Inject - LBStickinessPolicyDao _lb2stickinesspoliciesDao; - @Inject - UserVmDao _vmDao; - @Inject - AccountDao _accountDao; - @Inject - DomainDao _domainDao; - @Inject - NicDao _nicDao; - @Inject - UsageEventDao _usageEventDao; - @Inject - FirewallRulesCidrsDao _firewallCidrsDao; - @Inject - FirewallManager _firewallMgr; - @Inject - ElasticLoadBalancerManager _elbMgr; - @Inject - NetworkDao _networkDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - DomainService _domainMgr; - @Inject - ConfigurationManager _configMgr; - @Inject - ExternalLoadBalancerUsageManager _externalLBUsageMgr; - @Inject - NetworkServiceMapDao _ntwkSrvcDao; - @Inject - ResourceTagDao _resourceTagDao; - - private String getLBStickinessCapability(long networkid) { - Map> serviceCapabilitiesMap = _networkMgr.getNetworkCapabilities(networkid); - if (serviceCapabilitiesMap != null) { - for (Service service : serviceCapabilitiesMap.keySet()) { - ServiceResponse serviceResponse = new ServiceResponse(); - serviceResponse.setName(service.getName()); - if ("Lb".equalsIgnoreCase(service.getName())) { - Map serviceCapabilities = serviceCapabilitiesMap - .get(service); - if (serviceCapabilities != null) { - for (Capability capability : serviceCapabilities - .keySet()) { - if (Capability.SupportedStickinessMethods.getName() - .equals(capability.getName())) { - return serviceCapabilities.get(capability); - } - } - } - } - } - } - return null; - } - - private boolean genericValidator(CreateLBStickinessPolicyCmd cmd) throws InvalidParameterValueException { - LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); - /* Validation : check for valid Method name and params */ - List stickinessMethodList = getStickinessMethods(loadBalancer - .getNetworkId()); - boolean methodMatch = false; - - if (stickinessMethodList == null) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed: No Stickiness method available for LB rule with specified id", idList); - } - for (LbStickinessMethod method : stickinessMethodList) { - if (method.getMethodName().equalsIgnoreCase(cmd.getStickinessMethodName())) { - methodMatch = true; - Map apiParamList = cmd.getparamList(); - List methodParamList = method.getParamList(); - Map tempParamList = new HashMap(); - - /* - * validation-1: check for any extra params that are not - * required by the policymethod(capability), FIXME: make the - * below loop simple without using raw data type - */ - if (apiParamList != null) { - Collection userGroupCollection = apiParamList.values(); - Iterator iter = userGroupCollection.iterator(); - while (iter.hasNext()) { - HashMap paramKVpair = (HashMap) iter.next(); - String paramName = paramKVpair.get("name"); - String paramValue = paramKVpair.get("value"); - - tempParamList.put(paramName, paramValue); - Boolean found = false; - for (LbStickinessMethodParam param : methodParamList) { - if (param.getParamName().equalsIgnoreCase(paramName)) { - if ((param.getIsflag() == false) && (paramValue == null)) { - throw new InvalidParameterValueException("Failed : Value expected for the Param :" + param.getParamName(), null); - } - found = true; - break; - } - } - if (!found) { - throw new InvalidParameterValueException("Failed : Stickiness policy does not support param name :" + paramName, null); - } - } - } - - /* validation-2: check for mandatory params */ - for (LbStickinessMethodParam param : methodParamList) { - if (param.getRequired()) { - if (tempParamList.get(param.getParamName()) == null) { - throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + param.getParamName(), null); - } - } - } - /* Successfully completed the Validation */ - break; - } - } - if (methodMatch == false) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule whose id is specified", idList); - } - - /* Validation : check for the multiple policies to the rule id */ - List stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false); - if (stickinessPolicies.size() > 0) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed to create Stickiness policy: Policy already attached", idList); - } - return true; - } - - @SuppressWarnings("rawtypes") - @Override - @DB - @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "create lb stickinesspolicy to load balancer", create = true) - public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException { - UserContext caller = UserContext.current(); - - /* Validation : check corresponding load balancer rule exist */ - LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); - if (loadBalancer == null) { - throw new InvalidParameterValueException("Failed: LB rule provided not present", null); - } - - _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); - if (loadBalancer.getState() == FirewallRule.State.Revoke) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed: LB rule with specified id is in deleting state: ", idList); - } - - /* Generic validations */ - if (!genericValidator(cmd)) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation of rule with specified id failed", idList); - } - - /* Specific validations using network element validator for specific validations */ - LBStickinessPolicyVO lbpolicy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); - List policyList = new ArrayList(); - policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams())); - LoadBalancingRule lbRule = new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), policyList); - if (!_networkMgr.validateRule(lbRule)) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); - throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation of rule with specified id failed ", idList); - } - - /* Finally Insert into DB */ - LBStickinessPolicyVO policy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); - policy = _lb2stickinesspoliciesDao.persist(policy); - - return policy; - } - - @Override - @DB - @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()); - } - FirewallRule.State backupState = loadBalancer.getState(); - loadBalancer.setState(FirewallRule.State.Add); - _lbDao.persist(loadBalancer); - try { - applyLoadBalancerConfig(cmd.getLbRuleId()); - } catch (ResourceUnavailableException e) { - s_logger.warn("Unable to apply Stickiness policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e); - if (isRollBackAllowedForProvider(loadBalancer)) { - loadBalancer.setState(backupState); - _lbDao.persist(loadBalancer); - s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating sticky policy" ); - } - deleteLBStickinessPolicy(cmd.getEntityId(), false); - success = false; - } - - return success; - } - - @Override - @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); - - if (stickinessPolicy == null) { - throw new InvalidParameterException("Invalid Stickiness policy id value: " + stickinessPolicyId); - } - LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(stickinessPolicy.getLoadBalancerId())); - if (loadBalancer == null) { - throw new InvalidParameterException("Invalid Load balancer : " + stickinessPolicy.getLoadBalancerId() + " for Stickiness policy id: " + stickinessPolicyId); - } - long loadBalancerId = loadBalancer.getId(); - FirewallRule.State backupState = loadBalancer.getState(); - _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); - - - if (apply) { - if (loadBalancer.getState() == FirewallRule.State.Active) { - loadBalancer.setState(FirewallRule.State.Add); - _lbDao.persist(loadBalancer); - } - - boolean backupStickyState = stickinessPolicy.isRevoke(); - 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); - throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId); - } - } catch (ResourceUnavailableException e) { - if (isRollBackAllowedForProvider(loadBalancer)) { - stickinessPolicy.setRevoke(backupStickyState); - _lb2stickinesspoliciesDao.persist(stickinessPolicy); - loadBalancer.setState(backupState); - _lbDao.persist(loadBalancer); - s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while deleting sticky policy: " + stickinessPolicyId); - } - s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); - success = false; - } - }else{ - _lb2stickinesspoliciesDao.remove(stickinessPolicy.getLoadBalancerId()); - } - - return success; - } - - private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) { - Network network = _networkDao.findById(loadBalancer.getNetworkId()); - Provider provider = Network.Provider.Netscaler; - return _ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider); - } - @Override - @DB - @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true) - public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) { - UserContext ctx = UserContext.current(); - Account caller = ctx.getCaller(); - - LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); - if (loadBalancer == null) { - throw new InvalidParameterValueException("Failed to assign to load balancer; the load balancer was not found.", null); - } - - List mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false); - Set mappedInstanceIds = new HashSet(); - for (LoadBalancerVMMapVO mappedInstance : mappedInstances) { - mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId())); - } - - List vmsToAdd = new ArrayList(); - - for (Long instanceId : instanceIds) { - if (mappedInstanceIds.contains(instanceId)) { - List idList = new ArrayList(); - idList.add(new IdentityProxy("user_vm", instanceId, "vmId")); - throw new InvalidParameterValueException("VM with specified id is already mapped to load balancer", idList); - } - - UserVm vm = _vmDao.findById(instanceId); - if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { - throw new InvalidParameterValueException("Couldn't locate vm instance by id", null); - } - - _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller); - - if (vm.getAccountId() != loadBalancer.getAccountId()) { - throw new PermissionDeniedException("Cannot add virtual machines that do not belong to the same owner."); - } - - // Let's check to make sure the vm has a nic in the same network as the load balancing rule. - List nics = _networkMgr.getNics(vm.getId()); - Nic nicInSameNetwork = null; - for (Nic nic : nics) { - if (nic.getNetworkId() == loadBalancer.getNetworkId()) { - nicInSameNetwork = nic; - break; - } - } - - if (nicInSameNetwork == null) { - List idList = new ArrayList(); - idList.add(new IdentityProxy(vm, instanceId, "vmId")); - throw new InvalidParameterValueException("VM with specified id cannot be added because it doesn't belong in the same network.", idList); - - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Adding " + vm + " to the load balancer pool"); - } - vmsToAdd.add(vm); - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (UserVm vm : vmsToAdd) { - LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); - map = _lb2VmMapDao.persist(map); - } - txn.commit(); - - boolean success = false; - FirewallRule.State backupState = loadBalancer.getState(); - try { - loadBalancer.setState(FirewallRule.State.Add); - _lbDao.persist(loadBalancer); - applyLoadBalancerConfig(loadBalancerId); - success = true; - } catch (ResourceUnavailableException e) { - if (isRollBackAllowedForProvider(loadBalancer)) { - List vmInstanceIds = new ArrayList(); - txn = Transaction.currentTxn(); - txn.start(); - for (UserVm vm : vmsToAdd) { - vmInstanceIds.add(vm.getId()); - } - txn.commit(); - if (!vmInstanceIds.isEmpty()) { - _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null); - s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while attaching VM: " + vmInstanceIds); - } - loadBalancer.setState(backupState); - _lbDao.persist(loadBalancer); - } - 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. - throw ex; - } - - return success; - } - - @Override - @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true) - public boolean removeFromLoadBalancer(long loadBalancerId, List instanceIds) { - return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true); - } - - private boolean removeFromLoadBalancerInternal(long loadBalancerId, List instanceIds, boolean rollBack) { - UserContext caller = UserContext.current(); - - LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(loadBalancerId)); - if (loadBalancer == null) { - throw new InvalidParameterException("Invalid load balancer value: " + loadBalancerId); - } - - _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); - - boolean success = false; - FirewallRule.State backupState = loadBalancer.getState(); - try { - loadBalancer.setState(FirewallRule.State.Add); - _lbDao.persist(loadBalancer); - - for (long instanceId : instanceIds) { - LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); - map.setRevoke(true); - _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId); - } - - 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"); - 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"); - } - 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"); - throw ex; - } - return success; - } - - @Override - public boolean removeVmFromLoadBalancers(long instanceId) { - boolean success = true; - List maps = _lb2VmMapDao.listByInstanceId(instanceId); - if (maps == null || maps.isEmpty()) { - return true; - } - - Map> lbsToReconfigure = new HashMap>(); - - // first set all existing lb mappings with Revoke state - for (LoadBalancerVMMapVO map : maps) { - long lbId = map.getLoadBalancerId(); - List instances = lbsToReconfigure.get(lbId); - if (instances == null) { - instances = new ArrayList(); - } - instances.add(map.getInstanceId()); - lbsToReconfigure.put(lbId, instances); - - map.setRevoke(true); - _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + instanceId); - } - - // Reapply all lbs that had the vm assigned - if (lbsToReconfigure != null) { - for (Map.Entry> lb : lbsToReconfigure.entrySet()) { - if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false)) { - success = false; - } - } - } - return success; - } - - @Override - @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_DELETE, eventDescription = "deleting load balancer", async = true) - public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply) { - UserContext ctx = UserContext.current(); - Account caller = ctx.getCaller(); - - LoadBalancerVO rule = _lbDao.findById(loadBalancerId); - if (rule == null) { - throw new InvalidParameterValueException("Unable to find load balancer rule by id", null); - } - - _accountMgr.checkAccess(caller, null, true, rule); - - boolean result = deleteLoadBalancerRule(loadBalancerId, apply, caller, ctx.getCallerUserId(), true); - if (!result) { - throw new CloudRuntimeException("Unable to remove load balancer rule " + loadBalancerId); - } - return result; - } - - @DB - public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) { - LoadBalancerVO lb = _lbDao.findById(loadBalancerId); - Transaction txn = Transaction.currentTxn(); - boolean generateUsageEvent = false; - boolean success = true; - FirewallRule.State backupState = lb.getState(); - - txn.start(); - if (lb.getState() == FirewallRule.State.Staged) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb); - } - generateUsageEvent = true; - } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) { - lb.setState(FirewallRule.State.Revoke); - _lbDao.persist(lb); - generateUsageEvent = true; - } - List backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); - List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); - if (maps != null) { - for (LoadBalancerVMMapVO map : maps) { - map.setRevoke(true); - _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + map.getInstanceId()); - } - } - - if (generateUsageEvent) { - // Generate usage event right after all rules were marked for revoke - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), null); - _usageEventDao.persist(usageEvent); - } - - txn.commit(); - - // gather external network usage stats for this lb rule - NetworkVO network = _networkDao.findById(lb.getNetworkId()); - if (network != null) { - if (_networkMgr.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) { - _externalLBUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId); - } - } - - if (apply) { - try { - if (!applyLoadBalancerConfig(loadBalancerId)) { - s_logger.warn("Unable to apply the load balancer config"); - return false; - } - } catch (ResourceUnavailableException e) { - if (rollBack && isRollBackAllowedForProvider(lb)) { - if (backupMaps != null) { - for (LoadBalancerVMMapVO map : backupMaps) { - _lb2VmMapDao.persist(map); - s_logger.debug("LB Rollback rule id: " + loadBalancerId + ", vmId " + map.getInstanceId()); - } - } - lb.setState(backupState); - _lbDao.persist(lb); - s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while deleting LB rule."); - } else { - s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); - } - return false; - } - } - - FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(lb.getId()); - if (relatedRule != null) { - s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); - success = false; - } else { - _firewallMgr.removeRule(lb); - } - - _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); - - if (success) { - s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); - } - - return success; - } - - @Override - @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer") - public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException { - Account lbOwner = _accountMgr.getAccount(lb.getEntityOwnerId()); - - int defPortStart = lb.getDefaultPortStart(); - int defPortEnd = lb.getDefaultPortEnd(); - - if (!NetUtils.isValidPort(defPortEnd)) { - throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortEnd, null); - } - if (defPortStart > defPortEnd) { - throw new InvalidParameterValueException("private port range is invalid: " + defPortStart + "-" + defPortEnd, null); - } - if ((lb.getAlgorithm() == null) || !NetUtils.isValidAlgorithm(lb.getAlgorithm())) { - throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm(), null); - } - - Long ipAddrId = lb.getSourceIpAddressId(); - IPAddressVO ipVO = null; - if (ipAddrId != null) { - ipVO = _ipAddressDao.findById(ipAddrId); - } - - Network network = _networkMgr.getNetwork(lb.getNetworkId()); - - LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId()); - boolean performedIpAssoc = false; - if (result == null) { - IpAddress systemIp = null; - NetworkOffering off = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); - if (off.getElasticLb() && ipVO == null && network.getVpcId() == null) { - systemIp = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false); - lb.setSourceIpAddressId(systemIp.getId()); - ipVO = _ipAddressDao.findById(systemIp.getId()); - } - - // Validate ip address - if (ipVO == null) { - throw new InvalidParameterValueException("Unable to create load balance rule; can't find/allocate source IP", null); - } else if (ipVO.isOneToOneNat()) { - throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipVO.getAddress()); - } - - try { - if (ipVO.getAssociatedWithNetworkId() == null) { - boolean assignToVpcNtwk = network.getVpcId() != null - && ipVO.getVpcId() != null && ipVO.getVpcId().longValue() == network.getVpcId(); - if (assignToVpcNtwk) { - //set networkId just for verification purposes - _networkMgr.checkIpForService(ipVO, Service.Lb, lb.getNetworkId()); - - s_logger.debug("The ip is not associated with the VPC network id="+ lb.getNetworkId() + " so assigning"); - ipVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId(), false); - performedIpAssoc = true; - } - } else { - _networkMgr.checkIpForService(ipVO, Service.Lb, null); - } - - if (ipVO.getAssociatedWithNetworkId() == null) { - throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + network); - } - - if (lb.getSourceIpAddressId() == null) { - throw new CloudRuntimeException("No ip address is defined to assign the LB to"); - } - result = createLoadBalancer(lb, openFirewall); - } catch (Exception ex) { - s_logger.warn("Failed to create load balancer due to ", ex); - if (ex instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) ex; - } - } finally { - if (result == null && systemIp != null) { - s_logger.debug("Releasing system IP address " + systemIp + " as corresponding lb rule failed to create"); - _networkMgr.handleSystemIpRelease(systemIp); - } - // release ip address if ipassoc was perfored - if (performedIpAssoc) { - ipVO = _ipAddressDao.findById(ipVO.getId()); - _networkMgr.unassignIPFromVpcNetwork(ipVO.getId(), lb.getNetworkId()); - - } - } - } - - if (result == null) { - throw new CloudRuntimeException("Failed to create load balancer rule: " + lb.getName()); - } - - return result; - } - - @Override - @DB - public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException { - UserContext caller = UserContext.current(); - int srcPortStart = lb.getSourcePortStart(); - int defPortStart = lb.getDefaultPortStart(); - int srcPortEnd = lb.getSourcePortEnd(); - long sourceIpId = lb.getSourceIpAddressId(); - - 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", null); - 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", null); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); - throw ex; - } - - _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), - Purpose.LoadBalancing, FirewallRuleType.User); - - Long networkId = ipAddr.getAssociatedWithNetworkId(); - if (networkId == null) { - List idList = new ArrayList(); - idList.add(new IdentityProxy(ipAddr, sourceIpId, "sourceIpid")); - throw new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network", idList); - - } - NetworkVO network = _networkDao.findById(networkId); - - _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr); - - // verify that lb service is supported by the network - if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - List idList = new ArrayList(); - idList.add(new IdentityProxy(network, networkId, "networkId")); - throw new InvalidParameterValueException("LB service is not supported in network with specified id", idList); - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - LoadBalancerVO newRule = new LoadBalancerVO(lb.getXid(), lb.getName(), lb.getDescription(), lb.getSourceIpAddressId(), lb.getSourcePortEnd(), lb.getDefaultPortStart(), - lb.getAlgorithm(), network.getId(), ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); - - newRule = _lbDao.persist(newRule); - - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), - lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); - } - - boolean success = true; - - try { - _firewallMgr.detectRulesConflict(newRule); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + srcPortStart + ", private port " + defPortStart + " is added successfully."); - UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null); - _usageEventDao.persist(usageEvent); - txn.commit(); - - return newRule; - } catch (Exception e) { - success = false; - if (e instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) e; - } - throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e); - } finally { - if (!success && newRule != null) { - - txn.start(); - _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - removeLBRule(newRule); - - txn.commit(); - } - } - } - - @Override - public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException { - LoadBalancerVO lb = _lbDao.findById(lbRuleId); - List lbs; - 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)); - } else { - // get all rules in transition state - lbs = _lbDao.listInTransitionStateByNetworkId(lb.getNetworkId()); - } - return applyLoadBalancerRules(lbs, true); - } - - @Override - public boolean applyLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException { - List lbs = _lbDao.listByNetworkId(networkId); - if (lbs != null) { - return applyLoadBalancerRules(lbs, true); - } else { - s_logger.info("Network id=" + networkId + " doesn't have load balancer rules, nothing to apply"); - return true; - } - } - - @DB - protected boolean applyLoadBalancerRules(List lbs, boolean updateRulesInDB) throws ResourceUnavailableException { - Transaction txn = Transaction.currentTxn(); - List rules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = getExistingDestinations(lb.getId()); - List policyList = getStickinessPolicies(lb.getId()); - - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); - rules.add(loadBalancing); - } - - if (!_networkMgr.applyRules(rules, false)) { - s_logger.debug("LB rules are not completely applied"); - return false; - } - - if (updateRulesInDB) { - for (LoadBalancerVO lb : lbs) { - boolean checkForReleaseElasticIp = false; - txn.start(); - if (lb.getState() == FirewallRule.State.Revoke) { - removeLBRule(lb); - s_logger.debug("LB " + lb.getId() + " is successfully removed"); - checkForReleaseElasticIp = true; - } else if (lb.getState() == FirewallRule.State.Add) { - lb.setState(FirewallRule.State.Active); - s_logger.debug("LB rule " + lb.getId() + " state is set to Active"); - _lbDao.persist(lb); - } - - // remove LB-Vm mappings that were state to revoke - List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true); - List instanceIds = new ArrayList(); - - for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { - instanceIds.add(lbVmMap.getInstanceId()); - } - - if (!instanceIds.isEmpty()) { - _lb2VmMapDao.remove(lb.getId(), instanceIds, null); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vms " + instanceIds); - } - - if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) { - lb.setState(FirewallRule.State.Add); - _lbDao.persist(lb); - s_logger.debug("LB rule " + lb.getId() + " state is set to Add as there are no more active LB-VM mappings"); - } - - // remove LB-Stickiness policy mapping that were state to revoke - List stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lb.getId(), true); - if (!stickinesspolicies.isEmpty()) { - _lb2stickinesspoliciesDao.remove(lb.getId(), true); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies"); - } - - txn.commit(); - - if (checkForReleaseElasticIp) { - boolean success = true; - long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId()); - if (count == 0) { - try { - success = handleSystemLBIpRelease(lb); - } catch (Exception ex) { - s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion due to exception ", ex); - success = false; - } finally { - if (!success) { - s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion"); - } - } - } - } - } - } - - return true; - } - - protected boolean handleSystemLBIpRelease(LoadBalancerVO lb) { - IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId()); - boolean success = true; - if (ip.getSystem()) { - s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule"); - if (!_networkMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { - s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); - success = false; - } else { - s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); - } - } - - return success; - } - - @Override - public boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId) { - List rules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.LoadBalancing); - if (rules != null) - s_logger.debug("Found " + rules.size() + " lb rules to cleanup"); - for (FirewallRule rule : rules) { - boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false); - if (result == false) { - s_logger.warn("Unable to remove load balancer rule " + rule.getId()); - return false; - } - } - return true; - } - - @Override - public boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId) { - List rules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing); - if (rules != null) - s_logger.debug("Found " + rules.size() + " lb rules to cleanup"); - for (FirewallRule rule : rules) { - boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false); - if (result == false) { - s_logger.warn("Unable to remove load balancer rule " + rule.getId()); - return false; - } - } - return true; - } - - @Override - public List getStickinessPolicies(long lbId) { - List stickinessPolicies = new ArrayList(); - List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lbId); - - for (LBStickinessPolicyVO sDbPolicy : sDbpolicies) { - LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), sDbPolicy.isRevoke()); - stickinessPolicies.add(sPolicy); - } - return stickinessPolicies; - } - - @Override - public List getExistingDestinations(long lbId) { - List dstList = new ArrayList(); - List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId); - LoadBalancerVO lb = _lbDao.findById(lbId); - - String dstIp = null; - for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { - UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); - Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId()); - dstIp = nic.getIp4Address(); - LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke()); - dstList.add(lbDst); - } - return dstList; - } - - @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; - } - - @Override - @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_UPDATE, eventDescription = "updating load balancer", async = true) - public LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd) { - Account caller = UserContext.current().getCaller(); - Long lbRuleId = cmd.getId(); - String name = cmd.getLoadBalancerName(); - String description = cmd.getDescription(); - 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", null); - } - - // check permissions - _accountMgr.checkAccess(caller, null, true, lb); - - if (name != null) { - lb.setName(name); - } - - if (description != null) { - lb.setDescription(description); - } - - if (algorithm != null) { - lb.setAlgorithm(algorithm); - } - - boolean success = _lbDao.update(lbRuleId, lb); - - // If algorithm is changed, have to reapply the lb config - if (algorithm != null) { - try { - lb.setState(FirewallRule.State.Add); - _lbDao.persist(lb); - 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. - */ - if (lbBackup.getName() != null) { - lb.setName(lbBackup.getName()); - } - if (lbBackup.getDescription() != null) { - lb.setDescription(lbBackup.getDescription()); - } - if (lbBackup.getAlgorithm() != null){ - 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); - success = false; - } - } - - if (!success) { - throw new CloudRuntimeException("Failed to update load balancer rule: " + lbRuleId); - } - - return lb; - } - - @Override - public List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) throws PermissionDeniedException { - Account caller = UserContext.current().getCaller(); - Long loadBalancerId = cmd.getId(); - Boolean applied = cmd.isApplied(); - - if (applied == null) { - applied = Boolean.TRUE; - } - - LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); - if (loadBalancer == null) { - return null; - } - - _accountMgr.checkAccess(caller, null, true, loadBalancer); - - List loadBalancerInstances = new ArrayList(); - List vmLoadBalancerMappings = null; - - vmLoadBalancerMappings = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); - - List appliedInstanceIdList = new ArrayList(); - if ((vmLoadBalancerMappings != null) && !vmLoadBalancerMappings.isEmpty()) { - for (LoadBalancerVMMapVO vmLoadBalancerMapping : vmLoadBalancerMappings) { - appliedInstanceIdList.add(vmLoadBalancerMapping.getInstanceId()); - } - } - - IPAddressVO addr = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()); - List userVms = _vmDao.listVirtualNetworkInstancesByAcctAndZone(loadBalancer.getAccountId(), addr.getDataCenterId(), loadBalancer.getNetworkId()); - - for (UserVmVO userVm : userVms) { - // if the VM is destroyed, being expunged, in an error state, or in an unknown state, skip it - switch (userVm.getState()) { - case Destroyed: - case Expunging: - case Error: - case Unknown: - continue; - } - - boolean isApplied = appliedInstanceIdList.contains(userVm.getId()); - if ((isApplied && applied) || (!isApplied && !applied)) { - loadBalancerInstances.add(userVm); - } - } - - return loadBalancerInstances; - } - - @Override - public List getStickinessMethods(long networkid) - { - String capability = getLBStickinessCapability(networkid); - if (capability == null) - return null; - Gson gson = new Gson(); - java.lang.reflect.Type listType = new TypeToken>() { - }.getType(); - List result = gson.fromJson(capability, listType); - return result; - } - - @Override - public List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException { - Account caller = UserContext.current().getCaller(); - Long loadBalancerId = cmd.getLbRuleId(); - LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); - if (loadBalancer == null) { - return null; - } - - _accountMgr.checkAccess(caller, null, true, loadBalancer); - - List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId()); - - return sDbpolicies; - } - - @Override - public List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) { - Long ipId = cmd.getPublicIpId(); - Long zoneId = cmd.getZoneId(); - Long id = cmd.getId(); - String name = cmd.getLoadBalancerRuleName(); - String keyword = cmd.getKeyword(); - Long instanceId = cmd.getVirtualMachineId(); - Map tags = cmd.getTags(); - - Account caller = UserContext.current().getCaller(); - List permittedAccounts = new ArrayList(); - - Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); - Long domainId = domainIdRecursiveListProject.first(); - Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - - Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchBuilder sb = _lbDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ); - - if (instanceId != null) { - SearchBuilder lbVMSearch = _lb2VmMapDao.createSearchBuilder(); - lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - sb.join("lbVMSearch", lbVMSearch, sb.entity().getId(), lbVMSearch.entity().getLoadBalancerId(), JoinBuilder.JoinType.INNER); - } - - if (zoneId != null) { - SearchBuilder ipSearch = _ipAddressDao.createSearchBuilder(); - ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER); - } - - if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); - for (int count=0; count < tags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); - } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); - } - - SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - if (keyword != null) { - SearchCriteria ssc = _lbDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (name != null) { - sc.setParameters("name", "%" + name + "%"); - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (ipId != null) { - sc.setParameters("sourceIpAddress", ipId); - } - - if (instanceId != null) { - sc.setJoinParameters("lbVMSearch", "instanceId", instanceId); - } - - if (zoneId != null) { - sc.setJoinParameters("ipSearch", "zoneId", zoneId); - } - - - if (tags != null && !tags.isEmpty()) { - int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); - for (String key : tags.keySet()) { - sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); - sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); - count++; - } - } - - return _lbDao.search(sc, searchFilter); - } - - @Override - public List listByNetworkId(long networkId) { - List lbs = _lbDao.listByNetworkId(networkId); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = getExistingDestinations(lb.getId()); - List policyList = this.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); - lbRules.add(loadBalancing); - } - return lbRules; - } - - @Override - public LoadBalancerVO findById(long lbId) { - return _lbDao.findById(lbId); - } - - protected void removeLBRule(LoadBalancerVO rule) { - - //remove the rule - _lbDao.remove(rule.getId()); - - //if the rule is the last one for the ip address assigned to VPC, unassign it from the network - IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); - _networkMgr.unassignIPFromVpcNetwork(ip.getId(), rule.getNetworkId()); - - } -} +// 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.lb; + +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Formatter; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiServer; +import com.cloud.api.commands.CreateLBStickinessPolicyCmd; +import com.cloud.api.commands.CreateLoadBalancerRuleCmd; +import com.cloud.api.commands.ListLBStickinessPoliciesCmd; +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.ConfigurationManager; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.domain.dao.DomainDao; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventVO; +import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.ExternalLoadBalancerUsageManager; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.LBStickinessPolicyVO; +import com.cloud.network.LoadBalancerVMMapVO; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +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.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; +import com.cloud.network.dao.LBStickinessPolicyDao; +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; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.FirewallRuleType; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.LbStickinessMethod; +import com.cloud.network.rules.LbStickinessMethod.LbStickinessMethodParam; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.RulesManager; +import com.cloud.network.rules.StickinessPolicy; +import com.cloud.offering.NetworkOffering; +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.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.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.Nic; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.UserVmDao; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +@Local(value = { LoadBalancingRulesManager.class, LoadBalancingRulesService.class }) +public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, LoadBalancingRulesService, Manager { + private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class); + + String _name; + + @Inject + NetworkManager _networkMgr; + @Inject + RulesManager _rulesMgr; + @Inject + AccountManager _accountMgr; + @Inject + IPAddressDao _ipAddressDao; + @Inject + LoadBalancerDao _lbDao; + @Inject + VlanDao _vlanDao; + @Inject + EventDao _eventDao; + @Inject + LoadBalancerVMMapDao _lb2VmMapDao; + @Inject + LBStickinessPolicyDao _lb2stickinesspoliciesDao; + @Inject + UserVmDao _vmDao; + @Inject + AccountDao _accountDao; + @Inject + DomainDao _domainDao; + @Inject + NicDao _nicDao; + @Inject + UsageEventDao _usageEventDao; + @Inject + FirewallRulesCidrsDao _firewallCidrsDao; + @Inject + FirewallManager _firewallMgr; + @Inject + ElasticLoadBalancerManager _elbMgr; + @Inject + NetworkDao _networkDao; + @Inject + FirewallRulesDao _firewallDao; + @Inject + DomainService _domainMgr; + @Inject + ConfigurationManager _configMgr; + @Inject + TemplateManager _templateMgr; + @Inject + ExternalLoadBalancerUsageManager _externalLBUsageMgr; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + ResourceTagDao _resourceTagDao; + @Inject + CounterDao _counterDao; + @Inject + ConditionDao _conditionDao; + @Inject + AutoScaleVmProfileDao _autoScaleVmProfileDao; + @Inject + AutoScalePolicyDao _autoScalePolicyDao; + @Inject + AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao; + @Inject + AutoScaleVmGroupDao _autoScaleVmGroupDao; + @Inject + AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao; + @Inject + DataCenterDao _dcDao = null; + @Inject + UserDao _userDao; + + // 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()) { + ServiceResponse serviceResponse = new ServiceResponse(); + serviceResponse.setName(service.getName()); + if ("Lb".equalsIgnoreCase(service.getName())) { + Map serviceCapabilities = serviceCapabilitiesMap + .get(service); + if (serviceCapabilities != null) { + for (Capability capability : serviceCapabilities + .keySet()) { + if (capabilityName.equals(capability.getName())) { + return serviceCapabilities.get(capability); + } + } + } + } + } + } + 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)); + } + ApiServer apiserver = ApiServer.getInstance(); + String apiIpAddress = apiserver.getServerIpAddress(); + String apiPort = apiserver.getServerPort(); + StringBuilder sb = new StringBuilder(); + + Formatter formatter = new Formatter(sb, java.util.Locale.US); + formatter.format("https://%s:%s/client/api?", apiIpAddress, apiPort); + String csurl = sb.toString(); + AutoScaleVmProfile autoScaleVmProfile = _autoScaleVmProfileDao.findById(vmGroup.getProfileId()); + Long autoscaleUserId = autoScaleVmProfile.getAutoScaleUserId(); + User user = _userDao.findById(autoscaleUserId); + String apiKey = user.getApiKey(); + String secretKey = user.getSecretKey(); + LbAutoScaleVmProfile lbAutoScaleVmProfile = new LbAutoScaleVmProfile(autoScaleVmProfile, csurl, apiKey, secretKey); + return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, lbAutoScaleVmProfile); + } + + private boolean applyAutoScaleConfig(LoadBalancerVO lb, LoadBalancingRule rule, boolean updateRulesInDB) 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 are not completely applied"); + return false; + } + + if (updateRulesInDB) { + } + + return true; + } + + @Override + @DB + public boolean configureLbAutoScaleVmGroup(long vmGroupid, boolean vmGroupCreation) { + AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); + boolean success = true; + + LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId()); + + List vmLoadBalancerMappings = _lb2VmMapDao.listByLoadBalancerId(loadBalancer.getId()); + + boolean loadBalancerCreation = false; + + if (vmLoadBalancerMappings.size() == 0 && vmGroupCreation) { // No manual binding exists, a loadbalancer will be + // created eventually, setting to lb to Add state + loadBalancerCreation = true; + } + + FirewallRule.State backupState = loadBalancer.getState(); + + if (loadBalancerCreation) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + txn.commit(); + } + + // LBTODO + try { + LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup); + LoadBalancingRule rule = new LoadBalancingRule(loadBalancer, null, null); + rule.setAutoScaleVmGroup(lbAutoScaleVmGroup); + success = applyAutoScaleConfig(loadBalancer, rule, true); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to configure AutoScaleVmGroup to the lb rule: " + loadBalancer.getId() + " because resource is unavaliable:", e); + if (isRollBackAllowedForProvider(loadBalancer)) { + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating AutoscaleVmGroup"); + } + success = false; + } + + return success; + } + + private boolean genericValidator(CreateLBStickinessPolicyCmd cmd) throws InvalidParameterValueException { + LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); + /* Validation : check for valid Method name and params */ + List stickinessMethodList = getStickinessMethods(loadBalancer + .getNetworkId()); + boolean methodMatch = false; + + if (stickinessMethodList == null) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed: No Stickiness method available for LB rule with specified id", idList); + } + for (LbStickinessMethod method : stickinessMethodList) { + if (method.getMethodName().equalsIgnoreCase(cmd.getStickinessMethodName())) { + methodMatch = true; + Map apiParamList = cmd.getparamList(); + List methodParamList = method.getParamList(); + Map tempParamList = new HashMap(); + + /* + * validation-1: check for any extra params that are not + * required by the policymethod(capability), FIXME: make the + * below loop simple without using raw data type + */ + if (apiParamList != null) { + Collection userGroupCollection = apiParamList.values(); + Iterator iter = userGroupCollection.iterator(); + while (iter.hasNext()) { + HashMap paramKVpair = (HashMap) iter.next(); + String paramName = paramKVpair.get("name"); + String paramValue = paramKVpair.get("value"); + + tempParamList.put(paramName, paramValue); + Boolean found = false; + for (LbStickinessMethodParam param : methodParamList) { + if (param.getParamName().equalsIgnoreCase(paramName)) { + if ((param.getIsflag() == false) && (paramValue == null)) { + throw new InvalidParameterValueException("Failed : Value expected for the Param :" + param.getParamName(), null); + } + found = true; + break; + } + } + if (!found) { + throw new InvalidParameterValueException("Failed : Stickiness policy does not support param name :" + paramName, null); + } + } + } + + /* validation-2: check for mandatory params */ + for (LbStickinessMethodParam param : methodParamList) { + if (param.getRequired()) { + if (tempParamList.get(param.getParamName()) == null) { + throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + param.getParamName(), null); + } + } + } + /* Successfully completed the Validation */ + break; + } + } + if (methodMatch == false) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule whose id is specified", idList); + } + + /* Validation : check for the multiple policies to the rule id */ + List stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false); + if (stickinessPolicies.size() > 0) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Policy already attached", idList); + } + return true; + } + + @SuppressWarnings("rawtypes") + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "create lb stickinesspolicy to load balancer", create = true) + public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException { + UserContext caller = UserContext.current(); + + /* Validation : check corresponding load balancer rule exist */ + LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); + if (loadBalancer == null) { + throw new InvalidParameterValueException("Failed: LB rule provided not present", null); + } + + _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); + if (loadBalancer.getState() == FirewallRule.State.Revoke) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed: LB rule with specified id is in deleting state: ", idList); + } + + /* Generic validations */ + if (!genericValidator(cmd)) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation of rule with specified id failed", idList); + } + + /* Specific validations using network element validator for specific validations */ + LBStickinessPolicyVO lbpolicy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); + List policyList = new ArrayList(); + policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams())); + LoadBalancingRule lbRule = new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), policyList); + if (!_networkMgr.validateRule(lbRule)) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("firewall_rules", cmd.getLbRuleId(), "ruleId")); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation of rule with specified id failed ", idList); + } + + /* Finally Insert into DB */ + LBStickinessPolicyVO policy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); + policy = _lb2stickinesspoliciesDao.persist(policy); + + return policy; + } + + @Override + @DB + @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()); + } + FirewallRule.State backupState = loadBalancer.getState(); + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + try { + applyLoadBalancerConfig(cmd.getLbRuleId()); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to apply Stickiness policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e); + if (isRollBackAllowedForProvider(loadBalancer)) { + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating sticky policy" ); + } + deleteLBStickinessPolicy(cmd.getEntityId(), false); + success = false; + } + + return success; + } + + @Override + @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); + + if (stickinessPolicy == null) { + throw new InvalidParameterException("Invalid Stickiness policy id value: " + stickinessPolicyId); + } + LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(stickinessPolicy.getLoadBalancerId())); + if (loadBalancer == null) { + throw new InvalidParameterException("Invalid Load balancer : " + stickinessPolicy.getLoadBalancerId() + " for Stickiness policy id: " + stickinessPolicyId); + } + long loadBalancerId = loadBalancer.getId(); + FirewallRule.State backupState = loadBalancer.getState(); + _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); + + if (apply) { + if (loadBalancer.getState() == FirewallRule.State.Active) { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + } + + boolean backupStickyState = stickinessPolicy.isRevoke(); + 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); + throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId); + } + } catch (ResourceUnavailableException e) { + if (isRollBackAllowedForProvider(loadBalancer)) { + stickinessPolicy.setRevoke(backupStickyState); + _lb2stickinesspoliciesDao.persist(stickinessPolicy); + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while deleting sticky policy: " + stickinessPolicyId); + } + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + success = false; + } + }else{ + _lb2stickinesspoliciesDao.remove(stickinessPolicy.getLoadBalancerId()); + } + + return success; + } + + private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) { + Network network = _networkDao.findById(loadBalancer.getNetworkId()); + Provider provider = Network.Provider.Netscaler; + return _ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true) + public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + + LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); + if (loadBalancer == null) { + throw new InvalidParameterValueException("Failed to assign to load balancer; the load balancer was not found.", null); + } + + + List mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false); + Set mappedInstanceIds = new HashSet(); + for (LoadBalancerVMMapVO mappedInstance : mappedInstances) { + mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId())); + } + + List vmsToAdd = new ArrayList(); + + for (Long instanceId : instanceIds) { + if (mappedInstanceIds.contains(instanceId)) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("user_vm", instanceId, "vmId")); + throw new InvalidParameterValueException("VM with specified id is already mapped to load balancer", idList); + } + + UserVm vm = _vmDao.findById(instanceId); + if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { + throw new InvalidParameterValueException("Couldn't locate vm instance by id", null); + } + + _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller); + + if (vm.getAccountId() != loadBalancer.getAccountId()) { + throw new PermissionDeniedException("Cannot add virtual machines that do not belong to the same owner."); + } + + // Let's check to make sure the vm has a nic in the same network as the load balancing rule. + List nics = _networkMgr.getNics(vm.getId()); + Nic nicInSameNetwork = null; + for (Nic nic : nics) { + if (nic.getNetworkId() == loadBalancer.getNetworkId()) { + nicInSameNetwork = nic; + break; + } + } + + if (nicInSameNetwork == null) { + List idList = new ArrayList(); + idList.add(new IdentityProxy(vm, instanceId, "vmId")); + throw new InvalidParameterValueException("VM with specified id cannot be added because it doesn't belong in the same network.", idList); + + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Adding " + vm + " to the load balancer pool"); + } + vmsToAdd.add(vm); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (UserVm vm : vmsToAdd) { + LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); + 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 { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + applyLoadBalancerConfig(loadBalancerId); + success = true; + } catch (ResourceUnavailableException e) { + if (isRollBackAllowedForProvider(loadBalancer)) { + List vmInstanceIds = new ArrayList(); + txn = Transaction.currentTxn(); + txn.start(); + for (UserVm vm : vmsToAdd) { + vmInstanceIds.add(vm.getId()); + } + txn.commit(); + if (!vmInstanceIds.isEmpty()) { + _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while attaching VM: " + vmInstanceIds); + } + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + } + 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. + throw ex; + } + + return success; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true) + public boolean removeFromLoadBalancer(long loadBalancerId, List instanceIds) { + return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true); + } + + private boolean removeFromLoadBalancerInternal(long loadBalancerId, List instanceIds, boolean rollBack) { + UserContext caller = UserContext.current(); + + LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(loadBalancerId)); + if (loadBalancer == null) { + throw new InvalidParameterException("Invalid load balancer value: " + loadBalancerId); + } + + _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); + + boolean success = false; + FirewallRule.State backupState = loadBalancer.getState(); + try { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + + for (long instanceId : instanceIds) { + LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); + map.setRevoke(true); + _lb2VmMapDao.persist(map); + 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"); + 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"); + } + 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"); + throw ex; + } + return success; + } + + @Override + public boolean removeVmFromLoadBalancers(long instanceId) { + boolean success = true; + List maps = _lb2VmMapDao.listByInstanceId(instanceId); + if (maps == null || maps.isEmpty()) { + return true; + } + + Map> lbsToReconfigure = new HashMap>(); + + // first set all existing lb mappings with Revoke state + for (LoadBalancerVMMapVO map : maps) { + long lbId = map.getLoadBalancerId(); + List instances = lbsToReconfigure.get(lbId); + if (instances == null) { + instances = new ArrayList(); + } + instances.add(map.getInstanceId()); + lbsToReconfigure.put(lbId, instances); + + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + instanceId); + } + + // Reapply all lbs that had the vm assigned + if (lbsToReconfigure != null) { + for (Map.Entry> lb : lbsToReconfigure.entrySet()) { + if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false)) { + success = false; + } + } + } + return success; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_DELETE, eventDescription = "deleting load balancer", async = true) + public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply) { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + + LoadBalancerVO rule = _lbDao.findById(loadBalancerId); + if (rule == null) { + throw new InvalidParameterValueException("Unable to find load balancer rule by id", null); + } + + _accountMgr.checkAccess(caller, null, true, rule); + + boolean result = deleteLoadBalancerRule(loadBalancerId, apply, caller, ctx.getCallerUserId(), true); + if (!result) { + throw new CloudRuntimeException("Unable to remove load balancer rule " + loadBalancerId); + } + return result; + } + + @DB + public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) { + LoadBalancerVO lb = _lbDao.findById(loadBalancerId); + Transaction txn = Transaction.currentTxn(); + boolean generateUsageEvent = false; + boolean success = true; + FirewallRule.State backupState = lb.getState(); + + txn.start(); + if (lb.getState() == FirewallRule.State.Staged) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb); + } + generateUsageEvent = true; + } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) { + lb.setState(FirewallRule.State.Revoke); + _lbDao.persist(lb); + generateUsageEvent = true; + } + List backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + if (maps != null) { + for (LoadBalancerVMMapVO map : maps) { + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + map.getInstanceId()); + } + } + + if (generateUsageEvent) { + // Generate usage event right after all rules were marked for revoke + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), null); + _usageEventDao.persist(usageEvent); + } + + txn.commit(); + + // gather external network usage stats for this lb rule + NetworkVO network = _networkDao.findById(lb.getNetworkId()); + if (network != null) { + if (_networkMgr.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) { + _externalLBUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId); + } + } + + if (apply) { + try { + if (!applyLoadBalancerConfig(loadBalancerId)) { + s_logger.warn("Unable to apply the load balancer config"); + return false; + } + } catch (ResourceUnavailableException e) { + if (rollBack && isRollBackAllowedForProvider(lb)) { + if (backupMaps != null) { + for (LoadBalancerVMMapVO map : backupMaps) { + _lb2VmMapDao.persist(map); + s_logger.debug("LB Rollback rule id: " + loadBalancerId + ", vmId " + map.getInstanceId()); + } + } + lb.setState(backupState); + _lbDao.persist(lb); + s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while deleting LB rule."); + } else { + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + } + return false; + } + } + + FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(lb.getId()); + if (relatedRule != null) { + s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); + success = false; + } else { + _firewallMgr.removeRule(lb); + } + + _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); + + if (success) { + s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); + } + + return success; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer") + public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException { + Account lbOwner = _accountMgr.getAccount(lb.getEntityOwnerId()); + + int defPortStart = lb.getDefaultPortStart(); + int defPortEnd = lb.getDefaultPortEnd(); + + if (!NetUtils.isValidPort(defPortEnd)) { + throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortEnd, null); + } + if (defPortStart > defPortEnd) { + throw new InvalidParameterValueException("private port range is invalid: " + defPortStart + "-" + defPortEnd, null); + } + if ((lb.getAlgorithm() == null) || !NetUtils.isValidAlgorithm(lb.getAlgorithm())) { + throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm(), null); + } + + Long ipAddrId = lb.getSourceIpAddressId(); + IPAddressVO ipVO = null; + if (ipAddrId != null) { + ipVO = _ipAddressDao.findById(ipAddrId); + } + + Network network = _networkMgr.getNetwork(lb.getNetworkId()); + + LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId()); + boolean performedIpAssoc = false; + if (result == null) { + IpAddress systemIp = null; + NetworkOffering off = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (off.getElasticLb() && ipVO == null && network.getVpcId() == null) { + systemIp = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false); + lb.setSourceIpAddressId(systemIp.getId()); + ipVO = _ipAddressDao.findById(systemIp.getId()); + } + + // Validate ip address + if (ipVO == null) { + throw new InvalidParameterValueException("Unable to create load balance rule; can't find/allocate source IP", null); + } else if (ipVO.isOneToOneNat()) { + throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipVO.getAddress()); + } + + try { + if (ipVO.getAssociatedWithNetworkId() == null) { + boolean assignToVpcNtwk = network.getVpcId() != null + && ipVO.getVpcId() != null && ipVO.getVpcId().longValue() == network.getVpcId(); + if (assignToVpcNtwk) { + //set networkId just for verification purposes + _networkMgr.checkIpForService(ipVO, Service.Lb, lb.getNetworkId()); + + s_logger.debug("The ip is not associated with the VPC network id="+ lb.getNetworkId() + " so assigning"); + ipVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId(), false); + performedIpAssoc = true; + } + } else { + _networkMgr.checkIpForService(ipVO, Service.Lb, null); + } + + if (ipVO.getAssociatedWithNetworkId() == null) { + throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + network); + } + + if (lb.getSourceIpAddressId() == null) { + throw new CloudRuntimeException("No ip address is defined to assign the LB to"); + } + result = createLoadBalancer(lb, openFirewall); + } catch (Exception ex) { + s_logger.warn("Failed to create load balancer due to ", ex); + if (ex instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) ex; + } + } finally { + if (result == null && systemIp != null) { + s_logger.debug("Releasing system IP address " + systemIp + " as corresponding lb rule failed to create"); + _networkMgr.handleSystemIpRelease(systemIp); + } + // release ip address if ipassoc was perfored + if (performedIpAssoc) { + ipVO = _ipAddressDao.findById(ipVO.getId()); + _networkMgr.unassignIPFromVpcNetwork(ipVO.getId(), lb.getNetworkId()); + + } + } + } + + if (result == null) { + throw new CloudRuntimeException("Failed to create load balancer rule: " + lb.getName()); + } + + return result; + } + + @Override + @DB + public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException { + UserContext caller = UserContext.current(); + int srcPortStart = lb.getSourcePortStart(); + int defPortStart = lb.getDefaultPortStart(); + int srcPortEnd = lb.getSourcePortEnd(); + long sourceIpId = lb.getSourceIpAddressId(); + + 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", null); + 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", null); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + throw ex; + } + + _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), + Purpose.LoadBalancing, FirewallRuleType.User); + + Long networkId = ipAddr.getAssociatedWithNetworkId(); + if (networkId == null) { + List idList = new ArrayList(); + idList.add(new IdentityProxy(ipAddr, sourceIpId, "sourceIpid")); + throw new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network", idList); + + } + NetworkVO network = _networkDao.findById(networkId); + + _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr); + + // verify that lb service is supported by the network + if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { + List idList = new ArrayList(); + idList.add(new IdentityProxy(network, networkId, "networkId")); + throw new InvalidParameterValueException("LB service is not supported in network with specified id", idList); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + LoadBalancerVO newRule = new LoadBalancerVO(lb.getXid(), lb.getName(), lb.getDescription(), lb.getSourceIpAddressId(), lb.getSourcePortEnd(), lb.getDefaultPortStart(), + lb.getAlgorithm(), network.getId(), ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); + + newRule = _lbDao.persist(newRule); + + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), + lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); + } + + boolean success = true; + + try { + _firewallMgr.detectRulesConflict(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + srcPortStart + ", private port " + defPortStart + " is added successfully."); + UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null); + _usageEventDao.persist(usageEvent); + txn.commit(); + + return newRule; + } catch (Exception e) { + success = false; + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e); + } finally { + if (!success && newRule != null) { + + txn.start(); + _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); + removeLBRule(newRule); + + txn.commit(); + } + } + } + + @Override + public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException { + LoadBalancerVO lb = _lbDao.findById(lbRuleId); + List lbs; + if (isRollBackAllowedForProvider(lb)) { + // this is for Netscalar type of devices. if their is failure the db entries will be rollbacked. + lbs = Arrays.asList(lb); + } else { + // get all rules in transition state + lbs = _lbDao.listInTransitionStateByNetworkId(lb.getNetworkId()); + } + return applyLoadBalancerRules(lbs, true); + } + + @Override + public boolean applyLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException { + List lbs = _lbDao.listByNetworkId(networkId); + if (lbs != null) { + return applyLoadBalancerRules(lbs, true); + } else { + s_logger.info("Network id=" + networkId + " doesn't have load balancer rules, nothing to apply"); + return true; + } + } + + @DB + protected boolean applyLoadBalancerRules(List lbs, boolean updateRulesInDB) throws ResourceUnavailableException { + Transaction txn = Transaction.currentTxn(); + List rules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = getExistingDestinations(lb.getId()); + List policyList = getStickinessPolicies(lb.getId()); + + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + rules.add(loadBalancing); + } + + if (!_networkMgr.applyRules(rules, false)) { + s_logger.debug("LB rules are not completely applied"); + return false; + } + + if (updateRulesInDB) { + for (LoadBalancerVO lb : lbs) { + boolean checkForReleaseElasticIp = false; + txn.start(); + if (lb.getState() == FirewallRule.State.Revoke) { + removeLBRule(lb); + s_logger.debug("LB " + lb.getId() + " is successfully removed"); + checkForReleaseElasticIp = true; + } else if (lb.getState() == FirewallRule.State.Add) { + lb.setState(FirewallRule.State.Active); + s_logger.debug("LB rule " + lb.getId() + " state is set to Active"); + _lbDao.persist(lb); + } + + // remove LB-Vm mappings that were state to revoke + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true); + List instanceIds = new ArrayList(); + + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + instanceIds.add(lbVmMap.getInstanceId()); + } + + if (!instanceIds.isEmpty()) { + _lb2VmMapDao.remove(lb.getId(), instanceIds, null); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vms " + instanceIds); + } + + if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) { + lb.setState(FirewallRule.State.Add); + _lbDao.persist(lb); + s_logger.debug("LB rule " + lb.getId() + " state is set to Add as there are no more active LB-VM mappings"); + } + + // remove LB-Stickiness policy mapping that were state to revoke + List stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lb.getId(), true); + if (!stickinesspolicies.isEmpty()) { + _lb2stickinesspoliciesDao.remove(lb.getId(), true); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies"); + } + + txn.commit(); + + if (checkForReleaseElasticIp) { + boolean success = true; + long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId()); + if (count == 0) { + try { + success = handleSystemLBIpRelease(lb); + } catch (Exception ex) { + s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion due to exception ", ex); + success = false; + } finally { + if (!success) { + s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion"); + } + } + } + } + } + } + + return true; + } + + protected boolean handleSystemLBIpRelease(LoadBalancerVO lb) { + IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId()); + boolean success = true; + if (ip.getSystem()) { + s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule"); + if (!_networkMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { + s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); + success = false; + } else { + s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); + } + } + + return success; + } + + @Override + public boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId) { + List rules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.LoadBalancing); + if (rules != null) { + s_logger.debug("Found " + rules.size() + " lb rules to cleanup"); + } + for (FirewallRule rule : rules) { + boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false); + if (result == false) { + s_logger.warn("Unable to remove load balancer rule " + rule.getId()); + return false; + } + } + return true; + } + + @Override + public boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId) { + List rules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing); + if (rules != null) { + s_logger.debug("Found " + rules.size() + " lb rules to cleanup"); + } + for (FirewallRule rule : rules) { + boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false); + if (result == false) { + s_logger.warn("Unable to remove load balancer rule " + rule.getId()); + return false; + } + } + return true; + } + + @Override + public List getStickinessPolicies(long lbId) { + List stickinessPolicies = new ArrayList(); + List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lbId); + + for (LBStickinessPolicyVO sDbPolicy : sDbpolicies) { + LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), sDbPolicy.isRevoke()); + stickinessPolicies.add(sPolicy); + } + return stickinessPolicies; + } + + @Override + public List getExistingDestinations(long lbId) { + List dstList = new ArrayList(); + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId); + LoadBalancerVO lb = _lbDao.findById(lbId); + + String dstIp = null; + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); + Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId()); + dstIp = nic.getIp4Address(); + LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke()); + dstList.add(lbDst); + } + return dstList; + } + + public List getExistingPolicyConditions(long policyId) { + List conditionList = new ArrayList(); + return conditionList; + // List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId); + // LoadBalancerVO lb = _lbDao.findById(lbId); + // + // String dstIp = null; + // for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + // UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); + // Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId()); + // dstIp = nic.getIp4Address(); + // LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, + // lbVmMap.isRevoke()); + // dstList.add(lbDst); + // } + // return dstList; + } + + @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; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_UPDATE, eventDescription = "updating load balancer", async = true) + public LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd) { + Account caller = UserContext.current().getCaller(); + Long lbRuleId = cmd.getId(); + String name = cmd.getLoadBalancerName(); + String description = cmd.getDescription(); + 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", null); + } + + // check permissions + _accountMgr.checkAccess(caller, null, true, lb); + + if (name != null) { + lb.setName(name); + } + + if (description != null) { + lb.setDescription(description); + } + + if (algorithm != null) { + lb.setAlgorithm(algorithm); + } + + boolean success = _lbDao.update(lbRuleId, lb); + + // If algorithm is changed, have to reapply the lb config + if (algorithm != null) { + try { + lb.setState(FirewallRule.State.Add); + _lbDao.persist(lb); + 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. + */ + if (lbBackup.getName() != null) { + lb.setName(lbBackup.getName()); + } + if (lbBackup.getDescription() != null) { + lb.setDescription(lbBackup.getDescription()); + } + if (lbBackup.getAlgorithm() != null){ + 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); + success = false; + } + } + + if (!success) { + throw new CloudRuntimeException("Failed to update load balancer rule: " + lbRuleId); + } + + return lb; + } + + @Override + public List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) throws PermissionDeniedException { + Account caller = UserContext.current().getCaller(); + Long loadBalancerId = cmd.getId(); + Boolean applied = cmd.isApplied(); + + if (applied == null) { + applied = Boolean.TRUE; + } + + LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); + if (loadBalancer == null) { + return null; + } + + _accountMgr.checkAccess(caller, null, true, loadBalancer); + + List loadBalancerInstances = new ArrayList(); + List vmLoadBalancerMappings = null; + + vmLoadBalancerMappings = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + + List appliedInstanceIdList = new ArrayList(); + if ((vmLoadBalancerMappings != null) && !vmLoadBalancerMappings.isEmpty()) { + for (LoadBalancerVMMapVO vmLoadBalancerMapping : vmLoadBalancerMappings) { + appliedInstanceIdList.add(vmLoadBalancerMapping.getInstanceId()); + } + } + + IPAddressVO addr = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()); + List userVms = _vmDao.listVirtualNetworkInstancesByAcctAndZone(loadBalancer.getAccountId(), addr.getDataCenterId(), loadBalancer.getNetworkId()); + + for (UserVmVO userVm : userVms) { + // if the VM is destroyed, being expunged, in an error state, or in an unknown state, skip it + switch (userVm.getState()) { + case Destroyed: + case Expunging: + case Error: + case Unknown: + continue; + } + + boolean isApplied = appliedInstanceIdList.contains(userVm.getId()); + if ((isApplied && applied) || (!isApplied && !applied)) { + loadBalancerInstances.add(userVm); + } + } + + 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 = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName()); + if (capability == null) { + return null; + } + Gson gson = new Gson(); + java.lang.reflect.Type listType = new TypeToken>() { + }.getType(); + List result = gson.fromJson(capability, listType); + return result; + } + + @Override + public List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException { + Account caller = UserContext.current().getCaller(); + Long loadBalancerId = cmd.getLbRuleId(); + LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); + if (loadBalancer == null) { + return null; + } + + _accountMgr.checkAccess(caller, null, true, loadBalancer); + + List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId()); + + return sDbpolicies; + } + + @Override + public List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) { + Long ipId = cmd.getPublicIpId(); + Long zoneId = cmd.getZoneId(); + Long id = cmd.getId(); + String name = cmd.getLoadBalancerRuleName(); + String keyword = cmd.getKeyword(); + Long instanceId = cmd.getVirtualMachineId(); + Map tags = cmd.getTags(); + + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _lbDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ); + + if (instanceId != null) { + SearchBuilder lbVMSearch = _lb2VmMapDao.createSearchBuilder(); + lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); + sb.join("lbVMSearch", lbVMSearch, sb.entity().getId(), lbVMSearch.entity().getLoadBalancerId(), JoinBuilder.JoinType.INNER); + } + + if (zoneId != null) { + SearchBuilder ipSearch = _ipAddressDao.createSearchBuilder(); + ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (keyword != null) { + SearchCriteria ssc = _lbDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.setParameters("name", "%" + name + "%"); + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (ipId != null) { + sc.setParameters("sourceIpAddress", ipId); + } + + if (instanceId != null) { + sc.setJoinParameters("lbVMSearch", "instanceId", instanceId); + } + + if (zoneId != null) { + sc.setJoinParameters("ipSearch", "zoneId", zoneId); + } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + + return _lbDao.search(sc, searchFilter); + } + + @Override + public List listByNetworkId(long networkId) { + List lbs = _lbDao.listByNetworkId(networkId); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = getExistingDestinations(lb.getId()); + List policyList = this.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + lbRules.add(loadBalancing); + } + return lbRules; + } + + @Override + public LoadBalancerVO findById(long lbId) { + return _lbDao.findById(lbId); + } + + protected void removeLBRule(LoadBalancerVO rule) { + + //remove the rule + _lbDao.remove(rule.getId()); + + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); + _networkMgr.unassignIPFromVpcNetwork(ip.getId(), rule.getNetworkId()); + + } +} diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 1d82ba4913a..4840cc65b44 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1,3298 +1,3298 @@ -// 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.router; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.AgentManager.OnError; -import com.cloud.agent.Listener; -import com.cloud.agent.api.AgentControlAnswer; -import com.cloud.agent.api.AgentControlCommand; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BumpUpPriorityCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.ModifySshKeysCommand; -import com.cloud.agent.api.NetworkUsageAnswer; -import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.StartupCommand; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.check.CheckSshAnswer; -import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; -import com.cloud.agent.api.to.FirewallRuleTO; -import com.cloud.agent.api.to.IpAddressTO; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.manager.Commands; -import com.cloud.alert.AlertManager; -import com.cloud.api.commands.UpgradeRouterCmd; -import com.cloud.cluster.ManagementServerHostVO; -import com.cloud.cluster.ManagementServerNode; -import com.cloud.cluster.dao.ManagementServerHostDao; -import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ZoneConfig; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.deploy.DataCenterDeployment; -import com.cloud.deploy.DeployDestination; -import com.cloud.deploy.DeploymentPlan; -import com.cloud.deploy.DeploymentPlanner.ExcludeList; -import com.cloud.event.ActionEvent; -import com.cloud.event.EventTypes; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.ConnectionException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapcityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.HostVO; -import com.cloud.host.Status; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; -import com.cloud.network.Network.GuestType; -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.Networks.BroadcastDomainType; -import com.cloud.network.Networks.IsolationType; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PublicIpAddress; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.SshKeysDistriMonitor; -import com.cloud.network.VirtualNetworkApplianceService; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; -import com.cloud.network.VpnUser; -import com.cloud.network.VpnUserVO; -import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesDao; -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.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.RemoteAccessVpnDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; -import com.cloud.network.dao.Site2SiteVpnConnectionDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.dao.VirtualRouterProviderDao; -import com.cloud.network.dao.VpnUserDao; -import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.router.VirtualRouter.RedundantState; -import com.cloud.network.router.VirtualRouter.Role; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.StaticNat; -import com.cloud.network.rules.StaticNatImpl; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.dao.PortForwardingRulesDao; -import com.cloud.offering.ServiceOffering; -import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.resource.ResourceManager; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.GuestOSVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserStatsLogVO; -import com.cloud.user.UserVO; -import com.cloud.user.dao.UserDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.user.dao.UserStatsLogDao; -import com.cloud.uservm.UserVm; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.PasswordGenerator; -import com.cloud.utils.StringUtils; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.component.Inject; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.MacAddress; -import com.cloud.utils.net.NetUtils; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.Nic; -import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.ReservationContextImpl; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineGuru; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineName; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfile.Param; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.UserVmDetailsDao; - -/** - * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack. - */ -@Local(value = { VirtualNetworkApplianceManager.class, VirtualNetworkApplianceService.class }) -public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, - VirtualMachineGuru, Listener { - private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class); - - String _name; - @Inject - DataCenterDao _dcDao = null; - @Inject - VlanDao _vlanDao = null; - @Inject - FirewallRulesDao _rulesDao = null; - @Inject - LoadBalancerDao _loadBalancerDao = null; - @Inject - LoadBalancerVMMapDao _loadBalancerVMMapDao = null; - @Inject - IPAddressDao _ipAddressDao = null; - @Inject - VMTemplateDao _templateDao = null; - @Inject - DomainRouterDao _routerDao = null; - @Inject - UserDao _userDao = null; - @Inject - UserStatisticsDao _userStatsDao = null; - @Inject - HostDao _hostDao = null; - @Inject - ConfigurationDao _configDao; - @Inject - HostPodDao _podDao = null; - @Inject - UserStatsLogDao _userStatsLogDao = null; - @Inject - AgentManager _agentMgr; - @Inject - AlertManager _alertMgr; - @Inject - AccountManager _accountMgr; - @Inject - ConfigurationManager _configMgr; - @Inject - ServiceOfferingDao _serviceOfferingDao = null; - @Inject - UserVmDao _userVmDao; - @Inject - UserStatisticsDao _statsDao = null; - @Inject - NetworkOfferingDao _networkOfferingDao = null; - @Inject - GuestOSDao _guestOSDao = null; - @Inject - NetworkManager _networkMgr; - @Inject - VirtualMachineManager _itMgr; - @Inject - VpnUserDao _vpnUsersDao; - @Inject - RemoteAccessVpnDao _remoteAccessVpnDao; - @Inject - RulesManager _rulesMgr; - @Inject - NetworkDao _networkDao; - @Inject - LoadBalancingRulesManager _lbMgr; - @Inject - PortForwardingRulesDao _pfRulesDao; - @Inject - RemoteAccessVpnDao _vpnDao; - @Inject - NicDao _nicDao; - @Inject - VolumeDao _volumeDao = null; - @Inject - UserVmDetailsDao _vmDetailsDao; - @Inject - ClusterDao _clusterDao; - @Inject - ResourceManager _resourceMgr; - @Inject - PhysicalNetworkServiceProviderDao _physicalProviderDao; - @Inject - VirtualRouterProviderDao _vrProviderDao; - @Inject - ManagementServerHostDao _msHostDao; - @Inject - Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; - @Inject - Site2SiteVpnGatewayDao _s2sVpnGatewayDao; - @Inject - Site2SiteVpnConnectionDao _s2sVpnConnectionDao; - - int _routerRamSize; - int _routerCpuMHz; - int _retry = 2; - String _instance; - String _mgmt_host; - String _mgmt_cidr; - - int _routerStatsInterval = 300; - int _routerCheckInterval = 30; - protected ServiceOfferingVO _offering; - private String _dnsBasicZoneUpdates = "all"; - - private boolean _disable_rp_filter = false; - int _routerExtraPublicNics = 2; - private int _usageAggregationRange = 1440; - private String _usageTimeZone = "GMT"; - private final long mgmtSrvrId = MacAddress.getMacAddress().toLong(); - private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds - - ScheduledExecutorService _executor; - ScheduledExecutorService _checkExecutor; - ScheduledExecutorService _networkStatsUpdateExecutor; - - Account _systemAcct; - - @Override - public boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey) { - ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey); - final Answer answer = _agentMgr.easySend(hostId, cmd); - - if (answer != null) { - return true; - } else { - return false; - } - } - - @Override - public VirtualRouter destroyRouter(final long routerId) throws ResourceUnavailableException, ConcurrentOperationException { - UserContext context = UserContext.current(); - User user = _accountMgr.getActiveUser(context.getCallerUserId()); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Attempting to destroy router " + routerId); - } - - DomainRouterVO router = _routerDao.findById(routerId); - if (router == null) { - return null; - } - - _accountMgr.checkAccess(context.getCaller(), null, true, router); - - boolean result = _itMgr.expunge(router, user, _accountMgr.getAccount(router.getAccountId())); - - if (result) { - return router; - } - return null; - } - - @Override - @DB - public VirtualRouter upgradeRouter(UpgradeRouterCmd cmd) { - Long routerId = cmd.getId(); - Long serviceOfferingId = cmd.getServiceOfferingId(); - Account caller = UserContext.current().getCaller(); - - DomainRouterVO router = _routerDao.findById(routerId); - if (router == null) { - throw new InvalidParameterValueException("Unable to find router with id " + routerId); - } - - _accountMgr.checkAccess(caller, null, true, router); - - if (router.getServiceOfferingId() == serviceOfferingId) { - s_logger.debug("Router: " + routerId + "already has service offering: " + serviceOfferingId); - return _routerDao.findById(routerId); - } - - ServiceOffering newServiceOffering = _configMgr.getServiceOffering(serviceOfferingId); - if (newServiceOffering == null) { - throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId); - } - - // check if it is a system service offering, if yes return with error as it cannot be used for user vms - if (!newServiceOffering.getSystemUse()) { - throw new InvalidParameterValueException("Cannot upgrade router vm to a non system service offering " + serviceOfferingId); - } - - // Check that the router is stopped - if (!router.getState().equals(State.Stopped)) { - s_logger.warn("Unable to upgrade router " + router.toString() + " in state " + router.getState()); - throw new InvalidParameterValueException("Unable to upgrade router " + router.toString() + " in state " + router.getState() - + "; make sure the router is stopped and not in an error state before upgrading."); - } - - ServiceOfferingVO currentServiceOffering = _serviceOfferingDao.findById(router.getServiceOfferingId()); - - // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service - // offering - if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { - throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + - newServiceOffering.getUseLocalStorage() + " is different from " - + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage()); - } - - router.setServiceOfferingId(serviceOfferingId); - if (_routerDao.update(routerId, router)) { - return _routerDao.findById(routerId); - } else { - throw new CloudRuntimeException("Unable to upgrade router " + routerId); - } - - } - - @Override - public boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Unable save password, router doesn't exist in network " + network.getId()); - throw new CloudRuntimeException("Unable to save password to router"); - } - - UserVm userVm = profile.getVirtualMachine(); - String password = (String) profile.getParameter(Param.VmPassword); - String encodedPassword = PasswordGenerator.rot13(password); - DataCenter dc = _dcDao.findById(userVm.getDataCenterIdToDeployIn()); - - boolean result = true; - for (VirtualRouter router : routers) { - boolean sendPassword = true; - if (dc.getNetworkType() == NetworkType.Basic && userVm.getPodIdToDeployIn().longValue() != router.getPodIdToDeployIn().longValue()) { - sendPassword = false; - } - - if (sendPassword) { - Commands cmds = new Commands(OnError.Continue); - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), userVm.getHostName()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand("password", cmd); - - result = result && sendCommandsToRouter(router, cmds); - } - } - return result; - } - - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true) - public VirtualRouter stopRouter(long routerId, boolean forced) throws ResourceUnavailableException, ConcurrentOperationException { - UserContext context = UserContext.current(); - Account account = context.getCaller(); - - // verify parameters - DomainRouterVO router = _routerDao.findById(routerId); - if (router == null) { - throw new InvalidParameterValueException("Unable to find router by id " + routerId + "."); - } - - _accountMgr.checkAccess(account, null, true, router); - - UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); - - VirtualRouter virtualRouter = stop(router, forced, user, account); - if(virtualRouter == null){ - throw new CloudRuntimeException("Failed to stop router with id " + routerId); - } - return virtualRouter; - } - - @DB - public void processStopOrRebootAnswer(final DomainRouterVO router, Answer answer) { - final Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - for (Long guestNtwkId : routerGuestNtwkIds) { - final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), - guestNtwkId, null, router.getId(), router.getType().toString()); - if (userStats != null) { - final long currentBytesRcvd = userStats.getCurrentBytesReceived(); - userStats.setCurrentBytesReceived(0); - userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); - - final long currentBytesSent = userStats.getCurrentBytesSent(); - userStats.setCurrentBytesSent(0); - userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); - _userStatsDao.update(userStats.getId(), userStats); - s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); - } else { - s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn()); - } - } - - txn.commit(); - } catch (final Exception e) { - txn.rollback(); - throw new CloudRuntimeException("Problem updating stats after reboot/stop ", e); - } - } - - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) - public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, - ResourceUnavailableException, InsufficientCapacityException { - Account caller = UserContext.current().getCaller(); - - // verify parameters - DomainRouterVO router = _routerDao.findById(routerId); - if (router == null) { - throw new InvalidParameterValueException("Unable to find domain router with id " + routerId + "."); - } - - _accountMgr.checkAccess(caller, null, true, router); - - // Can reboot domain router only in Running state - if (router == null || router.getState() != State.Running) { - s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); - throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), - DataCenter.class, router.getDataCenterIdToDeployIn()); - } - - UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); - s_logger.debug("Stopping and starting router " + router + " as a part of router reboot"); - - if (stop(router, false, user, caller) != null) { - return startRouter(routerId, reprogramNetwork); - } else { - throw new CloudRuntimeException("Failed to reboot router " + router); - } - } - - @Override - public boolean configure(final String name, final Map params) throws ConfigurationException { - _name = name; - - _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterMonitor")); - _checkExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterStatusMonitor")); - _networkStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NetworkStatsUpdater")); - - final ComponentLocator locator = ComponentLocator.getCurrentLocator(); - - final Map configs = _configDao.getConfiguration("AgentManager", params); - - _mgmt_host = configs.get("host"); - _routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE); - _routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ); - - _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); - - String value = configs.get("start.retry"); - _retry = NumbersUtil.parseInt(value, 2); - - value = configs.get("router.stats.interval"); - _routerStatsInterval = NumbersUtil.parseInt(value, 300); - - value = configs.get("router.check.interval"); - _routerCheckInterval = NumbersUtil.parseInt(value, 30); - - _instance = configs.get("instance.name"); - if (_instance == null) { - _instance = "DEFAULT"; - } - - String rpValue = configs.get("network.disable.rpfilter"); - if (rpValue != null && rpValue.equalsIgnoreCase("true")) { - _disable_rp_filter = true; - } - - _dnsBasicZoneUpdates = String.valueOf(_configDao.getValue(Config.DnsBasicZoneUpdates.key())); - - s_logger.info("Router configurations: " + "ramsize=" + _routerRamSize); - - final UserStatisticsDao statsDao = locator.getDao(UserStatisticsDao.class); - if (statsDao == null) { - throw new ConfigurationException("Unable to get " + UserStatisticsDao.class.getName()); - } - - _agentMgr.registerForHostEvents(new SshKeysDistriMonitor(_agentMgr, _hostDao, _configDao), true, false, false); - _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this); - - boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); - _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, - null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); - _offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); - _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); - - // this can sometimes happen, if DB is manually or programmatically manipulated - if(_offering == null) { - String msg = "Data integrity problem : System Offering For Software router VM has been removed?"; - s_logger.error(msg); - throw new ConfigurationException(msg); - } - - _systemAcct = _accountMgr.getSystemAccount(); - - String aggregationRange = configs.get("usage.stats.job.aggregation.range"); - _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440); - _usageTimeZone = configs.get("usage.aggregation.timezone"); - if(_usageTimeZone == null){ - _usageTimeZone = "GMT"; - } - - _agentMgr.registerForHostEvents(this, true, false, false); - - s_logger.info("DomainRouterManager is configured."); - - return true; - } - - @Override - public String getName() { - return _name; - } - - @Override - public boolean start() { - if (_routerStatsInterval > 0){ - _executor.scheduleAtFixedRate(new NetworkUsageTask(), _routerStatsInterval, _routerStatsInterval, TimeUnit.SECONDS); - }else{ - s_logger.debug("router.stats.interval - " + _routerStatsInterval+ " so not scheduling the router stats thread"); - } - - //Schedule Network stats update task - TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone); - Calendar cal = Calendar.getInstance(usageTimezone); - cal.setTime(new Date()); - long endDate = 0; - int HOURLY_TIME = 60; - final int DAILY_TIME = 60 * 24; - if (_usageAggregationRange == DAILY_TIME) { - cal.roll(Calendar.DAY_OF_YEAR, false); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - cal.roll(Calendar.DAY_OF_YEAR, true); - cal.add(Calendar.MILLISECOND, -1); - endDate = cal.getTime().getTime(); - } else if (_usageAggregationRange == HOURLY_TIME) { - cal.roll(Calendar.HOUR_OF_DAY, false); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - cal.roll(Calendar.HOUR_OF_DAY, true); - cal.add(Calendar.MILLISECOND, -1); - endDate = cal.getTime().getTime(); - } else { - endDate = cal.getTime().getTime(); - } - - _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), - (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); - - if (_routerCheckInterval > 0) { - _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS); - } else { - s_logger.debug("router.check.interval - " + _routerCheckInterval+ " so not scheduling the redundant router checking thread"); - } - - return true; - } - - @Override - public boolean stop() { - return true; - } - - protected VirtualNetworkApplianceManagerImpl() { - } - - @Override - public Long convertToId(final String vmName) { - if (!VirtualMachineName.isValidRouterName(vmName, _instance)) { - return null; - } - - return VirtualMachineName.getRouterId(vmName); - } - - private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, - String serviceOffering, String zoneName, String guestIpAddress, String vmName, - String vmInstanceName, long vmId, String publicKey, long guestNetworkId) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); - - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmd.addVmData("userdata", "user-data", userData); - cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); - cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); - cmd.addVmData("metadata", "local-ipv4", guestIpAddress); - cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vmName)); - if (dcVo.getNetworkType() == NetworkType.Basic) { - cmd.addVmData("metadata", "public-ipv4", guestIpAddress); - cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName)); - } else - { - if (router.getPublicIpAddress() == null) { - cmd.addVmData("metadata", "public-ipv4", guestIpAddress); - } else { - cmd.addVmData("metadata", "public-ipv4", router.getPublicIpAddress()); - } - cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress()); - } - cmd.addVmData("metadata", "instance-id", vmInstanceName); - cmd.addVmData("metadata", "vm-id", String.valueOf(vmId)); - cmd.addVmData("metadata", "public-keys", publicKey); - - String cloudIdentifier = _configDao.getValue("cloud.identifier"); - if (cloudIdentifier == null) { - cloudIdentifier = ""; - } else { - cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}"; - } - cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier); - - return cmd; - } - - protected class NetworkUsageTask implements Runnable { - - public NetworkUsageTask() { - } - - @Override - public void run() { - try{ - final List routers = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Isolated, mgmtSrvrId); - s_logger.debug("Found " + routers.size() + " running routers. "); - - for (DomainRouterVO router : routers) { - String privateIP = router.getPrivateIpAddress(); - - if (privateIP != null) { - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - - for (Long guestNtwkId : routerGuestNtwkIds) { - boolean forVpc = router.getVpcId() != null; - Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); - Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); - NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), - guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), - _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), - _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); - final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), - forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); - UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), - router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); - NetworkUsageAnswer answer = null; - try { - answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); - } catch (Exception e) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); - continue; - } - - if (answer != null) { - if (!answer.getResult()) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); - continue; - } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { - s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); - continue; - } - txn.start(); - UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), - router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - continue; - } - - if(previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) - || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + - "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + - answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); - continue; - } - - if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesReceived() - + " Stored: " + stats.getCurrentBytesReceived()); - } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answer.getBytesReceived()); - if (stats.getCurrentBytesSent() > answer.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesSent() - + " Stored: " + stats.getCurrentBytesSent()); - } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - } - stats.setCurrentBytesSent(answer.getBytesSent()); - _statsDao.update(stats.getId(), stats); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() - + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); - } finally { - txn.close(); - } - } - } - } - } - } catch (Exception e) { - s_logger.warn("Error while collecting network stats", e); - } - } - } - - protected class NetworkStatsUpdateTask implements Runnable { - - public NetworkStatsUpdateTask() { - } - - @Override - public void run() { - GlobalLock scanLock = GlobalLock.getInternLock("network.stats"); - try { - if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { - //Check for ownership - //msHost in UP state with min id should run the job - ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L)); - if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){ - s_logger.debug("Skipping aggregate network stats update"); - scanLock.unlock(); - return; - } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - txn.start(); - //get all stats with delta > 0 - List updatedStats = _statsDao.listUpdatedStats(); - Date updatedTime = new Date(); - for(UserStatisticsVO stat : updatedStats){ - //update agg bytes - stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived()); - stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent()); - _userStatsDao.update(stat.getId(), stat); - //insert into op_user_stats_log - UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat.getCurrentBytesReceived(), - stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime); - _userStatsLogDao.persist(statsLog); - } - s_logger.debug("Successfully updated aggregate network stats"); - txn.commit(); - } catch (Exception e){ - txn.rollback(); - s_logger.debug("Failed to update aggregate network stats", e); - } finally { - scanLock.unlock(); - txn.close(); - } - } - } catch (Exception e){ - s_logger.debug("Exception while trying to acquire network stats lock", e); - } finally { - scanLock.releaseRef(); - } - } - } - - - protected void updateRoutersRedundantState(List routers) { - boolean updated = false; - for (DomainRouterVO router : routers) { - updated = false; - if (!router.getIsRedundantRouter()) { - continue; - } - RedundantState prevState = router.getRedundantState(); - if (router.getState() != State.Running) { - router.setRedundantState(RedundantState.UNKNOWN); - router.setIsPriorityBumpUp(false); - updated = true; - } else { - String privateIP = router.getPrivateIpAddress(); - HostVO host = _hostDao.findById(router.getHostId()); - if (host == null || host.getStatus() != Status.Up) { - router.setRedundantState(RedundantState.UNKNOWN); - updated = true; - } else if (host.getManagementServerId() != ManagementServerNode.getManagementServerId()) { - /* Only cover hosts managed by this management server */ - continue; - } else if (privateIP != null) { - final CheckRouterCommand command = new CheckRouterCommand(); - command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - command.setWait(60); - final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command); - CheckRouterAnswer answer = null; - if (origAnswer instanceof CheckRouterAnswer) { - answer = (CheckRouterAnswer)origAnswer; - } else { - s_logger.warn("Unable to update router " + router.getHostName() + "'s status"); - } - RedundantState state = RedundantState.UNKNOWN; - boolean isBumped = router.getIsPriorityBumpUp(); - if (answer != null && answer.getResult()) { - state = answer.getState(); - isBumped = answer.isBumped(); - } - router.setRedundantState(state); - router.setIsPriorityBumpUp(isBumped); - updated = true; - } - } - if (updated) { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - txn.start(); - _routerDao.update(router.getId(), router); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.warn("Unable to update router status for account: " + router.getAccountId()); - } finally { - txn.close(); - } - } - RedundantState currState = router.getRedundantState(); - if (prevState != currState) { - String title = "Redundant virtual router " + router.getInstanceName() + - " just switch from " + prevState + " to " + currState; - String context = "Redundant virtual router (name: " + router.getHostName() + ", id: " + router.getId() + ") " + - " just switch from " + prevState + " to " + currState; - s_logger.info(context); - if (currState == RedundantState.MASTER) { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, - router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); - } - } - } - } - - //Ensure router status is update to date before execute this function. The function would try best to recover all routers except MASTER - protected void recoverRedundantNetwork(DomainRouterVO masterRouter, DomainRouterVO backupRouter) { - UserContext context = UserContext.current(); - context.setAccountId(1); - if (masterRouter.getState() == State.Running && backupRouter.getState() == State.Running) { - HostVO masterHost = _hostDao.findById(masterRouter.getHostId()); - HostVO backupHost = _hostDao.findById(backupRouter.getHostId()); - if (masterHost.getStatus() == Status.Up && backupHost.getStatus() == Status.Up) { - String title = "Reboot " + backupRouter.getInstanceName() + " to ensure redundant virtual routers work"; - if (s_logger.isDebugEnabled()) { - s_logger.debug(title); - } - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, - backupRouter.getDataCenterIdToDeployIn(), backupRouter.getPodIdToDeployIn(), title, title); - try { - rebootRouter(backupRouter.getId(), false); - } catch (ConcurrentOperationException e) { - s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); - } catch (ResourceUnavailableException e) { - s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); - } catch (InsufficientCapacityException e) { - s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); - } - } - } - } - - private int getRealPriority(DomainRouterVO router) { - int priority = router.getPriority(); - if (router.getIsPriorityBumpUp()) { - priority += DEFAULT_DELTA; - } - return priority; - } - - protected class CheckRouterTask implements Runnable { - - public CheckRouterTask() { - } - - /* - * In order to make fail-over works well at any time, we have to ensure: - * 1. Backup router's priority = Master's priority - DELTA + 1 - * 2. Backup router's priority hasn't been bumped up. - */ - private void checkSanity(List routers) { - Set checkedNetwork = new HashSet(); - for (DomainRouterVO router : routers) { - if (!router.getIsRedundantRouter()) { - continue; - } - - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - - for (Long routerGuestNtwkId : routerGuestNtwkIds) { - if (checkedNetwork.contains(routerGuestNtwkId)) { - continue; - } - checkedNetwork.add(routerGuestNtwkId); - List checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER); - if (checkingRouters.size() != 2) { - continue; - } - DomainRouterVO masterRouter = null; - DomainRouterVO backupRouter = null; - for (DomainRouterVO r : checkingRouters) { - if (r.getRedundantState() == RedundantState.MASTER) { - if (masterRouter == null) { - masterRouter = r; - } else { - //Duplicate master! We give up, until the admin fix duplicate MASTER issue - break; - } - } else if (r.getRedundantState() == RedundantState.BACKUP) { - if (backupRouter == null) { - backupRouter = r; - } else { - break; - } - } - } - if (masterRouter != null && backupRouter != null) { - if (getRealPriority(masterRouter) - DEFAULT_DELTA + 1 != getRealPriority(backupRouter) || backupRouter.getIsPriorityBumpUp()) { - recoverRedundantNetwork(masterRouter, backupRouter); - } - } - } - } - } - - private void checkDuplicateMaster(List routers) { - Map networkRouterMaps = new HashMap(); - for (DomainRouterVO router : routers) { - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - - for (Long routerGuestNtwkId : routerGuestNtwkIds) { - if (router.getRedundantState() == RedundantState.MASTER) { - if (networkRouterMaps.containsKey(routerGuestNtwkId)) { - DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId); - String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName(); - String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " - + dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. "; - - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context); - } else { - networkRouterMaps.put(routerGuestNtwkId, router); - } - } - } - } - } - - @Override - public void run() { - try { - final List routers = _routerDao.listIsolatedByHostId(null); - s_logger.debug("Found " + routers.size() + " routers. "); - - updateRoutersRedundantState(routers); - - /* FIXME assumed the a pair of redundant routers managed by same mgmt server, - * then the update above can get the latest status */ - checkDuplicateMaster(routers); - checkSanity(routers); - } catch (Exception ex) { - s_logger.error("Fail to complete the CheckRouterTask! ", ex); - } - } - } - - - private final int DEFAULT_PRIORITY = 100; - private final int DEFAULT_DELTA = 2; - - protected int getUpdatedPriority(Network guestNetwork, List routers, DomainRouterVO exclude) throws InsufficientVirtualNetworkCapcityException { - int priority; - if (routers.size() == 0) { - priority = DEFAULT_PRIORITY; - } else { - int maxPriority = 0; - for (DomainRouterVO r : routers) { - if (!r.getIsRedundantRouter()) { - throw new CloudRuntimeException("Redundant router is mixed with single router in one network!"); - } - //FIXME Assume the maxPriority one should be running or just created. - if (r.getId() != exclude.getId() && getRealPriority(r) > maxPriority) { - maxPriority = getRealPriority(r); - } - } - if (maxPriority == 0) { - return DEFAULT_PRIORITY; - } - if (maxPriority < 20) { - s_logger.error("Current maximum priority is too low!"); - throw new InsufficientVirtualNetworkCapcityException("Current maximum priority is too low as " + maxPriority + "!", - guestNetwork.getId()); - } else if (maxPriority > 200) { - s_logger.error("Too many times fail-over happened! Current maximum priority is too high as " + maxPriority + "!"); - throw new InsufficientVirtualNetworkCapcityException("Too many times fail-over happened! Current maximum priority is too high as " - + maxPriority + "!", guestNetwork.getId()); - } - priority = maxPriority - DEFAULT_DELTA + 1; - } - return priority; - } - - /* - * Ovm won't support any system. So we have to choose a partner cluster in the same pod to start domain router for us - */ - private HypervisorType getClusterToStartDomainRouterForOvm(long podId) { - List clusters = _clusterDao.listByPodId(podId); - for (ClusterVO cv : clusters) { - if (cv.getHypervisorType() == HypervisorType.Ovm || cv.getHypervisorType() == HypervisorType.BareMetal) { - continue; - } - - List hosts = _resourceMgr.listAllHostsInCluster(cv.getId()); - if (hosts == null || hosts.isEmpty()) { - continue; - } - - for (HostVO h : hosts) { - if (h.getStatus() == Status.Up) { - s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + - cv.getId() + " to start domain router for OVM"); - return h.getHypervisorType(); - } - } - } - - String errMsg = "Cannot find an available cluster in Pod " - + podId - + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, " + - "please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod" + - " with Ovm cluster. And there is at least one host in UP status in that cluster."; - throw new CloudRuntimeException(errMsg); - } - - @DB - protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, - boolean isRedundant, Map params) throws ConcurrentOperationException, - InsufficientCapacityException, ResourceUnavailableException { - - 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.getTrafficType() == TrafficType.Guest; - - - - //1) Get deployment plan and find out the list of routers - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || - _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) - && guestNetwork.getTrafficType() == TrafficType.Guest; - - Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); - DeploymentPlan plan = planAndRouters.first(); - List routers = planAndRouters.second(); - - //2) Figure out required routers count - int routerCount = 1; - if (isRedundant) { - routerCount = 2; - } - - /* If it is the single router network, then keep it untouched */ - for (DomainRouterVO router : routers) { - if (!router.getIsRedundantRouter() || isPodBased) { - routerCount = 1; - break; - } - } - - /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ - if (routers.size() >= routerCount) { - return routers; - } - - if (routers.size() >= 5) { - s_logger.error("Too much redundant routers!"); - } - - Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); - if (network == null) { - throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); - } - - try { - //Check if providers are supported in the physical networks - VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); - } - - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } - - //Check if public network has to be set on VR - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (isRedundant && !publicNetwork) { - s_logger.error("Didn't support redundant virtual router without public network!"); - return null; - } - - Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offeringId == null) { - offeringId = _offering.getId(); - } - - PublicIp sourceNatIp = null; - if (publicNetwork) { - sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); - } - - //3) deploy virtual router(s) - int count = routerCount - routers.size(); - for (int i = 0; i < count; i++) { - List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, - new Pair(publicNetwork, sourceNatIp)); - DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, - null, networks); - - _routerDao.addRouterToGuestNetwork(router, network); - - routers.add(router); - } - } finally { - if (network != null) { - _networkDao.releaseFromLockTable(network.getId()); - } - } - return routers; - } - - protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, - boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, - Long vpcId, List> networks) throws ConcurrentOperationException, - InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, - StorageUnavailableException, ResourceUnavailableException { - - long id = _routerDao.getNextInSequence(Long.class, "id"); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating the router " + id + " in datacenter " + dest.getDataCenter()); - } - - ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); - - // Router is the network element, we don't know the hypervisor type yet. - //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up - List supportedHypervisors = new ArrayList(); - HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); - if (defaults != HypervisorType.None) { - supportedHypervisors.add(defaults); - } - - if (dest.getCluster() != null) { - if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { - supportedHypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); - } else { - supportedHypervisors.add(dest.getCluster().getHypervisorType()); - } - } else { - supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, - plan.getPodId()); - } - - if (supportedHypervisors.isEmpty()) { - if (plan.getPodId() != null) { - throw new InsufficientServerCapacityException("Unable to create virtual router, " + - "there are no clusters in the pod ", Pod.class, plan.getPodId()); - } - throw new InsufficientServerCapacityException("Unable to create virtual router, " + - "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); - } - - int allocateRetry = 0; - int startRetry = 0; - DomainRouterVO router = null; - for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { - HypervisorType hType = iter.next(); - try { - s_logger.debug("Allocating the domR with the hypervisor type " + hType); - VMTemplateVO template = _templateDao.findRoutingTemplate(hType); - - if (template == null) { - s_logger.debug(hType + " won't support system vm, skip it"); - continue; - } - - boolean offerHA = routerOffering.getOfferHA(); - /* We don't provide HA to redundant router VMs, admin should own it all, and redundant router themselves are HA */ - if (isRedundant) { - offerHA = false; - } - - router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), - VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), - template.getGuestOSId(), owner.getDomainId(), owner.getId(), isRedundant, 0, false, - RedundantState.UNKNOWN, offerHA, false, vpcId); - router.setRole(Role.VIRTUAL_ROUTER); - router = _itMgr.allocate(router, template, routerOffering, networks, plan, null, owner); - } catch (InsufficientCapacityException ex) { - if (allocateRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to allocate the domR with hypervisor type " + hType + ", retrying one more time"); - continue; - } else { - throw ex; - } - } finally { - allocateRetry++; - } - - try { - router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); - break; - } catch (InsufficientCapacityException ex) { - if (startRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", " + - "destroying it and recreating one more time"); - //destroy the router - destroyRouter(router.getId()); - continue; - } else { - throw ex; - } - } finally { - startRetry++; - } - } - - return router; - } - - protected List> createRouterNetworks(Account owner, boolean isRedundant, - DeploymentPlan plan, Network guestNetwork, Pair publicNetwork) throws ConcurrentOperationException, - InsufficientAddressCapacityException { - - - boolean setupPublicNetwork = false; - if (publicNetwork != null) { - setupPublicNetwork = publicNetwork.first(); - } - - //Form networks - List> networks = new ArrayList>(3); - - //1) Guest network - boolean hasGuestNetwork = false; - if (guestNetwork != null) { - s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); - String defaultNetworkStartIp = null; - if (guestNetwork.getCidr() != null && !setupPublicNetwork) { - String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); - if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { - defaultNetworkStartIp = startIp; - } else if (s_logger.isDebugEnabled()){ - s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + - " is already allocated, can't use it for domain router; will get random ip address from the range"); - } - } - - NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); - if (setupPublicNetwork) { - if (isRedundant) { - gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); - } else { - gatewayNic.setIp4Address(guestNetwork.getGateway()); - } - gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); - gatewayNic.setMode(guestNetwork.getMode()); - String gatewayCidr = guestNetwork.getCidr(); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - } else { - gatewayNic.setDefaultNic(true); - } - - networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); - hasGuestNetwork = true; - } - - //2) Control network - s_logger.debug("Adding nic for Virtual Router in Control network "); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); - NetworkOfferingVO controlOffering = offerings.get(0); - NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); - networks.add(new Pair(controlConfig, null)); - - - //3) Public network - if (setupPublicNetwork) { - PublicIp sourceNatIp = publicNetwork.second(); - s_logger.debug("Adding nic for Virtual Router in Public network "); - //if source nat service is supported by the network, get the source nat ip address - NicProfile defaultNic = new NicProfile(); - defaultNic.setDefaultNic(true); - defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); - defaultNic.setGateway(sourceNatIp.getGateway()); - defaultNic.setNetmask(sourceNatIp.getNetmask()); - defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - if (hasGuestNetwork) { - defaultNic.setDeviceId(2); - } - NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); - List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); - networks.add(new Pair(publicNetworks.get(0), defaultNic)); - } - - return networks; - } - - - protected Pair> getDeploymentPlanAndRouters(boolean isPodBased, - DeployDestination dest, long guestNetworkId) { - long dcId = dest.getDataCenter().getId(); - List routers = null; - DeploymentPlan plan = new DataCenterDeployment(dcId); - if (isPodBased) { - Pod pod = dest.getPod(); - Long podId = null; - if (pod != null) { - podId = pod.getId(); - } else { - throw new CloudRuntimeException("Pod id is expected in deployment destination"); - } - routers = _routerDao.listByNetworkAndPodAndRole(guestNetworkId, podId, Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId, podId, null, null, null, null); - } else { - routers = _routerDao.listByNetworkAndRole(guestNetworkId, Role.VIRTUAL_ROUTER); - } - - return new Pair>(plan, routers); - } - - - private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) - throws StorageUnavailableException, InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - - if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { - return this.start(router, user, caller, params, null); - } - - if (router.getState() == State.Running) { - s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!"); - return router; - } - - DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); - DomainRouterVO result = null; - assert router.getIsRedundantRouter(); - List routerList = _routerDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn()); - DomainRouterVO routerToBeAvoid = null; - for (DomainRouterVO rrouter : routerList) { - if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) { - if (routerToBeAvoid != null) { - throw new ResourceUnavailableException("Try to start router " + router.getInstanceName() + "(" + router.getId() + ")" - + ", but there are already two redundant routers with IP " + router.getPublicIpAddress() - + ", they are " + rrouter.getInstanceName() + "(" + rrouter.getId() + ") and " - + routerToBeAvoid.getInstanceName() + "(" + routerToBeAvoid.getId() + ")", - DataCenter.class, rrouter.getDataCenterIdToDeployIn()); - } - routerToBeAvoid = rrouter; - } - } - if (routerToBeAvoid == null) { - return this.start(router, user, caller, params, null); - } - // We would try best to deploy the router to another place - int retryIndex = 5; - ExcludeList[] avoids = new ExcludeList[5]; - avoids[0] = new ExcludeList(); - avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn()); - avoids[1] = new ExcludeList(); - avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId()); - avoids[2] = new ExcludeList(); - List volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Type.ROOT); - if (volumes != null && volumes.size() != 0) { - avoids[2].addPool(volumes.get(0).getPoolId()); - } - avoids[2].addHost(routerToBeAvoid.getHostId()); - avoids[3] = new ExcludeList(); - avoids[3].addHost(routerToBeAvoid.getHostId()); - avoids[4] = new ExcludeList(); - - for (int i = 0; i < retryIndex; i++) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Try to deploy redundant virtual router:" + router.getHostName() + ", for " + i + " time"); - } - plan.setAvoids(avoids[i]); - try { - result = this.start(router, user, caller, params, plan); - } catch (InsufficientServerCapacityException ex) { - result = null; - } - if (result != null) { - break; - } - } - return result; - } - - @Override - public List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, - Map params, boolean isRedundant) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - - List routers = findOrDeployVirtualRouterInGuestNetwork - (guestNetwork, dest, owner, isRedundant, params); - - return startRouters(params, routers); - } - - protected List startRouters(Map params, List routers) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, - ResourceUnavailableException { - List runningRouters = null; - - if (routers != null) { - runningRouters = new ArrayList(); - } - - for (DomainRouterVO router : routers) { - boolean skip = false; - State state = router.getState(); - if (router.getHostId() != null && state != State.Running) { - HostVO host = _hostDao.findById(router.getHostId()); - if (host == null || host.getStatus() != Status.Up) { - skip = true; - } - } - if (!skip) { - if (state != State.Running) { - router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); - } - if (router != null) { - runningRouters.add(router); - } - } - } - return runningRouters; - } - - @Override - public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, - ReservationContext context) { - - boolean dnsProvided = true; - boolean dhcpProvided = true; - boolean publicNetwork = false; - DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); - _dcDao.loadDetails(dc); - - //1) Set router details - DomainRouterVO router = profile.getVirtualMachine(); - Map details = _vmDetailsDao.findDetails(router.getId()); - router.setDetails(details); - - //2) Prepare boot loader elements related with Control network - - StringBuilder buf = profile.getBootArgsBuilder(); - buf.append(" template=domP"); - buf.append(" name=").append(profile.getHostName()); - - if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { - buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); - } - - NicProfile controlNic = null; - String defaultDns1 = null; - String defaultDns2 = null; - for (NicProfile nic : profile.getNics()) { - int deviceId = nic.getDeviceId(); - buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); - buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); - - if (nic.isDefaultNic()) { - buf.append(" gateway=").append(nic.getGateway()); - defaultDns1 = nic.getDns1(); - defaultDns2 = nic.getDns2(); - } - - if (nic.getTrafficType() == TrafficType.Management) { - buf.append(" localgw=").append(dest.getPod().getGateway()); - } else if (nic.getTrafficType() == TrafficType.Control) { - controlNic = nic; - // DOMR control command is sent over management server in VMware - if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " - + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() - + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmt_host); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Add management server explicit route to DomR."); - } - - // always add management explicit route, for basic networking setup, DomR may have two interfaces while both - // are on the same subnet - _mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key()); - if (NetUtils.isValidCIDR(_mgmt_cidr)) { - buf.append(" mgmtcidr=").append(_mgmt_cidr); - buf.append(" localgw=").append(dest.getPod().getGateway()); - } - - - if (dc.getNetworkType() == NetworkType.Basic) { - // ask domR to setup SSH on guest network - buf.append(" sshonguest=true"); - } - - } - } else if (nic.getTrafficType() == TrafficType.Guest) { - dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter); - dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter); - //build bootloader parameter for the guest - buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router)); - } else if (nic.getTrafficType() == TrafficType.Public) { - publicNetwork = true; - } - } - - if (controlNic == null) { - throw new CloudRuntimeException("Didn't start a control port"); - } - - String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); - if (rpValue != null && rpValue.equalsIgnoreCase("true")) { - _disable_rp_filter = true; - }else { - _disable_rp_filter = false; - } - - String rpFilter = " "; - String type = null; - if (router.getVpcId() != null) { - type = "vpcrouter"; - if (_disable_rp_filter) { - rpFilter=" disable_rp_filter=true"; - } - } else if (!publicNetwork) { - type = "dhcpsrvr"; - } else { - type = "router"; - if (_disable_rp_filter) { - rpFilter=" disable_rp_filter=true"; - } - } - - if (_disable_rp_filter) { - rpFilter=" disable_rp_filter=true"; - } - - buf.append(" type=" + type + rpFilter); - - String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName()); - if (domain_suffix != null) { - buf.append(" dnssearchorder=").append(domain_suffix); - } - - if (profile.getHypervisorType() == HypervisorType.VMware) { - buf.append(" extra_pubnics=" + _routerExtraPublicNics); - } - - /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response - * to return DNS server rather than - * virtual router itself. */ - if (dnsProvided || dhcpProvided) { - if (defaultDns1 != null) { - buf.append(" dns1=").append(defaultDns1); - } - if (defaultDns2 != null) { - buf.append(" dns2=").append(defaultDns2); - } - - boolean useExtDns = !dnsProvided; - /* For backward compatibility */ - String use_external_dns = _configDao.getValue(Config.UseExternalDnsServers.key()); - if (use_external_dns != null && use_external_dns.equals("true")) { - useExtDns = true; - } - - if (useExtDns) { - buf.append(" useextdns=true"); - } - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); - } - - return true; - } - - - protected StringBuilder createGuestBootLoadArgs(NicProfile guestNic, String defaultDns1, - String defaultDns2, DomainRouterVO router) { - long guestNetworkId = guestNic.getNetworkId(); - NetworkVO guestNetwork = _networkDao.findById(guestNetworkId); - String dhcpRange = null; - DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId()); - - StringBuilder buf = new StringBuilder(); - - boolean isRedundant = router.getIsRedundantRouter(); - if (isRedundant) { - buf.append(" redundant_router=1"); - List routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - try { - int priority = getUpdatedPriority(guestNetwork, routers, router); - router.setPriority(priority); - } catch (InsufficientVirtualNetworkCapcityException e) { - s_logger.error("Failed to get update priority!", e); - throw new CloudRuntimeException("Failed to get update priority!"); - } - Network net = _networkMgr.getNetwork(guestNic.getNetworkId()); - buf.append(" guestgw=").append(net.getGateway()); - String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); - buf.append(" guestbrd=").append(brd); - buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getNetmask())); - buf.append(" router_pr=").append(router.getPriority()); - } - - //setup network domain - String domain = guestNetwork.getNetworkDomain(); - if (domain != null) { - buf.append(" domain=" + domain); - } - - //setup dhcp range - if (dc.getNetworkType() == NetworkType.Basic) { - if (guestNic.isDefaultNic()) { - long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); - String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); - if (cidr != null) { - dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); - } - } - } else if (dc.getNetworkType() == NetworkType.Advanced) { - String cidr = guestNetwork.getCidr(); - if (cidr != null) { - dhcpRange = NetUtils.getDhcpRange(cidr); - } - } - - if (dhcpRange != null) { - buf.append(" dhcprange=" + dhcpRange); - } - - return buf; - } - - - protected String getGuestDhcpRange(NicProfile guestNic, Network guestNetwork, DataCenter dc) { - String dhcpRange = null; - //setup dhcp range - if (dc.getNetworkType() == NetworkType.Basic) { - long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); - String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); - if (cidr != null) { - dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); - } - } else if (dc.getNetworkType() == NetworkType.Advanced) { - String cidr = guestNetwork.getCidr(); - if (cidr != null) { - dhcpRange = NetUtils.getDhcpRange(cidr); - } - } - return dhcpRange; - } - - @Override - public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, - DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { - DomainRouterVO router = profile.getVirtualMachine(); - - List nics = profile.getNics(); - for (NicProfile nic : nics) { - if (nic.getTrafficType() == TrafficType.Public) { - router.setPublicIpAddress(nic.getIp4Address()); - router.setPublicNetmask(nic.getNetmask()); - router.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Control) { - router.setPrivateIpAddress(nic.getIp4Address()); - router.setPrivateMacAddress(nic.getMacAddress()); - } - } - _routerDao.update(router.getId(), router); - - finalizeCommandsOnStart(cmds, profile); - return true; - } - - @Override - public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { - DomainRouterVO router = profile.getVirtualMachine(); - NicProfile controlNic = getControlNic(profile); - - if (controlNic == null) { - s_logger.error("Control network doesn't exist for the router " + router); - return false; - } - - finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic); - - // restart network if restartNetwork = false is not specified in profile parameters - boolean reprogramGuestNtwks = true; - if (profile.getParameter(Param.ReProgramGuestNetworks) != null - && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { - reprogramGuestNtwks = false; - } - - VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName()); - } - Provider provider = Network.Provider.getProvider(vrProvider.getType().toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); - } - - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - for (Long guestNetworkId : routerGuestNtwkIds) { - if (reprogramGuestNtwks) { - finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId); - finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); - } - - finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); - } - - return true; - } - - protected NicProfile getControlNic(VirtualMachineProfile profile) { - DomainRouterVO router = profile.getVirtualMachine(); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - NicProfile controlNic = null; - if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { - // TODO this is a ugly to test hypervisor type here - // for basic network mode, we will use the guest NIC for control NIC - for (NicProfile nic : profile.getNics()) { - if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { - controlNic = nic; - } - } - } else { - for (NicProfile nic : profile.getNics()) { - if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { - controlNic = nic; - } - } - } - return controlNic; - } - - protected void finalizeSshAndVersionAndNetworkUsageOnStart(Commands cmds, VirtualMachineProfile profile, DomainRouterVO router, NicProfile controlNic) { - cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); - - // Update router template/scripts version - final GetDomRVersionCmd command = new GetDomRVersionCmd(); - command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIp4Address()); - command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - cmds.addCommand("getDomRVersion", command); - - // Network usage command to create iptables rules - boolean forVpc = profile.getVirtualMachine().getVpcId() != null; - cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); - } - - protected void finalizeUserDataAndDhcpOnStart(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) { - // Resend dhcp - s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start..."); - createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId); - } - - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) { - // Resend user data - s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start..."); - createVmDataCommandForVMs(router, cmds, guestNetworkId); - } - } - - protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { - s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); - - ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); - - if (publicIps != null && !publicIps.isEmpty()) { - List vpns = new ArrayList(); - List pfRules = new ArrayList(); - List staticNatFirewallRules = new ArrayList(); - List staticNats = new ArrayList(); - List firewallRules = new ArrayList(); - - //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) - for (PublicIpAddress ip : publicIps) { - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) { - pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); - } - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { - staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); - } - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { - firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall)); - } - - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) { - RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); - if (vpn != null) { - vpns.add(vpn); - } - } - - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { - if (ip.isOneToOneNat()) { - String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId); - StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false); - staticNats.add(staticNat); - } - } - } - - //Re-apply static nats - s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); - if (!staticNats.isEmpty()) { - createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId); - } - - //Re-apply firewall rules - s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start."); - if (!firewallRules.isEmpty()) { - createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId); - } - - // Re-apply port forwarding rules - s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start."); - if (!pfRules.isEmpty()) { - createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId); - } - - // Re-apply static nat rules - s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start."); - if (!staticNatFirewallRules.isEmpty()) { - List staticNatRules = new ArrayList(); - for (FirewallRule rule : staticNatFirewallRules) { - staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); - } - createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); - } - - // Re-apply vpn rules - s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start."); - if (!vpns.isEmpty()) { - for (RemoteAccessVpn vpn : vpns) { - createApplyVpnCommands(vpn, router, cmds); - } - } - - List lbs = _loadBalancerDao.listByNetworkId(guestNetworkId); - List lbRules = new ArrayList(); - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) { - // Re-apply load balancing rules - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); - lbRules.add(loadBalancing); - } - } - - s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start."); - if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId); - } - } - } - - protected void finalizeIpAssocForNetwork(Commands cmds, VirtualRouter router, Provider provider, - Long guestNetworkId) { - - ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); - - if (publicIps != null && !publicIps.isEmpty()) { - s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); - // Re-apply public ip addresses - should come before PF/LB/VPN - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { - createAssociateIPCommands(router, publicIps, cmds, 0); - } - } - } - - protected ArrayList getPublicIpsToApply(VirtualRouter router, Provider provider, - Long guestNetworkId, com.cloud.network.IpAddress.State... skipInStates) { - long ownerId = router.getAccountId(); - final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); - List allPublicIps = new ArrayList(); - if (userIps != null && !userIps.isEmpty()) { - boolean addIp = true; - for (IPAddressVO userIp : userIps) { - if (skipInStates != null) { - for (IpAddress.State stateToSkip : skipInStates) { - if (userIp.getState() == stateToSkip) { - s_logger.debug("Skipping ip address " + userIp + " in state " + userIp.getState()); - addIp = false; - break; - } - } - } - - if (addIp) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), - NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); - allPublicIps.add(publicIp); - } - } - } - - //Get public Ips that should be handled by router - Network network = _networkDao.findById(guestNetworkId); - Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); - Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); - // Only cover virtual router for now, if ELB use it this need to be modified - - ArrayList publicIps = providerToIpList.get(provider); - return publicIps; - } - - @Override - public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, - ReservationContext context) { - DomainRouterVO router = profile.getVirtualMachine(); - - boolean result = true; - - Answer answer = cmds.getAnswer("checkSsh"); - if (answer != null && answer instanceof CheckSshAnswer) { - CheckSshAnswer sshAnswer = (CheckSshAnswer) answer; - if (sshAnswer == null || !sshAnswer.getResult()) { - s_logger.warn("Unable to ssh to the VM: " + sshAnswer.getDetails()); - result = false; - } - } else { - result = false; - } - if (result == false) { - return result; - } - - //Get guest networks info - List guestNetworks = new ArrayList(); - - List routerNics = _nicDao.listByVmId(profile.getId()); - for (Nic routerNic : routerNics) { - Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); - if (network.getTrafficType() == TrafficType.Guest) { - guestNetworks.add(network); - } - } - - answer = cmds.getAnswer("getDomRVersion"); - if (answer != null && answer instanceof GetDomRVersionAnswer) { - GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; - if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + - " due to: " + versionAnswer.getDetails()); - result = false; - } else { - router.setTemplateVersion(versionAnswer.getTemplateVersion()); - router.setScriptsVersion(versionAnswer.getScriptsVersion()); - router = _routerDao.persist(router, guestNetworks); - } - } else { - result = false; - } - - return result; - } - - @Override - public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { - if (answer != null) { - VMInstanceVO vm = profile.getVirtualMachine(); - DomainRouterVO domR = _routerDao.findById(vm.getId()); - processStopOrRebootAnswer(domR, answer); - } - } - - @Override - public void finalizeExpunge(DomainRouterVO vm) { - } - - - @Override - public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) - throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Failed to start remote access VPN: no router found for account and zone"); - throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", - DataCenter.class, network.getDataCenterId()); - } - - for (VirtualRouter router : routers) { - if (router.getState() != State.Running) { - s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " - + router.getState(), DataCenter.class, network.getDataCenterId()); - } - - Commands cmds = new Commands(OnError.Stop); - createApplyVpnCommands(vpn, router, cmds); - - try { - _agentMgr.send(router.getHostId(), cmds); - } catch (OperationTimedoutException e) { - s_logger.debug("Failed to start remote access VPN: ", e); - throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); - } - Answer answer = cmds.getAnswer("users"); - if (!answer.getResult()) { - s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() - + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() - + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + - router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " - + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); - } - answer = cmds.getAnswer("startVpn"); - if (!answer.getResult()) { - s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + - vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " - + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() - + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() - + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); - } - - } - return true; - } - - - @Override - public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) - throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Failed to delete remote access VPN: no router found for account and zone"); - throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId()); - } - - boolean result = true; - for (VirtualRouter router : routers) { - if (router.getState() == State.Running) { - Commands cmds = new Commands(OnError.Continue); - IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - - RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), - vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand(removeVpnCmd); - - result = result && sendCommandsToRouter(router, cmds); - } else if (router.getState() == State.Stopped) { - s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it"); - continue; - } else { - s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + - router.getState(), DataCenter.class, network.getDataCenterId()); - } - } - - return result; - } - - - private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) - throws StorageUnavailableException, InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - s_logger.debug("Starting router " + router); - if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { - return _routerDao.findById(router.getId()); - } else { - return null; - } - } - - @Override - public DomainRouterVO stop(VirtualRouter router, boolean forced, User user, Account caller) throws ConcurrentOperationException, ResourceUnavailableException { - s_logger.debug("Stopping router " + router); - try { - if (_itMgr.advanceStop((DomainRouterVO) router, forced, user, caller)) { - return _routerDao.findById(router.getId()); - } else { - return null; - } - } catch (OperationTimedoutException e) { - throw new CloudRuntimeException("Unable to stop " + router, e); - } - } - - @Override - public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, - DeployDestination dest, List routers) - throws ResourceUnavailableException { - _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); - - final VirtualMachineProfile updatedProfile = profile; - final boolean isZoneBasic = (dest.getDataCenter().getNetworkType() == NetworkType.Basic); - final Long podId = isZoneBasic ? dest.getPod().getId() : null; - - boolean podLevelException = false; - //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User - && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { - podLevelException = true; - } - - return applyRules(network, routers, "dhcp entry", podLevelException, podId, true, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - //for basic zone, send dhcp/dns information to all routers in the basic network only when _dnsBasicZoneUpdates is set to "all" value - Commands cmds = new Commands(OnError.Stop); - if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod"))) { - NicVO nicVo = _nicDao.findById(nic.getId()); - createDhcpEntryCommand(router, updatedProfile.getVirtualMachine(), nicVo, cmds); - return sendCommandsToRouter(router, cmds); - } - return true; - } - }); - } - - private String findDefaultDnsIp(long userVmId) { - NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId); - - //check if DNS provider is the domR - if (!_networkMgr.isProviderSupportServiceInNetwork(defaultNic.getNetworkId(), Service.Dns, Provider.VirtualRouter)) { - return null; - } - - NetworkOfferingVO offering = _networkOfferingDao.findById(_networkDao.findById(defaultNic.getNetworkId()).getNetworkOfferingId()); - if (offering.getRedundantRouter()) { - return findGatewayIp(userVmId); - } - - //find domR's nic in the network - NicVO domrDefaultNic = _nicDao.findByNetworkIdAndType(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter); - return domrDefaultNic.getIp4Address(); - } - - private String findGatewayIp(long userVmId) { - NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId); - return defaultNic.getGateway(); - } - - @Override - public boolean applyUserData(Network network, final NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, List routers) - throws ResourceUnavailableException { - _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); - - final VirtualMachineProfile updatedProfile = profile; - final boolean isZoneBasic = (dest.getDataCenter().getNetworkType() == NetworkType.Basic); - final Long podId = isZoneBasic ? dest.getPod().getId() : null; - - boolean podLevelException = false; - //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User - && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { - podLevelException = true; - } - - return applyRules(network, routers, "userdata and password entry", podLevelException, podId, false, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - //for basic zone, send vm data/password information only to the router in the same pod - Commands cmds = new Commands(OnError.Stop); - if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue())) { - NicVO nicVo = _nicDao.findById(nic.getId()); - createPasswordCommand(router, updatedProfile, nicVo, cmds); - createVmDataCommand(router, updatedProfile.getVirtualMachine(), nicVo, updatedProfile.getVirtualMachine().getDetail("SSH.PublicKey"), cmds); - return sendCommandsToRouter(router, cmds); - } - return true; - } - }); - } - - @Override - public DomainRouterVO persist(DomainRouterVO router) { - DomainRouterVO virtualRouter = _routerDao.persist(router); - return virtualRouter; - } - - @Override - //FIXME add partial success and STOP state support - public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + - network.getId(), DataCenter.class, network.getDataCenterId()); - } - - boolean agentResults = true; - - for (DomainRouterVO router : routers) { - if (router.getState() != State.Running) { - s_logger.warn("Failed to add/remove VPN users: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + - router.getState(), DataCenter.class, network.getDataCenterId()); - } - - Commands cmds = new Commands(OnError.Continue); - List addUsers = new ArrayList(); - List removeUsers = new ArrayList(); - for (VpnUser user : users) { - if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) { - addUsers.add(user); - } else if (user.getState() == VpnUser.State.Revoke) { - removeUsers.add(user); - } - } - - VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers); - cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); - cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand(cmd); - - - // Currently we receive just one answer from the agent. In the future we have to parse individual answers and set - // results accordingly - boolean agentResult = sendCommandsToRouter(router, cmds); - agentResults = agentResults && agentResult; - } - - String[] result = new String[users.size()]; - for (int i = 0; i < result.length; i++) { - if (agentResults) { - result[i] = null; - } else { - result[i] = String.valueOf(agentResults); - } - } - - return result; - } - - @Override - public DomainRouterVO findById(long id) { - return _routerDao.findById(id); - } - - @Override - public DomainRouterVO findByName(String name) { - if (!VirtualMachineName.isValidRouterName(name)) { - return null; - } - - return _routerDao.findById(VirtualMachineName.getRouterId(name)); - } - - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "starting router Vm", async = true) - public VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException{ - return startRouter(id, true); - } - - @Override - public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, - InsufficientCapacityException, ConcurrentOperationException { - Account caller = UserContext.current().getCaller(); - User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - - // verify parameters - DomainRouterVO router = _routerDao.findById(routerId); - if (router == null) { - throw new InvalidParameterValueException("Unable to find router by id " + routerId + "."); - } - _accountMgr.checkAccess(caller, null, true, router); - - Account owner = _accountMgr.getAccount(router.getAccountId()); - - // Check if all networks are implemented for the domR; if not - implement them - DataCenter dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); - HostPodVO pod = null; - if (router.getPodIdToDeployIn() != null) { - pod = _podDao.findById(router.getPodIdToDeployIn()); - } - DeployDestination dest = new DeployDestination(dc, pod, null, null); - - ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner); - - List nics = _nicDao.listByVmId(routerId); - - for (NicVO nic : nics) { - if (!_networkMgr.startNetwork(nic.getNetworkId(), dest, context)) { - s_logger.warn("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start"); - throw new CloudRuntimeException("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start"); - } - } - - UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); - Map params = new HashMap(); - if (reprogramNetwork) { - params.put(Param.ReProgramGuestNetworks, true); - } else { - params.put(Param.ReProgramGuestNetworks, false); - } - VirtualRouter virtualRouter = startVirtualRouter(router, user, caller, params); - if(virtualRouter == null){ - throw new CloudRuntimeException("Failed to start router with id " + routerId); - } - return virtualRouter; - } - - private void createAssociateIPCommands(final VirtualRouter router, final List ips, Commands cmds, long vmId) { - - // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc.. - Map> vlanIpMap = new HashMap>(); - for (final PublicIpAddress ipAddress : ips) { - String vlanTag = ipAddress.getVlanTag(); - ArrayList ipList = vlanIpMap.get(vlanTag); - if (ipList == null) { - ipList = new ArrayList(); - } - //domR doesn't support release for sourceNat IP address; so reset the state - if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) { - ipAddress.setState(IpAddress.State.Allocated); - } - ipList.add(ipAddress); - vlanIpMap.put(vlanTag, ipList); - } - - for (Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { - List ipAddrList = vlanAndIp.getValue(); - // Source nat ip address should always be sent first - Collections.sort(ipAddrList, new Comparator() { - @Override - public int compare(PublicIpAddress o1, PublicIpAddress o2) { - boolean s1 = o1.isSourceNat(); - boolean s2 = o2.isSourceNat(); - return (s1 ^ s2) ? ((s1 ^ true) ? 1 : -1) : 0; - } - }); - - // Get network rate - required for IpAssoc - Integer networkRate = _networkMgr.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); - Network network = _networkMgr.getNetwork(ipAddrList.get(0).getNetworkId()); - - IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; - int i = 0; - boolean firstIP = true; - - for (final PublicIpAddress ipAddr : ipAddrList) { - - boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); - boolean sourceNat = ipAddr.isSourceNat(); - /* enable sourceNAT for the first ip of the public interface */ - if (firstIP) { - sourceNat = true; - } - String vlanId = ipAddr.getVlanTag(); - String vlanGateway = ipAddr.getGateway(); - String vlanNetmask = ipAddr.getNetmask(); - String vifMacAddress = ipAddr.getMacAddress(); - - String vmGuestAddress = null; - - IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, - sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); - - ip.setTrafficType(network.getTrafficType()); - ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); - ipsToSend[i++] = ip; - /* send the firstIP = true for the first Add, this is to create primary on interface*/ - if (!firstIP || add) { - firstIP = false; - } - } - IpAssocCommand cmd = new IpAssocCommand(ipsToSend); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("IPAssocCommand", cmd); - } - } - - private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (PortForwardingRule rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, sourceIp.getAddress().addr()); - rulesTO.add(ruleTO); - } - } - - SetPortForwardingRulesCommand cmd = null; - - if (router.getVpcId() != null) { - cmd = new SetPortForwardingRulesVpcCommand(rulesTO); - } else { - cmd = new SetPortForwardingRulesCommand(rulesTO); - } - - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand(cmd); - } - - private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (StaticNatRule rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getDestIpAddress()); - rulesTO.add(ruleTO); - } - } - - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand(cmd); - } - - private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { - - LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; - int i = 0; - for (LoadBalancingRule rule : rules) { - boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); - String protocol = rule.getProtocol(); - String algorithm = rule.getAlgorithm(); - - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); - int srcPort = rule.getSourcePortStart(); - List destinations = rule.getDestinations(); - List stickinessPolicies = rule.getStickinessPolicies(); - LoadBalancerTO lb = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations, stickinessPolicies); - lbs[i++] = lb; - } - String routerPublicIp = null; - - if (router instanceof DomainRouterVO) { - DomainRouterVO domr = _routerDao.findById(router.getId()); - routerPublicIp = domr.getPublicIpAddress(); - } - - Network guestNetwork = _networkMgr.getNetwork(guestNetworkId); - Nic nic = _nicDao.findByInstanceIdAndNetworkId(guestNetwork.getId(), router.getId()); - NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), - _networkMgr.getNetworkRate(guestNetwork.getId(), router.getId()), - _networkMgr.isSecurityGroupSupportedInNetwork(guestNetwork), - _networkMgr.getNetworkTag(router.getHypervisorType(), guestNetwork)); - - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,routerPublicIp, - getRouterIpInNetwork(guestNetworkId, router.getId()),router.getPrivateIpAddress(), - _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId()); - - cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); - cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); - cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); - cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); - - - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand(cmd); - - } - - private void createApplyVpnCommands(RemoteAccessVpn vpn, VirtualRouter router, Commands cmds) { - List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); - List addUsers = new ArrayList(); - List removeUsers = new ArrayList(); - for (VpnUser user : vpnUsers) { - if (user.getState() == VpnUser.State.Add) { - addUsers.add(user); - } else if (user.getState() == VpnUser.State.Revoke) { - removeUsers.add(user); - } - } - - VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - - IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - - RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), - vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("users", addUsersCmd); - cmds.addCommand("startVpn", startVpnCmd); - } - - private void createPasswordCommand(VirtualRouter router, VirtualMachineProfile profile, NicVO nic, Commands cmds) { - String password = (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - - // password should be set only on default network element - if (password != null && nic.isDefaultNic()) { - final String encodedPassword = PasswordGenerator.rot13(password); - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("password", cmd); - } - - } - - private void createVmDataCommand(VirtualRouter router, UserVm vm, NicVO nic, String publicKey, Commands cmds) { - String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); - String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); - cmds.addCommand("vmdata", - generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), - vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey, nic.getNetworkId())); - - } - - private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { - List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); - DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); - for (UserVmVO vm : vms) { - boolean createVmData = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()) { - createVmData = false; - } - - if (createVmData) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); - if (nic != null) { - s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); - createVmDataCommand(router, vm, nic, null, cmds); - } - } - } - } - - private void createDhcpEntryCommand(VirtualRouter router, UserVm vm, NicVO nic, Commands cmds) { - DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - String gatewayIp = findGatewayIp(vm.getId()); - if (!gatewayIp.equals(nic.getGateway())) { - GuestOSVO guestOS = _guestOSDao.findById(vm.getGuestOSId()); - // Don't set dhcp:router option for non-default nic on CentOS/RHEL, because they would set routing on wrong interface - // This is tricky, we may need to update this when we have more information on various OS's behavior - if (guestOS.getDisplayName().startsWith("CentOS") || guestOS.getDisplayName().startsWith("Red Hat Enterprise")) { - gatewayIp = "0.0.0.0"; - } - } - dhcpCommand.setDefaultRouter(gatewayIp); - dhcpCommand.setDefaultDns(findDefaultDnsIp(vm.getId())); - - dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); - dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("dhcp", dhcpCommand); - } - - private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { - List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); - DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); - for (UserVmVO vm : vms) { - boolean createDhcp = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() - && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { - createDhcp = false; - } - if (createDhcp) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); - if (nic != null) { - s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + "."); - createDhcpEntryCommand(router, vm, nic, cmds); - } - } - } - } - - protected boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { - Answer[] answers = null; - try { - answers = _agentMgr.send(router.getHostId(), cmds); - } catch (OperationTimedoutException e) { - s_logger.warn("Timed Out", e); - throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); - } - - if (answers == null) { - return false; - } - - if (answers.length != cmds.size()) { - return false; - } - - // FIXME: Have to return state for individual command in the future - boolean result = true; - if (answers.length > 0) { - for (Answer answer : answers) { - if (!answer.getResult()) { - result = false; - break; - } - } - } - return result; - } - - protected void handleSingleWorkingRedundantRouter(List connectedRouters, List disconnectedRouters, String reason) throws ResourceUnavailableException - { - if (connectedRouters.isEmpty() || disconnectedRouters.isEmpty()) { - return; - } - if (connectedRouters.size() != 1 || disconnectedRouters.size() != 1) { - s_logger.warn("How many redundant routers do we have?? "); - return; - } - if (!connectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", - DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); - } - if (!disconnectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", - DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); - } - - DomainRouterVO connectedRouter = (DomainRouterVO)connectedRouters.get(0); - DomainRouterVO disconnectedRouter = (DomainRouterVO)disconnectedRouters.get(0); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("About to stop the router " + disconnectedRouter.getInstanceName() + " due to: " + reason); - } - String title = "Virtual router " + disconnectedRouter.getInstanceName() + " would be stopped after connecting back, due to " + reason; - String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId() + ") would be stopped after connecting back, due to: " + reason; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, - disconnectedRouter.getDataCenterIdToDeployIn(), disconnectedRouter.getPodIdToDeployIn(), title, context); - disconnectedRouter.setStopPending(true); - disconnectedRouter = _routerDao.persist(disconnectedRouter); - - int connRouterPR = getRealPriority(connectedRouter); - int disconnRouterPR = getRealPriority(disconnectedRouter); - if (connRouterPR < disconnRouterPR) { - //connRouterPR < disconnRouterPR, they won't equal at anytime - if (!connectedRouter.getIsPriorityBumpUp()) { - final BumpUpPriorityCommand command = new BumpUpPriorityCommand(); - command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(connectedRouter.getId())); - command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, connectedRouter.getInstanceName()); - final Answer answer = _agentMgr.easySend(connectedRouter.getHostId(), command); - if (!answer.getResult()) { - s_logger.error("Failed to bump up " + connectedRouter.getInstanceName() + "'s priority! " + answer.getDetails()); - } - } else { - String t = "Can't bump up virtual router " + connectedRouter.getInstanceName() + "'s priority due to it's already bumped up!"; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, - connectedRouter.getDataCenterIdToDeployIn(), connectedRouter.getPodIdToDeployIn(), t, t); - } - } - } - - @Override - public boolean associatePublicIP(Network network, final List ipAddress, List routers) - throws ResourceUnavailableException { - if (ipAddress == null || ipAddress.isEmpty()) { - s_logger.debug("No ip association rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "ip association", false, null, false, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createAssociateIPCommands(router, ipAddress, cmds, 0); - return sendCommandsToRouter(router, cmds); - } - }); - } - - @Override - public boolean applyFirewallRules(Network network, final List rules, List routers) throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No firewall rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "firewall rules", false, null, false, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - if (rules.get(0).getPurpose() == Purpose.LoadBalancing) { - // for load balancer we have to resend all lb rules for the network - List lbs = _loadBalancerDao.listByNetworkId(network.getId()); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList,policyList); - lbRules.add(loadBalancing); - } - return sendLBRules(router, lbRules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.PortForwarding) { - return sendPortForwardingRules(router, (List) rules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.StaticNat) { - return sendStaticNatRules(router, (List) rules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.Firewall) { - return sendFirewallRules(router, (List) rules, network.getId()); - } else { - s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); - return false; - } - } - }); - } - - protected boolean sendLBRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - protected boolean sendPortForwardingRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplyPortForwardingRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - protected boolean sendStaticNatRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - @Override - public List getRoutersForNetwork(long networkId) { - List routers = _routerDao.findByNetwork(networkId); - List vrs = new ArrayList(routers.size()); - for (DomainRouterVO router : routers) { - vrs.add(router); - } - return vrs; - } - - private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (FirewallRule rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr()); - rulesTO.add(ruleTO); - } - } - - SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand(cmd); - } - - - protected boolean sendFirewallRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createFirewallRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - @Override - public String getDnsBasicZoneUpdate() { - return _dnsBasicZoneUpdates; - } - - protected interface RuleApplier { - boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; - } - - protected boolean applyRules(Network network, List routers, String typeString, - boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); - throw new ResourceUnavailableException("Unable to apply " + typeString , DataCenter.class, network.getDataCenterId()); - } - - DataCenter dc = _dcDao.findById(network.getDataCenterId()); - boolean isZoneBasic = (dc.getNetworkType() == NetworkType.Basic); - - // isPodLevelException and podId is only used for basic zone - assert !((!isZoneBasic && isPodLevelException) || (isZoneBasic && isPodLevelException && podId == null)); - - List connectedRouters = new ArrayList(); - List disconnectedRouters = new ArrayList(); - boolean result = true; - String msg = "Unable to apply " + typeString + " on disconnected router "; - for (VirtualRouter router : routers) { - if (router.getState() == State.Running) { - s_logger.debug("Applying " + typeString + " in network " + network); - - if (router.isStopPending()) { - if (_hostDao.findById(router.getHostId()).getStatus() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + - router.getInstanceName() + " haven't been stopped after it's host coming back!", - DataCenter.class, router.getDataCenterIdToDeployIn()); - } - s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + - typeString + " commands to the backend"); - continue; - } - try { - result = applier.execute(network, router); - connectedRouters.add(router); - } catch (AgentUnavailableException e) { - s_logger.warn(msg + router.getInstanceName(), e); - disconnectedRouters.add(router); - } - - //If rules fail to apply on one domR and not due to disconnection, no need to proceed with the rest - if (!result) { - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); - } - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, - router.getDataCenterIdToDeployIn()); - } - - } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { - s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + - ", so not sending apply " + typeString + " commands to the backend"); - } else { - s_logger.warn("Unable to apply " + typeString +", virtual router is not in the right state " + router.getState()); - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + - ", virtual router is not in the right state", Pod.class, podId); - } - throw new ResourceUnavailableException("Unable to apply " + typeString + - ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); - } - } - - if (!connectedRouters.isEmpty()) { - if (!isZoneBasic && !disconnectedRouters.isEmpty() && disconnectedRouters.get(0).getIsRedundantRouter()) { - // These disconnected redundant virtual routers are out of sync now, stop them for synchronization - handleSingleWorkingRedundantRouter(connectedRouters, disconnectedRouters, msg); - } - } else if (!disconnectedRouters.isEmpty()) { - for (VirtualRouter router : disconnectedRouters) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg + router.getInstanceName() + "(" + router.getId() + ")"); - } - } - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException(msg, Pod.class, podId); - } - throw new ResourceUnavailableException(msg, DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); - } - - result = true; - if (failWhenDisconnect) { - result = !connectedRouters.isEmpty(); - } - return result; - } - - @Override - public boolean applyStaticNats(Network network, final List rules, List routers) throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No static nat rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "static nat rules", false, null, false, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - return applyStaticNat(router, rules, network.getId()); - } - }); - } - - - protected boolean applyStaticNat(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds, - long guestNetworkId) { - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (StaticNat rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, - null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); - rulesTO.add(ruleTO); - } - } - - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand(cmd); - } - - @Override - public int getTimeout() { - return -1; - } - - @Override - public boolean isRecurring() { - return false; - } - - @Override - public boolean processAnswers(long agentId, long seq, Answer[] answers) { - return false; - } - - @Override - public boolean processCommands(long agentId, long seq, Command[] commands) { - return false; - } - - @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { - UserContext context = UserContext.current(); - context.setAccountId(1); - List routers = _routerDao.listIsolatedByHostId(host.getId()); - for (DomainRouterVO router : routers) { - if (router.isStopPending()) { - State state = router.getState(); - if (state != State.Stopped && state != State.Destroyed) { - try { - stopRouter(router.getId(), false); - } catch (ResourceUnavailableException e) { - s_logger.warn("Fail to stop router " + router.getInstanceName(), e); - throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName()); - } catch (ConcurrentOperationException e) { - s_logger.warn("Fail to stop router " + router.getInstanceName(), e); - throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName()); - } - } - router.setStopPending(false); - router = _routerDao.persist(router); - } - } - } - - @Override - public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { - return null; - } - - @Override - - public boolean processDisconnect(long agentId, Status state) { - return false; - } - - @Override - public boolean processTimeout(long agentId, long seq) { - return false; - } - - protected String getRouterControlIp(long routerId) { - String routerControlIpAddress = null; - List nics = _nicDao.listByVmId(routerId); - for (NicVO n : nics) { - NetworkVO nc = _networkDao.findById(n.getNetworkId()); - if (nc.getTrafficType() == TrafficType.Control) { - routerControlIpAddress = n.getIp4Address(); - } - } - - if(routerControlIpAddress == null) { - s_logger.warn("Unable to find router's control ip in its attached NICs!. routerId: " + routerId); - DomainRouterVO router = _routerDao.findById(routerId); - return router.getPrivateIpAddress(); - } - - return routerControlIpAddress; - } - - - protected String getRouterIpInNetwork(long networkId, long instanceId) { - return _nicDao.getIpAddress(networkId, instanceId); - } - - - @Override - public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - //not supported - throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); - } - - @Override - public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) - throws ConcurrentOperationException, ResourceUnavailableException { - //not supported - throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); - } - - @Override - public void prepareStop(VirtualMachineProfile profile){ - //Collect network usage before stopping Vm - VMInstanceVO vm = profile.getVirtualMachine(); - DomainRouterVO router = _routerDao.findById(vm.getId()); - if(router == null){ - return; - } - String privateIP = router.getPrivateIpAddress(); - - if (privateIP != null) { - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - - for (Long guestNtwkId : routerGuestNtwkIds) { - boolean forVpc = router.getVpcId() != null; - Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); - Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); - NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), - guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), - _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), - _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); - final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), - forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); - UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), - router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); - NetworkUsageAnswer answer = null; - try { - answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); - } catch (Exception e) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); - continue; - } - - if (answer != null) { - if (!answer.getResult()) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); - continue; - } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { - s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); - continue; - } - txn.start(); - UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), - router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - continue; - } - - if(previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) - || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + - "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + - answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); - continue; - } - - if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesReceived() - + " Stored: " + stats.getCurrentBytesReceived()); - } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answer.getBytesReceived()); - if (stats.getCurrentBytesSent() > answer.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesSent() - + " Stored: " + stats.getCurrentBytesSent()); - } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - } - stats.setCurrentBytesSent(answer.getBytesSent()); - _statsDao.update(stats.getId(), stats); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() - + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); - } finally { - txn.close(); - } - } - } - } - } - - @Override - public boolean recreateNeeded( - VirtualMachineProfile profile, long hostId, - Commands cmds, ReservationContext context) { - //asssume that if failed to ssh into router, meaning router is crashed - CheckSshAnswer answer = (CheckSshAnswer) cmds.getAnswer("checkSsh"); - if (answer == null || !answer.getResult()) { - return true; - } - - return false; - } -} +// 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.router; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.Listener; +import com.cloud.agent.api.AgentControlAnswer; +import com.cloud.agent.api.AgentControlCommand; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.BumpUpPriorityCommand; +import com.cloud.agent.api.CheckRouterAnswer; +import com.cloud.agent.api.CheckRouterCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetDomRVersionAnswer; +import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.ModifySshKeysCommand; +import com.cloud.agent.api.NetworkUsageAnswer; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.routing.DhcpEntryCommand; +import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; +import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.routing.VpnUsersCfgCommand; +import com.cloud.agent.api.to.FirewallRuleTO; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.alert.AlertManager; +import com.cloud.api.commands.UpgradeRouterCmd; +import com.cloud.cluster.ManagementServerHostVO; +import com.cloud.cluster.ManagementServerNode; +import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.ZoneConfig; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ConnectionException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +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.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.SshKeysDistriMonitor; +import com.cloud.network.VirtualNetworkApplianceService; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.VpnUser; +import com.cloud.network.VpnUserVO; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.FirewallRulesDao; +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.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.dao.VpnUserDao; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.RulesManager; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatImpl; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.UserStatsLogVO; +import com.cloud.user.UserVO; +import com.cloud.user.dao.UserDao; +import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.user.dao.UserStatsLogDao; +import com.cloud.uservm.UserVm; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.PasswordGenerator; +import com.cloud.utils.StringUtils; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.MacAddress; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineName; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmDetailsDao; + +/** + * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack. + */ +@Local(value = { VirtualNetworkApplianceManager.class, VirtualNetworkApplianceService.class }) +public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, + VirtualMachineGuru, Listener { + private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class); + + String _name; + @Inject + DataCenterDao _dcDao = null; + @Inject + VlanDao _vlanDao = null; + @Inject + FirewallRulesDao _rulesDao = null; + @Inject + LoadBalancerDao _loadBalancerDao = null; + @Inject + LoadBalancerVMMapDao _loadBalancerVMMapDao = null; + @Inject + IPAddressDao _ipAddressDao = null; + @Inject + VMTemplateDao _templateDao = null; + @Inject + DomainRouterDao _routerDao = null; + @Inject + UserDao _userDao = null; + @Inject + UserStatisticsDao _userStatsDao = null; + @Inject + HostDao _hostDao = null; + @Inject + ConfigurationDao _configDao; + @Inject + HostPodDao _podDao = null; + @Inject + UserStatsLogDao _userStatsLogDao = null; + @Inject + AgentManager _agentMgr; + @Inject + AlertManager _alertMgr; + @Inject + AccountManager _accountMgr; + @Inject + ConfigurationManager _configMgr; + @Inject + ServiceOfferingDao _serviceOfferingDao = null; + @Inject + UserVmDao _userVmDao; + @Inject + UserStatisticsDao _statsDao = null; + @Inject + NetworkOfferingDao _networkOfferingDao = null; + @Inject + GuestOSDao _guestOSDao = null; + @Inject + NetworkManager _networkMgr; + @Inject + VirtualMachineManager _itMgr; + @Inject + VpnUserDao _vpnUsersDao; + @Inject + RemoteAccessVpnDao _remoteAccessVpnDao; + @Inject + RulesManager _rulesMgr; + @Inject + NetworkDao _networkDao; + @Inject + LoadBalancingRulesManager _lbMgr; + @Inject + PortForwardingRulesDao _pfRulesDao; + @Inject + RemoteAccessVpnDao _vpnDao; + @Inject + NicDao _nicDao; + @Inject + VolumeDao _volumeDao = null; + @Inject + UserVmDetailsDao _vmDetailsDao; + @Inject + ClusterDao _clusterDao; + @Inject + ResourceManager _resourceMgr; + @Inject + PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Inject + VirtualRouterProviderDao _vrProviderDao; + @Inject + ManagementServerHostDao _msHostDao; + @Inject + Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; + @Inject + Site2SiteVpnGatewayDao _s2sVpnGatewayDao; + @Inject + Site2SiteVpnConnectionDao _s2sVpnConnectionDao; + + int _routerRamSize; + int _routerCpuMHz; + int _retry = 2; + String _instance; + String _mgmt_host; + String _mgmt_cidr; + + int _routerStatsInterval = 300; + int _routerCheckInterval = 30; + protected ServiceOfferingVO _offering; + private String _dnsBasicZoneUpdates = "all"; + + private boolean _disable_rp_filter = false; + int _routerExtraPublicNics = 2; + private int _usageAggregationRange = 1440; + private String _usageTimeZone = "GMT"; + private final long mgmtSrvrId = MacAddress.getMacAddress().toLong(); + private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds + + ScheduledExecutorService _executor; + ScheduledExecutorService _checkExecutor; + ScheduledExecutorService _networkStatsUpdateExecutor; + + Account _systemAcct; + + @Override + public boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey) { + ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey); + final Answer answer = _agentMgr.easySend(hostId, cmd); + + if (answer != null) { + return true; + } else { + return false; + } + } + + @Override + public VirtualRouter destroyRouter(final long routerId) throws ResourceUnavailableException, ConcurrentOperationException { + UserContext context = UserContext.current(); + User user = _accountMgr.getActiveUser(context.getCallerUserId()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Attempting to destroy router " + routerId); + } + + DomainRouterVO router = _routerDao.findById(routerId); + if (router == null) { + return null; + } + + _accountMgr.checkAccess(context.getCaller(), null, true, router); + + boolean result = _itMgr.expunge(router, user, _accountMgr.getAccount(router.getAccountId())); + + if (result) { + return router; + } + return null; + } + + @Override + @DB + public VirtualRouter upgradeRouter(UpgradeRouterCmd cmd) { + Long routerId = cmd.getId(); + Long serviceOfferingId = cmd.getServiceOfferingId(); + Account caller = UserContext.current().getCaller(); + + DomainRouterVO router = _routerDao.findById(routerId); + if (router == null) { + throw new InvalidParameterValueException("Unable to find router with id " + routerId); + } + + _accountMgr.checkAccess(caller, null, true, router); + + if (router.getServiceOfferingId() == serviceOfferingId) { + s_logger.debug("Router: " + routerId + "already has service offering: " + serviceOfferingId); + return _routerDao.findById(routerId); + } + + ServiceOffering newServiceOffering = _configMgr.getServiceOffering(serviceOfferingId); + if (newServiceOffering == null) { + throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId); + } + + // check if it is a system service offering, if yes return with error as it cannot be used for user vms + if (!newServiceOffering.getSystemUse()) { + throw new InvalidParameterValueException("Cannot upgrade router vm to a non system service offering " + serviceOfferingId); + } + + // Check that the router is stopped + if (!router.getState().equals(State.Stopped)) { + s_logger.warn("Unable to upgrade router " + router.toString() + " in state " + router.getState()); + throw new InvalidParameterValueException("Unable to upgrade router " + router.toString() + " in state " + router.getState() + + "; make sure the router is stopped and not in an error state before upgrading."); + } + + ServiceOfferingVO currentServiceOffering = _serviceOfferingDao.findById(router.getServiceOfferingId()); + + // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service + // offering + if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { + throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + + newServiceOffering.getUseLocalStorage() + " is different from " + + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage()); + } + + router.setServiceOfferingId(serviceOfferingId); + if (_routerDao.update(routerId, router)) { + return _routerDao.findById(routerId); + } else { + throw new CloudRuntimeException("Unable to upgrade router " + routerId); + } + + } + + @Override + public boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Unable save password, router doesn't exist in network " + network.getId()); + throw new CloudRuntimeException("Unable to save password to router"); + } + + UserVm userVm = profile.getVirtualMachine(); + String password = (String) profile.getParameter(Param.VmPassword); + String encodedPassword = PasswordGenerator.rot13(password); + DataCenter dc = _dcDao.findById(userVm.getDataCenterIdToDeployIn()); + + boolean result = true; + for (VirtualRouter router : routers) { + boolean sendPassword = true; + if (dc.getNetworkType() == NetworkType.Basic && userVm.getPodIdToDeployIn().longValue() != router.getPodIdToDeployIn().longValue()) { + sendPassword = false; + } + + if (sendPassword) { + Commands cmds = new Commands(OnError.Continue); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), userVm.getHostName()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("password", cmd); + + result = result && sendCommandsToRouter(router, cmds); + } + } + return result; + } + + @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true) + public VirtualRouter stopRouter(long routerId, boolean forced) throws ResourceUnavailableException, ConcurrentOperationException { + UserContext context = UserContext.current(); + Account account = context.getCaller(); + + // verify parameters + DomainRouterVO router = _routerDao.findById(routerId); + if (router == null) { + throw new InvalidParameterValueException("Unable to find router by id " + routerId + "."); + } + + _accountMgr.checkAccess(account, null, true, router); + + UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); + + VirtualRouter virtualRouter = stop(router, forced, user, account); + if(virtualRouter == null){ + throw new CloudRuntimeException("Failed to stop router with id " + routerId); + } + return virtualRouter; + } + + @DB + public void processStopOrRebootAnswer(final DomainRouterVO router, Answer answer) { + final Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNtwkId : routerGuestNtwkIds) { + final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), + guestNtwkId, null, router.getId(), router.getType().toString()); + if (userStats != null) { + final long currentBytesRcvd = userStats.getCurrentBytesReceived(); + userStats.setCurrentBytesReceived(0); + userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); + + final long currentBytesSent = userStats.getCurrentBytesSent(); + userStats.setCurrentBytesSent(0); + userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); + _userStatsDao.update(userStats.getId(), userStats); + s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); + } else { + s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn()); + } + } + + txn.commit(); + } catch (final Exception e) { + txn.rollback(); + throw new CloudRuntimeException("Problem updating stats after reboot/stop ", e); + } + } + + @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) + public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + Account caller = UserContext.current().getCaller(); + + // verify parameters + DomainRouterVO router = _routerDao.findById(routerId); + if (router == null) { + throw new InvalidParameterValueException("Unable to find domain router with id " + routerId + "."); + } + + _accountMgr.checkAccess(caller, null, true, router); + + // Can reboot domain router only in Running state + if (router == null || router.getState() != State.Running) { + s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); + throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), + DataCenter.class, router.getDataCenterIdToDeployIn()); + } + + UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); + s_logger.debug("Stopping and starting router " + router + " as a part of router reboot"); + + if (stop(router, false, user, caller) != null) { + return startRouter(routerId, reprogramNetwork); + } else { + throw new CloudRuntimeException("Failed to reboot router " + router); + } + } + + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _name = name; + + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterMonitor")); + _checkExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterStatusMonitor")); + _networkStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NetworkStatsUpdater")); + + final ComponentLocator locator = ComponentLocator.getCurrentLocator(); + + final Map configs = _configDao.getConfiguration("AgentManager", params); + + _mgmt_host = configs.get("host"); + _routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE); + _routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ); + + _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); + + String value = configs.get("start.retry"); + _retry = NumbersUtil.parseInt(value, 2); + + value = configs.get("router.stats.interval"); + _routerStatsInterval = NumbersUtil.parseInt(value, 300); + + value = configs.get("router.check.interval"); + _routerCheckInterval = NumbersUtil.parseInt(value, 30); + + _instance = configs.get("instance.name"); + if (_instance == null) { + _instance = "DEFAULT"; + } + + String rpValue = configs.get("network.disable.rpfilter"); + if (rpValue != null && rpValue.equalsIgnoreCase("true")) { + _disable_rp_filter = true; + } + + _dnsBasicZoneUpdates = String.valueOf(_configDao.getValue(Config.DnsBasicZoneUpdates.key())); + + s_logger.info("Router configurations: " + "ramsize=" + _routerRamSize); + + final UserStatisticsDao statsDao = locator.getDao(UserStatisticsDao.class); + if (statsDao == null) { + throw new ConfigurationException("Unable to get " + UserStatisticsDao.class.getName()); + } + + _agentMgr.registerForHostEvents(new SshKeysDistriMonitor(_agentMgr, _hostDao, _configDao), true, false, false); + _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this); + + boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); + _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, + null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); + _offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); + _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); + + // this can sometimes happen, if DB is manually or programmatically manipulated + if(_offering == null) { + String msg = "Data integrity problem : System Offering For Software router VM has been removed?"; + s_logger.error(msg); + throw new ConfigurationException(msg); + } + + _systemAcct = _accountMgr.getSystemAccount(); + + String aggregationRange = configs.get("usage.stats.job.aggregation.range"); + _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440); + _usageTimeZone = configs.get("usage.aggregation.timezone"); + if(_usageTimeZone == null){ + _usageTimeZone = "GMT"; + } + + _agentMgr.registerForHostEvents(this, true, false, false); + + s_logger.info("DomainRouterManager is configured."); + + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + if (_routerStatsInterval > 0){ + _executor.scheduleAtFixedRate(new NetworkUsageTask(), _routerStatsInterval, _routerStatsInterval, TimeUnit.SECONDS); + }else{ + s_logger.debug("router.stats.interval - " + _routerStatsInterval+ " so not scheduling the router stats thread"); + } + + //Schedule Network stats update task + TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone); + Calendar cal = Calendar.getInstance(usageTimezone); + cal.setTime(new Date()); + long endDate = 0; + int HOURLY_TIME = 60; + final int DAILY_TIME = 60 * 24; + if (_usageAggregationRange == DAILY_TIME) { + cal.roll(Calendar.DAY_OF_YEAR, false); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.roll(Calendar.DAY_OF_YEAR, true); + cal.add(Calendar.MILLISECOND, -1); + endDate = cal.getTime().getTime(); + } else if (_usageAggregationRange == HOURLY_TIME) { + cal.roll(Calendar.HOUR_OF_DAY, false); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.roll(Calendar.HOUR_OF_DAY, true); + cal.add(Calendar.MILLISECOND, -1); + endDate = cal.getTime().getTime(); + } else { + endDate = cal.getTime().getTime(); + } + + _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), + (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); + + if (_routerCheckInterval > 0) { + _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS); + } else { + s_logger.debug("router.check.interval - " + _routerCheckInterval+ " so not scheduling the redundant router checking thread"); + } + + return true; + } + + @Override + public boolean stop() { + return true; + } + + protected VirtualNetworkApplianceManagerImpl() { + } + + @Override + public Long convertToId(final String vmName) { + if (!VirtualMachineName.isValidRouterName(vmName, _instance)) { + return null; + } + + return VirtualMachineName.getRouterId(vmName); + } + + private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, + String serviceOffering, String zoneName, String guestIpAddress, String vmName, + String vmInstanceName, long vmId, String publicKey, long guestNetworkId) { + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmd.addVmData("userdata", "user-data", userData); + cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); + cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); + cmd.addVmData("metadata", "local-ipv4", guestIpAddress); + cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vmName)); + if (dcVo.getNetworkType() == NetworkType.Basic) { + cmd.addVmData("metadata", "public-ipv4", guestIpAddress); + cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName)); + } else + { + if (router.getPublicIpAddress() == null) { + cmd.addVmData("metadata", "public-ipv4", guestIpAddress); + } else { + cmd.addVmData("metadata", "public-ipv4", router.getPublicIpAddress()); + } + cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress()); + } + cmd.addVmData("metadata", "instance-id", vmInstanceName); + cmd.addVmData("metadata", "vm-id", String.valueOf(vmId)); + cmd.addVmData("metadata", "public-keys", publicKey); + + String cloudIdentifier = _configDao.getValue("cloud.identifier"); + if (cloudIdentifier == null) { + cloudIdentifier = ""; + } else { + cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}"; + } + cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier); + + return cmd; + } + + protected class NetworkUsageTask implements Runnable { + + public NetworkUsageTask() { + } + + @Override + public void run() { + try{ + final List routers = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Isolated, mgmtSrvrId); + s_logger.debug("Found " + routers.size() + " running routers. "); + + for (DomainRouterVO router : routers) { + String privateIP = router.getPrivateIpAddress(); + + if (privateIP != null) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long guestNtwkId : routerGuestNtwkIds) { + boolean forVpc = router.getVpcId() != null; + Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); + Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), + guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); + final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), + forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + NetworkUsageAnswer answer = null; + try { + answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); + continue; + } + + if (answer != null) { + if (!answer.getResult()) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + continue; + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { + s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + continue; + } + txn.start(); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + continue; + } + + if(previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + continue; + } + + if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answer.getBytesReceived()); + if (stats.getCurrentBytesSent() > answer.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answer.getBytesSent()); + _statsDao.update(stats.getId(), stats); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + } finally { + txn.close(); + } + } + } + } + } + } catch (Exception e) { + s_logger.warn("Error while collecting network stats", e); + } + } + } + + protected class NetworkStatsUpdateTask implements Runnable { + + public NetworkStatsUpdateTask() { + } + + @Override + public void run() { + GlobalLock scanLock = GlobalLock.getInternLock("network.stats"); + try { + if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { + //Check for ownership + //msHost in UP state with min id should run the job + ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L)); + if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){ + s_logger.debug("Skipping aggregate network stats update"); + scanLock.unlock(); + return; + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + txn.start(); + //get all stats with delta > 0 + List updatedStats = _statsDao.listUpdatedStats(); + Date updatedTime = new Date(); + for(UserStatisticsVO stat : updatedStats){ + //update agg bytes + stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived()); + stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent()); + _userStatsDao.update(stat.getId(), stat); + //insert into op_user_stats_log + UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat.getCurrentBytesReceived(), + stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime); + _userStatsLogDao.persist(statsLog); + } + s_logger.debug("Successfully updated aggregate network stats"); + txn.commit(); + } catch (Exception e){ + txn.rollback(); + s_logger.debug("Failed to update aggregate network stats", e); + } finally { + scanLock.unlock(); + txn.close(); + } + } + } catch (Exception e){ + s_logger.debug("Exception while trying to acquire network stats lock", e); + } finally { + scanLock.releaseRef(); + } + } + } + + + protected void updateRoutersRedundantState(List routers) { + boolean updated = false; + for (DomainRouterVO router : routers) { + updated = false; + if (!router.getIsRedundantRouter()) { + continue; + } + RedundantState prevState = router.getRedundantState(); + if (router.getState() != State.Running) { + router.setRedundantState(RedundantState.UNKNOWN); + router.setIsPriorityBumpUp(false); + updated = true; + } else { + String privateIP = router.getPrivateIpAddress(); + HostVO host = _hostDao.findById(router.getHostId()); + if (host == null || host.getStatus() != Status.Up) { + router.setRedundantState(RedundantState.UNKNOWN); + updated = true; + } else if (host.getManagementServerId() != ManagementServerNode.getManagementServerId()) { + /* Only cover hosts managed by this management server */ + continue; + } else if (privateIP != null) { + final CheckRouterCommand command = new CheckRouterCommand(); + command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + command.setWait(60); + final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command); + CheckRouterAnswer answer = null; + if (origAnswer instanceof CheckRouterAnswer) { + answer = (CheckRouterAnswer)origAnswer; + } else { + s_logger.warn("Unable to update router " + router.getHostName() + "'s status"); + } + RedundantState state = RedundantState.UNKNOWN; + boolean isBumped = router.getIsPriorityBumpUp(); + if (answer != null && answer.getResult()) { + state = answer.getState(); + isBumped = answer.isBumped(); + } + router.setRedundantState(state); + router.setIsPriorityBumpUp(isBumped); + updated = true; + } + } + if (updated) { + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + txn.start(); + _routerDao.update(router.getId(), router); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update router status for account: " + router.getAccountId()); + } finally { + txn.close(); + } + } + RedundantState currState = router.getRedundantState(); + if (prevState != currState) { + String title = "Redundant virtual router " + router.getInstanceName() + + " just switch from " + prevState + " to " + currState; + String context = "Redundant virtual router (name: " + router.getHostName() + ", id: " + router.getId() + ") " + + " just switch from " + prevState + " to " + currState; + s_logger.info(context); + if (currState == RedundantState.MASTER) { + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, + router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); + } + } + } + } + + //Ensure router status is update to date before execute this function. The function would try best to recover all routers except MASTER + protected void recoverRedundantNetwork(DomainRouterVO masterRouter, DomainRouterVO backupRouter) { + UserContext context = UserContext.current(); + context.setAccountId(1); + if (masterRouter.getState() == State.Running && backupRouter.getState() == State.Running) { + HostVO masterHost = _hostDao.findById(masterRouter.getHostId()); + HostVO backupHost = _hostDao.findById(backupRouter.getHostId()); + if (masterHost.getStatus() == Status.Up && backupHost.getStatus() == Status.Up) { + String title = "Reboot " + backupRouter.getInstanceName() + " to ensure redundant virtual routers work"; + if (s_logger.isDebugEnabled()) { + s_logger.debug(title); + } + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, + backupRouter.getDataCenterIdToDeployIn(), backupRouter.getPodIdToDeployIn(), title, title); + try { + rebootRouter(backupRouter.getId(), false); + } catch (ConcurrentOperationException e) { + s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); + } catch (ResourceUnavailableException e) { + s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); + } catch (InsufficientCapacityException e) { + s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e); + } + } + } + } + + private int getRealPriority(DomainRouterVO router) { + int priority = router.getPriority(); + if (router.getIsPriorityBumpUp()) { + priority += DEFAULT_DELTA; + } + return priority; + } + + protected class CheckRouterTask implements Runnable { + + public CheckRouterTask() { + } + + /* + * In order to make fail-over works well at any time, we have to ensure: + * 1. Backup router's priority = Master's priority - DELTA + 1 + * 2. Backup router's priority hasn't been bumped up. + */ + private void checkSanity(List routers) { + Set checkedNetwork = new HashSet(); + for (DomainRouterVO router : routers) { + if (!router.getIsRedundantRouter()) { + continue; + } + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { + if (checkedNetwork.contains(routerGuestNtwkId)) { + continue; + } + checkedNetwork.add(routerGuestNtwkId); + List checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER); + if (checkingRouters.size() != 2) { + continue; + } + DomainRouterVO masterRouter = null; + DomainRouterVO backupRouter = null; + for (DomainRouterVO r : checkingRouters) { + if (r.getRedundantState() == RedundantState.MASTER) { + if (masterRouter == null) { + masterRouter = r; + } else { + //Duplicate master! We give up, until the admin fix duplicate MASTER issue + break; + } + } else if (r.getRedundantState() == RedundantState.BACKUP) { + if (backupRouter == null) { + backupRouter = r; + } else { + break; + } + } + } + if (masterRouter != null && backupRouter != null) { + if (getRealPriority(masterRouter) - DEFAULT_DELTA + 1 != getRealPriority(backupRouter) || backupRouter.getIsPriorityBumpUp()) { + recoverRedundantNetwork(masterRouter, backupRouter); + } + } + } + } + } + + private void checkDuplicateMaster(List routers) { + Map networkRouterMaps = new HashMap(); + for (DomainRouterVO router : routers) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { + if (router.getRedundantState() == RedundantState.MASTER) { + if (networkRouterMaps.containsKey(routerGuestNtwkId)) { + DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId); + String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName(); + String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + + dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. "; + + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context); + } else { + networkRouterMaps.put(routerGuestNtwkId, router); + } + } + } + } + } + + @Override + public void run() { + try { + final List routers = _routerDao.listIsolatedByHostId(null); + s_logger.debug("Found " + routers.size() + " routers. "); + + updateRoutersRedundantState(routers); + + /* FIXME assumed the a pair of redundant routers managed by same mgmt server, + * then the update above can get the latest status */ + checkDuplicateMaster(routers); + checkSanity(routers); + } catch (Exception ex) { + s_logger.error("Fail to complete the CheckRouterTask! ", ex); + } + } + } + + + private final int DEFAULT_PRIORITY = 100; + private final int DEFAULT_DELTA = 2; + + protected int getUpdatedPriority(Network guestNetwork, List routers, DomainRouterVO exclude) throws InsufficientVirtualNetworkCapcityException { + int priority; + if (routers.size() == 0) { + priority = DEFAULT_PRIORITY; + } else { + int maxPriority = 0; + for (DomainRouterVO r : routers) { + if (!r.getIsRedundantRouter()) { + throw new CloudRuntimeException("Redundant router is mixed with single router in one network!"); + } + //FIXME Assume the maxPriority one should be running or just created. + if (r.getId() != exclude.getId() && getRealPriority(r) > maxPriority) { + maxPriority = getRealPriority(r); + } + } + if (maxPriority == 0) { + return DEFAULT_PRIORITY; + } + if (maxPriority < 20) { + s_logger.error("Current maximum priority is too low!"); + throw new InsufficientVirtualNetworkCapcityException("Current maximum priority is too low as " + maxPriority + "!", + guestNetwork.getId()); + } else if (maxPriority > 200) { + s_logger.error("Too many times fail-over happened! Current maximum priority is too high as " + maxPriority + "!"); + throw new InsufficientVirtualNetworkCapcityException("Too many times fail-over happened! Current maximum priority is too high as " + + maxPriority + "!", guestNetwork.getId()); + } + priority = maxPriority - DEFAULT_DELTA + 1; + } + return priority; + } + + /* + * Ovm won't support any system. So we have to choose a partner cluster in the same pod to start domain router for us + */ + private HypervisorType getClusterToStartDomainRouterForOvm(long podId) { + List clusters = _clusterDao.listByPodId(podId); + for (ClusterVO cv : clusters) { + if (cv.getHypervisorType() == HypervisorType.Ovm || cv.getHypervisorType() == HypervisorType.BareMetal) { + continue; + } + + List hosts = _resourceMgr.listAllHostsInCluster(cv.getId()); + if (hosts == null || hosts.isEmpty()) { + continue; + } + + for (HostVO h : hosts) { + if (h.getStatus() == Status.Up) { + s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + + cv.getId() + " to start domain router for OVM"); + return h.getHypervisorType(); + } + } + } + + String errMsg = "Cannot find an available cluster in Pod " + + podId + + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, " + + "please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod" + + " with Ovm cluster. And there is at least one host in UP status in that cluster."; + throw new CloudRuntimeException(errMsg); + } + + @DB + protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + boolean isRedundant, Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + 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.getTrafficType() == TrafficType.Guest; + + + + //1) Get deployment plan and find out the list of routers + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || + _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) + && guestNetwork.getTrafficType() == TrafficType.Guest; + + Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + + //2) Figure out required routers count + int routerCount = 1; + if (isRedundant) { + routerCount = 2; + } + + /* If it is the single router network, then keep it untouched */ + for (DomainRouterVO router : routers) { + if (!router.getIsRedundantRouter() || isPodBased) { + routerCount = 1; + break; + } + } + + /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ + if (routers.size() >= routerCount) { + return routers; + } + + if (routers.size() >= 5) { + s_logger.error("Too much redundant routers!"); + } + + Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); + if (network == null) { + throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); + } + + try { + //Check if providers are supported in the physical networks + VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); + } + + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } + + //Check if public network has to be set on VR + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { + publicNetwork = true; + } + if (isRedundant && !publicNetwork) { + s_logger.error("Didn't support redundant virtual router without public network!"); + return null; + } + + Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + + PublicIp sourceNatIp = null; + if (publicNetwork) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + } + + //3) deploy virtual router(s) + int count = routerCount - routers.size(); + for (int i = 0; i < count; i++) { + List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, + new Pair(publicNetwork, sourceNatIp)); + DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, + null, networks); + + _routerDao.addRouterToGuestNetwork(router, network); + + routers.add(router); + } + } finally { + if (network != null) { + _networkDao.releaseFromLockTable(network.getId()); + } + } + return routers; + } + + protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, + Long vpcId, List> networks) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + long id = _routerDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the router " + id + " in datacenter " + dest.getDataCenter()); + } + + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); + + // Router is the network element, we don't know the hypervisor type yet. + //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up + List supportedHypervisors = new ArrayList(); + HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); + if (defaults != HypervisorType.None) { + supportedHypervisors.add(defaults); + } + + if (dest.getCluster() != null) { + if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { + supportedHypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); + } else { + supportedHypervisors.add(dest.getCluster().getHypervisorType()); + } + } else { + supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); + } + + if (supportedHypervisors.isEmpty()) { + if (plan.getPodId() != null) { + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the pod ", Pod.class, plan.getPodId()); + } + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + } + + int allocateRetry = 0; + int startRetry = 0; + DomainRouterVO router = null; + for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { + HypervisorType hType = iter.next(); + try { + s_logger.debug("Allocating the domR with the hypervisor type " + hType); + VMTemplateVO template = _templateDao.findRoutingTemplate(hType); + + if (template == null) { + s_logger.debug(hType + " won't support system vm, skip it"); + continue; + } + + boolean offerHA = routerOffering.getOfferHA(); + /* We don't provide HA to redundant router VMs, admin should own it all, and redundant router themselves are HA */ + if (isRedundant) { + offerHA = false; + } + + router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), + VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), isRedundant, 0, false, + RedundantState.UNKNOWN, offerHA, false, vpcId); + router.setRole(Role.VIRTUAL_ROUTER); + router = _itMgr.allocate(router, template, routerOffering, networks, plan, null, owner); + } catch (InsufficientCapacityException ex) { + if (allocateRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to allocate the domR with hypervisor type " + hType + ", retrying one more time"); + continue; + } else { + throw ex; + } + } finally { + allocateRetry++; + } + + try { + router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); + break; + } catch (InsufficientCapacityException ex) { + if (startRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", " + + "destroying it and recreating one more time"); + //destroy the router + destroyRouter(router.getId()); + continue; + } else { + throw ex; + } + } finally { + startRetry++; + } + } + + return router; + } + + protected List> createRouterNetworks(Account owner, boolean isRedundant, + DeploymentPlan plan, Network guestNetwork, Pair publicNetwork) throws ConcurrentOperationException, + InsufficientAddressCapacityException { + + + boolean setupPublicNetwork = false; + if (publicNetwork != null) { + setupPublicNetwork = publicNetwork.first(); + } + + //Form networks + List> networks = new ArrayList>(3); + + //1) Guest network + boolean hasGuestNetwork = false; + if (guestNetwork != null) { + s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); + String defaultNetworkStartIp = null; + if (guestNetwork.getCidr() != null && !setupPublicNetwork) { + String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); + if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { + defaultNetworkStartIp = startIp; + } else if (s_logger.isDebugEnabled()){ + s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ip address from the range"); + } + } + + NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); + if (setupPublicNetwork) { + if (isRedundant) { + gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); + } else { + gatewayNic.setIp4Address(guestNetwork.getGateway()); + } + gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); + gatewayNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + } else { + gatewayNic.setDefaultNic(true); + } + + networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); + hasGuestNetwork = true; + } + + //2) Control network + s_logger.debug("Adding nic for Virtual Router in Control network "); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); + NetworkOfferingVO controlOffering = offerings.get(0); + NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + networks.add(new Pair(controlConfig, null)); + + + //3) Public network + if (setupPublicNetwork) { + PublicIp sourceNatIp = publicNetwork.second(); + s_logger.debug("Adding nic for Virtual Router in Public network "); + //if source nat service is supported by the network, get the source nat ip address + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); + defaultNic.setGateway(sourceNatIp.getGateway()); + defaultNic.setNetmask(sourceNatIp.getNetmask()); + defaultNic.setMacAddress(sourceNatIp.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + if (hasGuestNetwork) { + defaultNic.setDeviceId(2); + } + NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); + List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); + networks.add(new Pair(publicNetworks.get(0), defaultNic)); + } + + return networks; + } + + + protected Pair> getDeploymentPlanAndRouters(boolean isPodBased, + DeployDestination dest, long guestNetworkId) { + long dcId = dest.getDataCenter().getId(); + List routers = null; + DeploymentPlan plan = new DataCenterDeployment(dcId); + if (isPodBased) { + Pod pod = dest.getPod(); + Long podId = null; + if (pod != null) { + podId = pod.getId(); + } else { + throw new CloudRuntimeException("Pod id is expected in deployment destination"); + } + routers = _routerDao.listByNetworkAndPodAndRole(guestNetworkId, podId, Role.VIRTUAL_ROUTER); + plan = new DataCenterDeployment(dcId, podId, null, null, null, null); + } else { + routers = _routerDao.listByNetworkAndRole(guestNetworkId, Role.VIRTUAL_ROUTER); + } + + return new Pair>(plan, routers); + } + + + private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) + throws StorageUnavailableException, InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { + return this.start(router, user, caller, params, null); + } + + if (router.getState() == State.Running) { + s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!"); + return router; + } + + DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); + DomainRouterVO result = null; + assert router.getIsRedundantRouter(); + List routerList = _routerDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn()); + DomainRouterVO routerToBeAvoid = null; + for (DomainRouterVO rrouter : routerList) { + if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) { + if (routerToBeAvoid != null) { + throw new ResourceUnavailableException("Try to start router " + router.getInstanceName() + "(" + router.getId() + ")" + + ", but there are already two redundant routers with IP " + router.getPublicIpAddress() + + ", they are " + rrouter.getInstanceName() + "(" + rrouter.getId() + ") and " + + routerToBeAvoid.getInstanceName() + "(" + routerToBeAvoid.getId() + ")", + DataCenter.class, rrouter.getDataCenterIdToDeployIn()); + } + routerToBeAvoid = rrouter; + } + } + if (routerToBeAvoid == null) { + return this.start(router, user, caller, params, null); + } + // We would try best to deploy the router to another place + int retryIndex = 5; + ExcludeList[] avoids = new ExcludeList[5]; + avoids[0] = new ExcludeList(); + avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn()); + avoids[1] = new ExcludeList(); + avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId()); + avoids[2] = new ExcludeList(); + List volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Type.ROOT); + if (volumes != null && volumes.size() != 0) { + avoids[2].addPool(volumes.get(0).getPoolId()); + } + avoids[2].addHost(routerToBeAvoid.getHostId()); + avoids[3] = new ExcludeList(); + avoids[3].addHost(routerToBeAvoid.getHostId()); + avoids[4] = new ExcludeList(); + + for (int i = 0; i < retryIndex; i++) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Try to deploy redundant virtual router:" + router.getHostName() + ", for " + i + " time"); + } + plan.setAvoids(avoids[i]); + try { + result = this.start(router, user, caller, params, plan); + } catch (InsufficientServerCapacityException ex) { + result = null; + } + if (result != null) { + break; + } + } + return result; + } + + @Override + public List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + Map params, boolean isRedundant) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + List routers = findOrDeployVirtualRouterInGuestNetwork + (guestNetwork, dest, owner, isRedundant, params); + + return startRouters(params, routers); + } + + protected List startRouters(Map params, List routers) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException { + List runningRouters = null; + + if (routers != null) { + runningRouters = new ArrayList(); + } + + for (DomainRouterVO router : routers) { + boolean skip = false; + State state = router.getState(); + if (router.getHostId() != null && state != State.Running) { + HostVO host = _hostDao.findById(router.getHostId()); + if (host == null || host.getStatus() != Status.Up) { + skip = true; + } + } + if (!skip) { + if (state != State.Running) { + router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); + } + if (router != null) { + runningRouters.add(router); + } + } + } + return runningRouters; + } + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, + ReservationContext context) { + + boolean dnsProvided = true; + boolean dhcpProvided = true; + boolean publicNetwork = false; + DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); + _dcDao.loadDetails(dc); + + //1) Set router details + DomainRouterVO router = profile.getVirtualMachine(); + Map details = _vmDetailsDao.findDetails(router.getId()); + router.setDetails(details); + + //2) Prepare boot loader elements related with Control network + + StringBuilder buf = profile.getBootArgsBuilder(); + buf.append(" template=domP"); + buf.append(" name=").append(profile.getHostName()); + + if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { + buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); + } + + NicProfile controlNic = null; + String defaultDns1 = null; + String defaultDns2 = null; + for (NicProfile nic : profile.getNics()) { + int deviceId = nic.getDeviceId(); + buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); + buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + + if (nic.isDefaultNic()) { + buf.append(" gateway=").append(nic.getGateway()); + defaultDns1 = nic.getDns1(); + defaultDns2 = nic.getDns2(); + } + + if (nic.getTrafficType() == TrafficType.Management) { + buf.append(" localgw=").append(dest.getPod().getGateway()); + } else if (nic.getTrafficType() == TrafficType.Control) { + controlNic = nic; + // DOMR control command is sent over management server in VMware + if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmt_host); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Add management server explicit route to DomR."); + } + + // always add management explicit route, for basic networking setup, DomR may have two interfaces while both + // are on the same subnet + _mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key()); + if (NetUtils.isValidCIDR(_mgmt_cidr)) { + buf.append(" mgmtcidr=").append(_mgmt_cidr); + buf.append(" localgw=").append(dest.getPod().getGateway()); + } + + + if (dc.getNetworkType() == NetworkType.Basic) { + // ask domR to setup SSH on guest network + buf.append(" sshonguest=true"); + } + + } + } else if (nic.getTrafficType() == TrafficType.Guest) { + dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter); + dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter); + //build bootloader parameter for the guest + buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router)); + } else if (nic.getTrafficType() == TrafficType.Public) { + publicNetwork = true; + } + } + + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); + } + + String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); + if (rpValue != null && rpValue.equalsIgnoreCase("true")) { + _disable_rp_filter = true; + }else { + _disable_rp_filter = false; + } + + String rpFilter = " "; + String type = null; + if (router.getVpcId() != null) { + type = "vpcrouter"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + } else if (!publicNetwork) { + type = "dhcpsrvr"; + } else { + type = "router"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + } + + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + + buf.append(" type=" + type + rpFilter); + + String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName()); + if (domain_suffix != null) { + buf.append(" dnssearchorder=").append(domain_suffix); + } + + if (profile.getHypervisorType() == HypervisorType.VMware) { + buf.append(" extra_pubnics=" + _routerExtraPublicNics); + } + + /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response + * to return DNS server rather than + * virtual router itself. */ + if (dnsProvided || dhcpProvided) { + if (defaultDns1 != null) { + buf.append(" dns1=").append(defaultDns1); + } + if (defaultDns2 != null) { + buf.append(" dns2=").append(defaultDns2); + } + + boolean useExtDns = !dnsProvided; + /* For backward compatibility */ + String use_external_dns = _configDao.getValue(Config.UseExternalDnsServers.key()); + if (use_external_dns != null && use_external_dns.equals("true")) { + useExtDns = true; + } + + if (useExtDns) { + buf.append(" useextdns=true"); + } + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); + } + + return true; + } + + + protected StringBuilder createGuestBootLoadArgs(NicProfile guestNic, String defaultDns1, + String defaultDns2, DomainRouterVO router) { + long guestNetworkId = guestNic.getNetworkId(); + NetworkVO guestNetwork = _networkDao.findById(guestNetworkId); + String dhcpRange = null; + DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId()); + + StringBuilder buf = new StringBuilder(); + + boolean isRedundant = router.getIsRedundantRouter(); + if (isRedundant) { + buf.append(" redundant_router=1"); + List routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); + try { + int priority = getUpdatedPriority(guestNetwork, routers, router); + router.setPriority(priority); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.error("Failed to get update priority!", e); + throw new CloudRuntimeException("Failed to get update priority!"); + } + Network net = _networkMgr.getNetwork(guestNic.getNetworkId()); + buf.append(" guestgw=").append(net.getGateway()); + String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); + buf.append(" guestbrd=").append(brd); + buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getNetmask())); + buf.append(" router_pr=").append(router.getPriority()); + } + + //setup network domain + String domain = guestNetwork.getNetworkDomain(); + if (domain != null) { + buf.append(" domain=" + domain); + } + + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + if (guestNic.isDefaultNic()) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + + if (dhcpRange != null) { + buf.append(" dhcprange=" + dhcpRange); + } + + return buf; + } + + + protected String getGuestDhcpRange(NicProfile guestNic, Network guestNetwork, DataCenter dc) { + String dhcpRange = null; + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + return dhcpRange; + } + + @Override + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + DomainRouterVO router = profile.getVirtualMachine(); + + List nics = profile.getNics(); + for (NicProfile nic : nics) { + if (nic.getTrafficType() == TrafficType.Public) { + router.setPublicIpAddress(nic.getIp4Address()); + router.setPublicNetmask(nic.getNetmask()); + router.setPublicMacAddress(nic.getMacAddress()); + } else if (nic.getTrafficType() == TrafficType.Control) { + router.setPrivateIpAddress(nic.getIp4Address()); + router.setPrivateMacAddress(nic.getMacAddress()); + } + } + _routerDao.update(router.getId(), router); + + finalizeCommandsOnStart(cmds, profile); + return true; + } + + @Override + public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + DomainRouterVO router = profile.getVirtualMachine(); + NicProfile controlNic = getControlNic(profile); + + if (controlNic == null) { + s_logger.error("Control network doesn't exist for the router " + router); + return false; + } + + finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic); + + // restart network if restartNetwork = false is not specified in profile parameters + boolean reprogramGuestNtwks = true; + if (profile.getParameter(Param.ReProgramGuestNetworks) != null + && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { + reprogramGuestNtwks = false; + } + + VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName()); + } + Provider provider = Network.Provider.getProvider(vrProvider.getType().toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); + } + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNetworkId : routerGuestNtwkIds) { + if (reprogramGuestNtwks) { + finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId); + finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); + } + + finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); + } + + return true; + } + + protected NicProfile getControlNic(VirtualMachineProfile profile) { + DomainRouterVO router = profile.getVirtualMachine(); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + NicProfile controlNic = null; + if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { + // TODO this is a ugly to test hypervisor type here + // for basic network mode, we will use the guest NIC for control NIC + for (NicProfile nic : profile.getNics()) { + if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { + controlNic = nic; + } + } + } else { + for (NicProfile nic : profile.getNics()) { + if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { + controlNic = nic; + } + } + } + return controlNic; + } + + protected void finalizeSshAndVersionAndNetworkUsageOnStart(Commands cmds, VirtualMachineProfile profile, DomainRouterVO router, NicProfile controlNic) { + cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); + + // Update router template/scripts version + final GetDomRVersionCmd command = new GetDomRVersionCmd(); + command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIp4Address()); + command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmds.addCommand("getDomRVersion", command); + + // Network usage command to create iptables rules + boolean forVpc = profile.getVirtualMachine().getVpcId() != null; + cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); + } + + protected void finalizeUserDataAndDhcpOnStart(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) { + // Resend dhcp + s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start..."); + createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId); + } + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) { + // Resend user data + s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start..."); + createVmDataCommandForVMs(router, cmds, guestNetworkId); + } + } + + protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { + s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + List vpns = new ArrayList(); + List pfRules = new ArrayList(); + List staticNatFirewallRules = new ArrayList(); + List staticNats = new ArrayList(); + List firewallRules = new ArrayList(); + + //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) + for (PublicIpAddress ip : publicIps) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) { + pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); + } + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { + staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); + } + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall)); + } + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) { + RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); + if (vpn != null) { + vpns.add(vpn); + } + } + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { + if (ip.isOneToOneNat()) { + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId); + StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false); + staticNats.add(staticNat); + } + } + } + + //Re-apply static nats + s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); + if (!staticNats.isEmpty()) { + createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId); + } + + //Re-apply firewall rules + s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start."); + if (!firewallRules.isEmpty()) { + createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId); + } + + // Re-apply port forwarding rules + s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start."); + if (!pfRules.isEmpty()) { + createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId); + } + + // Re-apply static nat rules + s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start."); + if (!staticNatFirewallRules.isEmpty()) { + List staticNatRules = new ArrayList(); + for (FirewallRule rule : staticNatFirewallRules) { + staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); + } + createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); + } + + // Re-apply vpn rules + s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start."); + if (!vpns.isEmpty()) { + for (RemoteAccessVpn vpn : vpns) { + createApplyVpnCommands(vpn, router, cmds); + } + } + + List lbs = _loadBalancerDao.listByNetworkId(guestNetworkId); + List lbRules = new ArrayList(); + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) { + // Re-apply load balancing rules + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + lbRules.add(loadBalancing); + } + } + + s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start."); + if (!lbRules.isEmpty()) { + createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId); + } + } + } + + protected void finalizeIpAssocForNetwork(Commands cmds, VirtualRouter router, Provider provider, + Long guestNetworkId) { + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); + // Re-apply public ip addresses - should come before PF/LB/VPN + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + createAssociateIPCommands(router, publicIps, cmds, 0); + } + } + } + + protected ArrayList getPublicIpsToApply(VirtualRouter router, Provider provider, + Long guestNetworkId, com.cloud.network.IpAddress.State... skipInStates) { + long ownerId = router.getAccountId(); + final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); + List allPublicIps = new ArrayList(); + if (userIps != null && !userIps.isEmpty()) { + boolean addIp = true; + for (IPAddressVO userIp : userIps) { + if (skipInStates != null) { + for (IpAddress.State stateToSkip : skipInStates) { + if (userIp.getState() == stateToSkip) { + s_logger.debug("Skipping ip address " + userIp + " in state " + userIp.getState()); + addIp = false; + break; + } + } + } + + if (addIp) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + allPublicIps.add(publicIp); + } + } + } + + //Get public Ips that should be handled by router + Network network = _networkDao.findById(guestNetworkId); + Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); + Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); + // Only cover virtual router for now, if ELB use it this need to be modified + + ArrayList publicIps = providerToIpList.get(provider); + return publicIps; + } + + @Override + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, + ReservationContext context) { + DomainRouterVO router = profile.getVirtualMachine(); + + boolean result = true; + + Answer answer = cmds.getAnswer("checkSsh"); + if (answer != null && answer instanceof CheckSshAnswer) { + CheckSshAnswer sshAnswer = (CheckSshAnswer) answer; + if (sshAnswer == null || !sshAnswer.getResult()) { + s_logger.warn("Unable to ssh to the VM: " + sshAnswer.getDetails()); + result = false; + } + } else { + result = false; + } + if (result == false) { + return result; + } + + //Get guest networks info + List guestNetworks = new ArrayList(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNetworks.add(network); + } + } + + answer = cmds.getAnswer("getDomRVersion"); + if (answer != null && answer instanceof GetDomRVersionAnswer) { + GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + + " due to: " + versionAnswer.getDetails()); + result = false; + } else { + router.setTemplateVersion(versionAnswer.getTemplateVersion()); + router.setScriptsVersion(versionAnswer.getScriptsVersion()); + router = _routerDao.persist(router, guestNetworks); + } + } else { + result = false; + } + + return result; + } + + @Override + public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { + if (answer != null) { + VMInstanceVO vm = profile.getVirtualMachine(); + DomainRouterVO domR = _routerDao.findById(vm.getId()); + processStopOrRebootAnswer(domR, answer); + } + } + + @Override + public void finalizeExpunge(DomainRouterVO vm) { + } + + + @Override + public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Failed to start remote access VPN: no router found for account and zone"); + throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", + DataCenter.class, network.getDataCenterId()); + } + + for (VirtualRouter router : routers) { + if (router.getState() != State.Running) { + s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState()); + throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); + } + + Commands cmds = new Commands(OnError.Stop); + createApplyVpnCommands(vpn, router, cmds); + + try { + _agentMgr.send(router.getHostId(), cmds); + } catch (OperationTimedoutException e) { + s_logger.debug("Failed to start remote access VPN: ", e); + throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); + } + Answer answer = cmds.getAnswer("users"); + if (!answer.getResult()) { + s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + + " due to " + answer.getDetails()); + throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); + } + answer = cmds.getAnswer("startVpn"); + if (!answer.getResult()) { + s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + + answer.getDetails()); + throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); + } + + } + return true; + } + + + @Override + public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Failed to delete remote access VPN: no router found for account and zone"); + throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId()); + } + + boolean result = true; + for (VirtualRouter router : routers) { + if (router.getState() == State.Running) { + Commands cmds = new Commands(OnError.Continue); + IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); + + RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand(removeVpnCmd); + + result = result && sendCommandsToRouter(router, cmds); + } else if (router.getState() == State.Stopped) { + s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it"); + continue; + } else { + s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState()); + throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); + } + } + + return result; + } + + + private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) + throws StorageUnavailableException, InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + s_logger.debug("Starting router " + router); + if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { + return _routerDao.findById(router.getId()); + } else { + return null; + } + } + + @Override + public DomainRouterVO stop(VirtualRouter router, boolean forced, User user, Account caller) throws ConcurrentOperationException, ResourceUnavailableException { + s_logger.debug("Stopping router " + router); + try { + if (_itMgr.advanceStop((DomainRouterVO) router, forced, user, caller)) { + return _routerDao.findById(router.getId()); + } else { + return null; + } + } catch (OperationTimedoutException e) { + throw new CloudRuntimeException("Unable to stop " + router, e); + } + } + + @Override + public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, + DeployDestination dest, List routers) + throws ResourceUnavailableException { + _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); + + final VirtualMachineProfile updatedProfile = profile; + final boolean isZoneBasic = (dest.getDataCenter().getNetworkType() == NetworkType.Basic); + final Long podId = isZoneBasic ? dest.getPod().getId() : null; + + boolean podLevelException = false; + //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + podLevelException = true; + } + + return applyRules(network, routers, "dhcp entry", podLevelException, podId, true, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + //for basic zone, send dhcp/dns information to all routers in the basic network only when _dnsBasicZoneUpdates is set to "all" value + Commands cmds = new Commands(OnError.Stop); + if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod"))) { + NicVO nicVo = _nicDao.findById(nic.getId()); + createDhcpEntryCommand(router, updatedProfile.getVirtualMachine(), nicVo, cmds); + return sendCommandsToRouter(router, cmds); + } + return true; + } + }); + } + + private String findDefaultDnsIp(long userVmId) { + NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId); + + //check if DNS provider is the domR + if (!_networkMgr.isProviderSupportServiceInNetwork(defaultNic.getNetworkId(), Service.Dns, Provider.VirtualRouter)) { + return null; + } + + NetworkOfferingVO offering = _networkOfferingDao.findById(_networkDao.findById(defaultNic.getNetworkId()).getNetworkOfferingId()); + if (offering.getRedundantRouter()) { + return findGatewayIp(userVmId); + } + + //find domR's nic in the network + NicVO domrDefaultNic = _nicDao.findByNetworkIdAndType(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter); + return domrDefaultNic.getIp4Address(); + } + + private String findGatewayIp(long userVmId) { + NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId); + return defaultNic.getGateway(); + } + + @Override + public boolean applyUserData(Network network, final NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, List routers) + throws ResourceUnavailableException { + _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); + + final VirtualMachineProfile updatedProfile = profile; + final boolean isZoneBasic = (dest.getDataCenter().getNetworkType() == NetworkType.Basic); + final Long podId = isZoneBasic ? dest.getPod().getId() : null; + + boolean podLevelException = false; + //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + podLevelException = true; + } + + return applyRules(network, routers, "userdata and password entry", podLevelException, podId, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + //for basic zone, send vm data/password information only to the router in the same pod + Commands cmds = new Commands(OnError.Stop); + if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue())) { + NicVO nicVo = _nicDao.findById(nic.getId()); + createPasswordCommand(router, updatedProfile, nicVo, cmds); + createVmDataCommand(router, updatedProfile.getVirtualMachine(), nicVo, updatedProfile.getVirtualMachine().getDetail("SSH.PublicKey"), cmds); + return sendCommandsToRouter(router, cmds); + } + return true; + } + }); + } + + @Override + public DomainRouterVO persist(DomainRouterVO router) { + DomainRouterVO virtualRouter = _routerDao.persist(router); + return virtualRouter; + } + + @Override + //FIXME add partial success and STOP state support + public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + + network.getId(), DataCenter.class, network.getDataCenterId()); + } + + boolean agentResults = true; + + for (DomainRouterVO router : routers) { + if (router.getState() != State.Running) { + s_logger.warn("Failed to add/remove VPN users: router not in running state"); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); + } + + Commands cmds = new Commands(OnError.Continue); + List addUsers = new ArrayList(); + List removeUsers = new ArrayList(); + for (VpnUser user : users) { + if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) { + addUsers.add(user); + } else if (user.getState() == VpnUser.State.Revoke) { + removeUsers.add(user); + } + } + + VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers); + cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); + cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand(cmd); + + + // Currently we receive just one answer from the agent. In the future we have to parse individual answers and set + // results accordingly + boolean agentResult = sendCommandsToRouter(router, cmds); + agentResults = agentResults && agentResult; + } + + String[] result = new String[users.size()]; + for (int i = 0; i < result.length; i++) { + if (agentResults) { + result[i] = null; + } else { + result[i] = String.valueOf(agentResults); + } + } + + return result; + } + + @Override + public DomainRouterVO findById(long id) { + return _routerDao.findById(id); + } + + @Override + public DomainRouterVO findByName(String name) { + if (!VirtualMachineName.isValidRouterName(name)) { + return null; + } + + return _routerDao.findById(VirtualMachineName.getRouterId(name)); + } + + @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "starting router Vm", async = true) + public VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException{ + return startRouter(id, true); + } + + @Override + public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, + InsufficientCapacityException, ConcurrentOperationException { + Account caller = UserContext.current().getCaller(); + User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + + // verify parameters + DomainRouterVO router = _routerDao.findById(routerId); + if (router == null) { + throw new InvalidParameterValueException("Unable to find router by id " + routerId + "."); + } + _accountMgr.checkAccess(caller, null, true, router); + + Account owner = _accountMgr.getAccount(router.getAccountId()); + + // Check if all networks are implemented for the domR; if not - implement them + DataCenter dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); + HostPodVO pod = null; + if (router.getPodIdToDeployIn() != null) { + pod = _podDao.findById(router.getPodIdToDeployIn()); + } + DeployDestination dest = new DeployDestination(dc, pod, null, null); + + ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner); + + List nics = _nicDao.listByVmId(routerId); + + for (NicVO nic : nics) { + if (!_networkMgr.startNetwork(nic.getNetworkId(), dest, context)) { + s_logger.warn("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start"); + throw new CloudRuntimeException("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start"); + } + } + + UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); + Map params = new HashMap(); + if (reprogramNetwork) { + params.put(Param.ReProgramGuestNetworks, true); + } else { + params.put(Param.ReProgramGuestNetworks, false); + } + VirtualRouter virtualRouter = startVirtualRouter(router, user, caller, params); + if(virtualRouter == null){ + throw new CloudRuntimeException("Failed to start router with id " + routerId); + } + return virtualRouter; + } + + private void createAssociateIPCommands(final VirtualRouter router, final List ips, Commands cmds, long vmId) { + + // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc.. + Map> vlanIpMap = new HashMap>(); + for (final PublicIpAddress ipAddress : ips) { + String vlanTag = ipAddress.getVlanTag(); + ArrayList ipList = vlanIpMap.get(vlanTag); + if (ipList == null) { + ipList = new ArrayList(); + } + //domR doesn't support release for sourceNat IP address; so reset the state + if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) { + ipAddress.setState(IpAddress.State.Allocated); + } + ipList.add(ipAddress); + vlanIpMap.put(vlanTag, ipList); + } + + for (Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { + List ipAddrList = vlanAndIp.getValue(); + // Source nat ip address should always be sent first + Collections.sort(ipAddrList, new Comparator() { + @Override + public int compare(PublicIpAddress o1, PublicIpAddress o2) { + boolean s1 = o1.isSourceNat(); + boolean s2 = o2.isSourceNat(); + return (s1 ^ s2) ? ((s1 ^ true) ? 1 : -1) : 0; + } + }); + + // Get network rate - required for IpAssoc + Integer networkRate = _networkMgr.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); + Network network = _networkMgr.getNetwork(ipAddrList.get(0).getNetworkId()); + + IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; + int i = 0; + boolean firstIP = true; + + for (final PublicIpAddress ipAddr : ipAddrList) { + + boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); + boolean sourceNat = ipAddr.isSourceNat(); + /* enable sourceNAT for the first ip of the public interface */ + if (firstIP) { + sourceNat = true; + } + String vlanId = ipAddr.getVlanTag(); + String vlanGateway = ipAddr.getGateway(); + String vlanNetmask = ipAddr.getNetmask(); + String vifMacAddress = ipAddr.getMacAddress(); + + String vmGuestAddress = null; + + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, + sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); + + ip.setTrafficType(network.getTrafficType()); + ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); + ipsToSend[i++] = ip; + /* send the firstIP = true for the first Add, this is to create primary on interface*/ + if (!firstIP || add) { + firstIP = false; + } + } + IpAssocCommand cmd = new IpAssocCommand(ipsToSend); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("IPAssocCommand", cmd); + } + } + + private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (PortForwardingRule rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, sourceIp.getAddress().addr()); + rulesTO.add(ruleTO); + } + } + + SetPortForwardingRulesCommand cmd = null; + + if (router.getVpcId() != null) { + cmd = new SetPortForwardingRulesVpcCommand(rulesTO); + } else { + cmd = new SetPortForwardingRulesCommand(rulesTO); + } + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand(cmd); + } + + private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (StaticNatRule rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getDestIpAddress()); + rulesTO.add(ruleTO); + } + } + + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { + + LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; + int i = 0; + for (LoadBalancingRule rule : rules) { + boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + String protocol = rule.getProtocol(); + String algorithm = rule.getAlgorithm(); + + String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + List stickinessPolicies = rule.getStickinessPolicies(); + LoadBalancerTO lb = new LoadBalancerTO(rule.getId(), srcIp, srcPort, protocol, algorithm, revoked, false, destinations, stickinessPolicies); + lbs[i++] = lb; + } + String routerPublicIp = null; + + if (router instanceof DomainRouterVO) { + DomainRouterVO domr = _routerDao.findById(router.getId()); + routerPublicIp = domr.getPublicIpAddress(); + } + + Network guestNetwork = _networkMgr.getNetwork(guestNetworkId); + Nic nic = _nicDao.findByInstanceIdAndNetworkId(guestNetwork.getId(), router.getId()); + NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), + _networkMgr.getNetworkRate(guestNetwork.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNetwork), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNetwork)); + + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,routerPublicIp, + getRouterIpInNetwork(guestNetworkId, router.getId()),router.getPrivateIpAddress(), + _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId()); + + cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); + cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); + cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); + cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); + + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + + } + + private void createApplyVpnCommands(RemoteAccessVpn vpn, VirtualRouter router, Commands cmds) { + List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); + List addUsers = new ArrayList(); + List removeUsers = new ArrayList(); + for (VpnUser user : vpnUsers) { + if (user.getState() == VpnUser.State.Add) { + addUsers.add(user); + } else if (user.getState() == VpnUser.State.Revoke) { + removeUsers.add(user); + } + } + + VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers); + addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); + addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + + IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); + + RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); + startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("users", addUsersCmd); + cmds.addCommand("startVpn", startVpnCmd); + } + + private void createPasswordCommand(VirtualRouter router, VirtualMachineProfile profile, NicVO nic, Commands cmds) { + String password = (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + + // password should be set only on default network element + if (password != null && nic.isDefaultNic()) { + final String encodedPassword = PasswordGenerator.rot13(password); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("password", cmd); + } + + } + + private void createVmDataCommand(VirtualRouter router, UserVm vm, NicVO nic, String publicKey, Commands cmds) { + String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); + String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); + cmds.addCommand("vmdata", + generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), + vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey, nic.getNetworkId())); + + } + + private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); + DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); + for (UserVmVO vm : vms) { + boolean createVmData = true; + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()) { + createVmData = false; + } + + if (createVmData) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); + if (nic != null) { + s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); + createVmDataCommand(router, vm, nic, null, cmds); + } + } + } + } + + private void createDhcpEntryCommand(VirtualRouter router, UserVm vm, NicVO nic, Commands cmds) { + DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + String gatewayIp = findGatewayIp(vm.getId()); + if (!gatewayIp.equals(nic.getGateway())) { + GuestOSVO guestOS = _guestOSDao.findById(vm.getGuestOSId()); + // Don't set dhcp:router option for non-default nic on CentOS/RHEL, because they would set routing on wrong interface + // This is tricky, we may need to update this when we have more information on various OS's behavior + if (guestOS.getDisplayName().startsWith("CentOS") || guestOS.getDisplayName().startsWith("Red Hat Enterprise")) { + gatewayIp = "0.0.0.0"; + } + } + dhcpCommand.setDefaultRouter(gatewayIp); + dhcpCommand.setDefaultDns(findDefaultDnsIp(vm.getId())); + + dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); + dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("dhcp", dhcpCommand); + } + + private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); + DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); + for (UserVmVO vm : vms) { + boolean createDhcp = true; + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() + && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { + createDhcp = false; + } + if (createDhcp) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); + if (nic != null) { + s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + "."); + createDhcpEntryCommand(router, vm, nic, cmds); + } + } + } + } + + protected boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { + Answer[] answers = null; + try { + answers = _agentMgr.send(router.getHostId(), cmds); + } catch (OperationTimedoutException e) { + s_logger.warn("Timed Out", e); + throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); + } + + if (answers == null) { + return false; + } + + if (answers.length != cmds.size()) { + return false; + } + + // FIXME: Have to return state for individual command in the future + boolean result = true; + if (answers.length > 0) { + for (Answer answer : answers) { + if (!answer.getResult()) { + result = false; + break; + } + } + } + return result; + } + + protected void handleSingleWorkingRedundantRouter(List connectedRouters, List disconnectedRouters, String reason) throws ResourceUnavailableException + { + if (connectedRouters.isEmpty() || disconnectedRouters.isEmpty()) { + return; + } + if (connectedRouters.size() != 1 || disconnectedRouters.size() != 1) { + s_logger.warn("How many redundant routers do we have?? "); + return; + } + if (!connectedRouters.get(0).getIsRedundantRouter()) { + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); + } + if (!disconnectedRouters.get(0).getIsRedundantRouter()) { + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); + } + + DomainRouterVO connectedRouter = (DomainRouterVO)connectedRouters.get(0); + DomainRouterVO disconnectedRouter = (DomainRouterVO)disconnectedRouters.get(0); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("About to stop the router " + disconnectedRouter.getInstanceName() + " due to: " + reason); + } + String title = "Virtual router " + disconnectedRouter.getInstanceName() + " would be stopped after connecting back, due to " + reason; + String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId() + ") would be stopped after connecting back, due to: " + reason; + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, + disconnectedRouter.getDataCenterIdToDeployIn(), disconnectedRouter.getPodIdToDeployIn(), title, context); + disconnectedRouter.setStopPending(true); + disconnectedRouter = _routerDao.persist(disconnectedRouter); + + int connRouterPR = getRealPriority(connectedRouter); + int disconnRouterPR = getRealPriority(disconnectedRouter); + if (connRouterPR < disconnRouterPR) { + //connRouterPR < disconnRouterPR, they won't equal at anytime + if (!connectedRouter.getIsPriorityBumpUp()) { + final BumpUpPriorityCommand command = new BumpUpPriorityCommand(); + command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(connectedRouter.getId())); + command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, connectedRouter.getInstanceName()); + final Answer answer = _agentMgr.easySend(connectedRouter.getHostId(), command); + if (!answer.getResult()) { + s_logger.error("Failed to bump up " + connectedRouter.getInstanceName() + "'s priority! " + answer.getDetails()); + } + } else { + String t = "Can't bump up virtual router " + connectedRouter.getInstanceName() + "'s priority due to it's already bumped up!"; + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, + connectedRouter.getDataCenterIdToDeployIn(), connectedRouter.getPodIdToDeployIn(), t, t); + } + } + } + + @Override + public boolean associatePublicIP(Network network, final List ipAddress, List routers) + throws ResourceUnavailableException { + if (ipAddress == null || ipAddress.isEmpty()) { + s_logger.debug("No ip association rules to be applied for network " + network.getId()); + return true; + } + return applyRules(network, routers, "ip association", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createAssociateIPCommands(router, ipAddress, cmds, 0); + return sendCommandsToRouter(router, cmds); + } + }); + } + + @Override + public boolean applyFirewallRules(Network network, final List rules, List routers) throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No firewall rules to be applied for network " + network.getId()); + return true; + } + return applyRules(network, routers, "firewall rules", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + if (rules.get(0).getPurpose() == Purpose.LoadBalancing) { + // for load balancer we have to resend all lb rules for the network + List lbs = _loadBalancerDao.listByNetworkId(network.getId()); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList,policyList); + lbRules.add(loadBalancing); + } + return sendLBRules(router, lbRules, network.getId()); + } else if (rules.get(0).getPurpose() == Purpose.PortForwarding) { + return sendPortForwardingRules(router, (List) rules, network.getId()); + } else if (rules.get(0).getPurpose() == Purpose.StaticNat) { + return sendStaticNatRules(router, (List) rules, network.getId()); + } else if (rules.get(0).getPurpose() == Purpose.Firewall) { + return sendFirewallRules(router, (List) rules, network.getId()); + } else { + s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); + return false; + } + } + }); + } + + protected boolean sendLBRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + protected boolean sendPortForwardingRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyPortForwardingRulesCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + protected boolean sendStaticNatRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyStaticNatRulesCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + @Override + public List getRoutersForNetwork(long networkId) { + List routers = _routerDao.findByNetwork(networkId); + List vrs = new ArrayList(routers.size()); + for (DomainRouterVO router : routers) { + vrs.add(router); + } + return vrs; + } + + private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (FirewallRule rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr()); + rulesTO.add(ruleTO); + } + } + + SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + + protected boolean sendFirewallRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createFirewallRulesCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + @Override + public String getDnsBasicZoneUpdate() { + return _dnsBasicZoneUpdates; + } + + protected interface RuleApplier { + boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; + } + + protected boolean applyRules(Network network, List routers, String typeString, + boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); + throw new ResourceUnavailableException("Unable to apply " + typeString , DataCenter.class, network.getDataCenterId()); + } + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + boolean isZoneBasic = (dc.getNetworkType() == NetworkType.Basic); + + // isPodLevelException and podId is only used for basic zone + assert !((!isZoneBasic && isPodLevelException) || (isZoneBasic && isPodLevelException && podId == null)); + + List connectedRouters = new ArrayList(); + List disconnectedRouters = new ArrayList(); + boolean result = true; + String msg = "Unable to apply " + typeString + " on disconnected router "; + for (VirtualRouter router : routers) { + if (router.getState() == State.Running) { + s_logger.debug("Applying " + typeString + " in network " + network); + + if (router.isStopPending()) { + if (_hostDao.findById(router.getHostId()).getStatus() == Status.Up) { + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + + router.getInstanceName() + " haven't been stopped after it's host coming back!", + DataCenter.class, router.getDataCenterIdToDeployIn()); + } + s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + + typeString + " commands to the backend"); + continue; + } + try { + result = applier.execute(network, router); + connectedRouters.add(router); + } catch (AgentUnavailableException e) { + s_logger.warn(msg + router.getInstanceName(), e); + disconnectedRouters.add(router); + } + + //If rules fail to apply on one domR and not due to disconnection, no need to proceed with the rest + if (!result) { + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); + } + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, + router.getDataCenterIdToDeployIn()); + } + + } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { + s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + + ", so not sending apply " + typeString + " commands to the backend"); + } else { + s_logger.warn("Unable to apply " + typeString +", virtual router is not in the right state " + router.getState()); + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", Pod.class, podId); + } + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); + } + } + + if (!connectedRouters.isEmpty()) { + if (!isZoneBasic && !disconnectedRouters.isEmpty() && disconnectedRouters.get(0).getIsRedundantRouter()) { + // These disconnected redundant virtual routers are out of sync now, stop them for synchronization + handleSingleWorkingRedundantRouter(connectedRouters, disconnectedRouters, msg); + } + } else if (!disconnectedRouters.isEmpty()) { + for (VirtualRouter router : disconnectedRouters) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(msg + router.getInstanceName() + "(" + router.getId() + ")"); + } + } + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException(msg, Pod.class, podId); + } + throw new ResourceUnavailableException(msg, DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); + } + + result = true; + if (failWhenDisconnect) { + result = !connectedRouters.isEmpty(); + } + return result; + } + + @Override + public boolean applyStaticNats(Network network, final List rules, List routers) throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No static nat rules to be applied for network " + network.getId()); + return true; + } + return applyRules(network, routers, "static nat rules", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + return applyStaticNat(router, rules, network.getId()); + } + }); + } + + + protected boolean applyStaticNat(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds, + long guestNetworkId) { + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (StaticNat rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, + null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + rulesTO.add(ruleTO); + } + } + + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + @Override + public int getTimeout() { + return -1; + } + + @Override + public boolean isRecurring() { + return false; + } + + @Override + public boolean processAnswers(long agentId, long seq, Answer[] answers) { + return false; + } + + @Override + public boolean processCommands(long agentId, long seq, Command[] commands) { + return false; + } + + @Override + public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + UserContext context = UserContext.current(); + context.setAccountId(1); + List routers = _routerDao.listIsolatedByHostId(host.getId()); + for (DomainRouterVO router : routers) { + if (router.isStopPending()) { + State state = router.getState(); + if (state != State.Stopped && state != State.Destroyed) { + try { + stopRouter(router.getId(), false); + } catch (ResourceUnavailableException e) { + s_logger.warn("Fail to stop router " + router.getInstanceName(), e); + throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName()); + } catch (ConcurrentOperationException e) { + s_logger.warn("Fail to stop router " + router.getInstanceName(), e); + throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName()); + } + } + router.setStopPending(false); + router = _routerDao.persist(router); + } + } + } + + @Override + public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { + return null; + } + + @Override + + public boolean processDisconnect(long agentId, Status state) { + return false; + } + + @Override + public boolean processTimeout(long agentId, long seq) { + return false; + } + + protected String getRouterControlIp(long routerId) { + String routerControlIpAddress = null; + List nics = _nicDao.listByVmId(routerId); + for (NicVO n : nics) { + NetworkVO nc = _networkDao.findById(n.getNetworkId()); + if (nc.getTrafficType() == TrafficType.Control) { + routerControlIpAddress = n.getIp4Address(); + } + } + + if(routerControlIpAddress == null) { + s_logger.warn("Unable to find router's control ip in its attached NICs!. routerId: " + routerId); + DomainRouterVO router = _routerDao.findById(routerId); + return router.getPrivateIpAddress(); + } + + return routerControlIpAddress; + } + + + protected String getRouterIpInNetwork(long networkId, long instanceId) { + return _nicDao.getIpAddress(networkId, instanceId); + } + + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile){ + //Collect network usage before stopping Vm + VMInstanceVO vm = profile.getVirtualMachine(); + DomainRouterVO router = _routerDao.findById(vm.getId()); + if(router == null){ + return; + } + String privateIP = router.getPrivateIpAddress(); + + if (privateIP != null) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long guestNtwkId : routerGuestNtwkIds) { + boolean forVpc = router.getVpcId() != null; + Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); + Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), + guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); + final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), + forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + NetworkUsageAnswer answer = null; + try { + answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); + continue; + } + + if (answer != null) { + if (!answer.getResult()) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + continue; + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { + s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + continue; + } + txn.start(); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + continue; + } + + if(previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + continue; + } + + if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answer.getBytesReceived()); + if (stats.getCurrentBytesSent() > answer.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answer.getBytesSent()); + _statsDao.update(stats.getId(), stats); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + } finally { + txn.close(); + } + } + } + } + } + + @Override + public boolean recreateNeeded( + VirtualMachineProfile profile, long hostId, + Commands cmds, ReservationContext context) { + //asssume that if failed to ssh into router, meaning router is crashed + CheckSshAnswer answer = (CheckSshAnswer) cmds.getAnswer("checkSsh"); + if (answer == null || !answer.getResult()) { + return true; + } + + return false; + } +} diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index ac496027f51..edf45bcfeb8 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1,2560 +1,2560 @@ -// 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.vm; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.AgentManager.OnError; -import com.cloud.agent.Listener; -import com.cloud.agent.api.AgentControlAnswer; -import com.cloud.agent.api.AgentControlCommand; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CheckVirtualMachineAnswer; -import com.cloud.agent.api.CheckVirtualMachineCommand; -import com.cloud.agent.api.ClusterSyncAnswer; -import com.cloud.agent.api.ClusterSyncCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.MigrateAnswer; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.PingRoutingCommand; -import com.cloud.agent.api.PrepareForMigrationAnswer; -import com.cloud.agent.api.PrepareForMigrationCommand; -import com.cloud.agent.api.RebootAnswer; -import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.StartAnswer; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StartupCommand; -import com.cloud.agent.api.StartupRoutingCommand; -import com.cloud.agent.api.StartupRoutingCommand.VmState; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.StopCommand; -import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.manager.Commands; -import com.cloud.agent.manager.allocator.HostAllocator; -import com.cloud.alert.AlertManager; -import com.cloud.capacity.CapacityManager; -import com.cloud.cluster.ClusterManager; -import com.cloud.cluster.StackMaid; -import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.consoleproxy.ConsoleProxyManager; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.deploy.DataCenterDeployment; -import com.cloud.deploy.DeployDestination; -import com.cloud.deploy.DeploymentPlan; -import com.cloud.deploy.DeploymentPlanner; -import com.cloud.deploy.DeploymentPlanner.ExcludeList; -import com.cloud.domain.dao.DomainDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.ConnectionException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapcityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ManagementServerException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.VirtualMachineMigrationException; -import com.cloud.ha.HighAvailabilityManager; -import com.cloud.ha.HighAvailabilityManager.WorkType; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.host.Status; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.hypervisor.HypervisorGuru; -import com.cloud.hypervisor.HypervisorGuruManager; -import com.cloud.network.Network; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkVO; -import com.cloud.network.dao.NetworkDao; -import com.cloud.offering.ServiceOffering; -import com.cloud.org.Cluster; -import com.cloud.resource.ResourceManager; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.GuestOSCategoryDao; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.User; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserDao; -import com.cloud.utils.Journal; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.Ternary; -import com.cloud.utils.component.Adapters; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.component.Inject; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.exception.ExecutionException; -import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.utils.fsm.StateMachine2; -import com.cloud.vm.ItWorkVO.Step; -import com.cloud.vm.VirtualMachine.Event; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.SecondaryStorageVmDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.VMInstanceDao; - -@Local(value = VirtualMachineManager.class) -public class VirtualMachineManagerImpl implements VirtualMachineManager, Listener { - private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class); - - String _name; - @Inject - protected StorageManager _storageMgr; - @Inject - protected NetworkManager _networkMgr; - @Inject - protected AgentManager _agentMgr; - @Inject - protected VMInstanceDao _vmDao; - @Inject - protected ServiceOfferingDao _offeringDao; - @Inject - protected VMTemplateDao _templateDao; - @Inject - protected UserDao _userDao; - @Inject - protected AccountDao _accountDao; - @Inject - protected DomainDao _domainDao; - @Inject - protected ClusterManager _clusterMgr; - @Inject - protected ItWorkDao _workDao; - @Inject - protected UserVmDao _userVmDao; - @Inject - protected DomainRouterDao _routerDao; - @Inject - protected ConsoleProxyDao _consoleDao; - @Inject - protected SecondaryStorageVmDao _secondaryDao; - @Inject - protected NicDao _nicsDao; - @Inject - protected AccountManager _accountMgr; - @Inject - protected HostDao _hostDao; - @Inject - protected AlertManager _alertMgr; - @Inject - protected GuestOSCategoryDao _guestOsCategoryDao; - @Inject - protected GuestOSDao _guestOsDao; - @Inject - protected VolumeDao _volsDao; - @Inject - protected ConsoleProxyManager _consoleProxyMgr; - @Inject - protected ConfigurationManager _configMgr; - @Inject - protected CapacityManager _capacityMgr; - @Inject - protected HighAvailabilityManager _haMgr; - @Inject - protected HostPodDao _podDao; - @Inject - protected DataCenterDao _dcDao; - @Inject - protected StoragePoolDao _storagePoolDao; - @Inject - protected HypervisorGuruManager _hvGuruMgr; - @Inject - protected NetworkDao _networkDao; - - @Inject(adapter = DeploymentPlanner.class) - protected Adapters _planners; - - @Inject(adapter = HostAllocator.class) - protected Adapters _hostAllocators; - - @Inject - protected ResourceManager _resourceMgr; - - Map> _vmGurus = new HashMap>(); - protected StateMachine2 _stateMachine; - - ScheduledExecutorService _executor = null; - protected int _operationTimeout; - - protected int _retry; - protected long _nodeId; - protected long _cleanupWait; - protected long _cleanupInterval; - protected long _cancelWait; - protected long _opWaitInterval; - protected int _lockStateRetry; - protected boolean _forceStop; - - @Override - public void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru) { - synchronized (_vmGurus) { - _vmGurus.put(type, guru); - } - } - - @Override - @DB - public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, Pair rootDiskOffering, - List> dataDiskOfferings, List> networks, Map params, DeploymentPlan plan, - HypervisorType hyperType, Account owner) throws InsufficientCapacityException { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating entries for VM: " + vm); - } - - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, params); - - vm.setDataCenterId(plan.getDataCenterId()); - if (plan.getPodId() != null) { - vm.setPodId(plan.getPodId()); - } - assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; - - @SuppressWarnings("unchecked") - VirtualMachineGuru guru = (VirtualMachineGuru) _vmGurus.get(vm.getType()); - - Transaction txn = Transaction.currentTxn(); - txn.start(); - vm = guru.persist(vm); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating nics for " + vm); - } - - try { - _networkMgr.allocate(vmProfile, networks); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); - } - - if (dataDiskOfferings == null) { - dataDiskOfferings = new ArrayList>(0); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocaing disks for " + vm); - } - - if (template.getFormat() == ImageFormat.ISO) { - _storageMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner); - } else if (template.getFormat() == ImageFormat.BAREMETAL) { - // Do nothing - } else { - _storageMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner); - } - - for (Pair offering : dataDiskOfferings) { - _storageMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner); - } - - txn.commit(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocation completed for VM: " + vm); - } - - return vm; - } - - @Override - public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, Long rootSize, Pair dataDiskOffering, - List> networks, DeploymentPlan plan, HypervisorType hyperType, Account owner) throws InsufficientCapacityException { - List> diskOfferings = new ArrayList>(1); - if (dataDiskOffering != null) { - diskOfferings.add(dataDiskOffering); - } - return allocate(vm, template, serviceOffering, new Pair(serviceOffering, rootSize), diskOfferings, networks, null, plan, hyperType, owner); - } - - @Override - public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, List> networks, DeploymentPlan plan, - HypervisorType hyperType, Account owner) throws InsufficientCapacityException { - return allocate(vm, template, serviceOffering, new Pair(serviceOffering, null), null, networks, null, plan, hyperType, owner); - } - - @SuppressWarnings("unchecked") - private VirtualMachineGuru getVmGuru(T vm) { - return (VirtualMachineGuru) _vmGurus.get(vm.getType()); - } - - @SuppressWarnings("unchecked") - private VirtualMachineGuru getBareMetalVmGuru(T vm) { - return (VirtualMachineGuru) _vmGurus.get(VirtualMachine.Type.UserBareMetal); - } - - @Override - public boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException { - try { - if (advanceExpunge(vm, caller, account)) { - // Mark vms as removed - remove(vm, caller, account); - return true; - } else { - s_logger.info("Did not expunge " + vm); - return false; - } - } catch (OperationTimedoutException e) { - throw new CloudRuntimeException("Operation timed out", e); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation ", e); - } - } - - @Override - public boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { - if (vm == null || vm.getRemoved() != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find vm or vm is destroyed: " + vm); - } - return true; - } - - if (!this.advanceStop(vm, false, caller, account)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to stop the VM so we can't expunge it."); - } - } - - try { - if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) { - s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); - return false; - } - } catch (NoTransitionException e) { - s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); - return false; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Destroying vm " + vm); - } - - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - s_logger.debug("Cleaning up NICS"); - _networkMgr.cleanupNics(profile); - // Clean up volumes based on the vm's instance id - _storageMgr.cleanupVolumes(vm.getId()); - - VirtualMachineGuru guru = getVmGuru(vm); - guru.finalizeExpunge(vm); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expunged " + vm); - } - - return true; - } - - @Override - public boolean start() { - _executor.scheduleAtFixedRate(new CleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS); - cancelWorkItems(_nodeId); - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public boolean configure(String name, Map xmlParams) throws ConfigurationException { - _name = name; - - ComponentLocator locator = ComponentLocator.getCurrentLocator(); - ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); - Map params = configDao.getConfiguration(xmlParams); - - _retry = NumbersUtil.parseInt(params.get(Config.StartRetry.key()), 10); - - ReservationContextImpl.setComponents(_userDao, _domainDao, _accountDao); - VirtualMachineProfileImpl.setComponents(_offeringDao, _templateDao, _accountDao); - - _cancelWait = NumbersUtil.parseLong(params.get(Config.VmOpCancelInterval.key()), 3600); - _cleanupWait = NumbersUtil.parseLong(params.get(Config.VmOpCleanupWait.key()), 3600); - _cleanupInterval = NumbersUtil.parseLong(params.get(Config.VmOpCleanupInterval.key()), 86400) * 1000; - _opWaitInterval = NumbersUtil.parseLong(params.get(Config.VmOpWaitInterval.key()), 120) * 1000; - _lockStateRetry = NumbersUtil.parseInt(params.get(Config.VmOpLockStateRetry.key()), 5); - _operationTimeout = NumbersUtil.parseInt(params.get(Config.Wait.key()), 1800) * 2; - _forceStop = Boolean.parseBoolean(params.get(Config.VmDestroyForcestop.key())); - - _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup")); - _nodeId = _clusterMgr.getManagementNodeId(); - - _agentMgr.registerForHostEvents(this, true, true, true); - - return true; - } - - @Override - public String getName() { - return _name; - } - - protected VirtualMachineManagerImpl() { - setStateMachine(); - } - - @Override - public T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { - return start(vm, params, caller, account, null); - } - - @Override - public T start(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, - ResourceUnavailableException { - try { - return advanceStart(vm, params, caller, account, planToDeploy); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e); - } - } - - protected boolean checkWorkItems(VMInstanceVO vm, State state) throws ConcurrentOperationException { - while (true) { - ItWorkVO vo = _workDao.findByOutstandingWork(vm.getId(), state); - if (vo == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find work for VM: " + vm + " and state: " + state); - } - return true; - } - - if (vo.getStep() == Step.Done) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Work for " + vm + " is " + vo.getStep()); - } - return true; - } - - if (vo.getSecondsTaskIsInactive() > _cancelWait) { - s_logger.warn("The task item for vm " + vm + " has been inactive for " + vo.getSecondsTaskIsInactive()); - return false; - } - - try { - Thread.sleep(_opWaitInterval); - } catch (InterruptedException e) { - s_logger.info("Waiting for " + vm + " but is interrupted"); - throw new ConcurrentOperationException("Waiting for " + vm + " but is interrupted"); - } - s_logger.debug("Waiting some more to make sure there's no activity on " + vm); - } - - } - - @DB - protected Ternary changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) - throws ConcurrentOperationException { - long vmId = vm.getId(); - - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId()); - int retry = _lockStateRetry; - while (retry-- != 0) { - Transaction txn = Transaction.currentTxn(); - Ternary result = null; - txn.start(); - try { - Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - work = _workDao.persist(work); - ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); - - if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); - } - result = new Ternary(vmGuru.findById(vmId), context, work); - txn.commit(); - return result; - } - } catch (NoTransitionException e) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to transition into Starting state due to " + e.getMessage()); - } - } finally { - if (result == null) { - txn.rollback(); - } - } - - VMInstanceVO instance = _vmDao.findById(vmId); - if (instance == null) { - throw new ConcurrentOperationException("Unable to acquire lock on " + vm); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Determining why we're unable to update the state to Starting for " + instance + ". Retry=" + retry); - } - - State state = instance.getState(); - if (state == State.Running) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is already started: " + vm); - } - return null; - } - - if (state.isTransitional()) { - if (!checkWorkItems(vm, state)) { - throw new ConcurrentOperationException("There are concurrent operations on " + vm); - } else { - continue; - } - } - - if (state != State.Stopped) { - s_logger.debug("VM " + vm + " is not in a state to be started: " + state); - return null; - } - } - - throw new ConcurrentOperationException("Unable to change the state of " + vm); - } - - protected boolean changeState(T vm, Event event, Long hostId, ItWorkVO work, Step step) throws NoTransitionException { - // FIXME: We should do this better. - Step previousStep = work.getStep(); - _workDao.updateStep(work, step); - boolean result = false; - try { - result = stateTransitTo(vm, event, hostId); - return result; - } finally { - if (!result) { - _workDao.updateStep(work, previousStep); - } - } - } - - @Override - public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - return advanceStart(vm, params, caller, account, null); - } - - @Override - public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - long vmId = vm.getId(); - VirtualMachineGuru vmGuru; - if (vm.getHypervisorType() == HypervisorType.BareMetal) { - vmGuru = getBareMetalVmGuru(vm); - } else { - vmGuru = getVmGuru(vm); - } - - vm = vmGuru.findById(vm.getId()); - Ternary start = changeToStartState(vmGuru, vm, caller, account); - if (start == null) { - return vmGuru.findById(vmId); - } - - vm = start.first(); - ReservationContext ctx = start.second(); - ItWorkVO work = start.third(); - - T startedVm = null; - ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); - VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to deploy VM, vm has dcId: " + vm.getDataCenterIdToDeployIn() + " and podId: " + vm.getPodIdToDeployIn()); - } - DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), null, null, null, null, ctx); - if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ - if (s_logger.isDebugEnabled()) { - s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() + ", clusterId: " - + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); - } - plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); - } - - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - - boolean canRetry = true; - try { - Journal journal = start.second().getJournal(); - - ExcludeList avoids = null; - if (planToDeploy != null) { - avoids = planToDeploy.getAvoids(); - } - if (avoids == null) { - avoids = new ExcludeList(); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); - } - - - boolean planChangedByVolume = false; - boolean reuseVolume = true; - DataCenterDeployment originalPlan = plan; - - int retry = _retry; - boolean recreate = false; - while (retry-- != 0) { // It's != so that it can match -1. - - if(reuseVolume){ - // edit plan if this vm's ROOT volume is in READY state already - List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); - for (VolumeVO vol : vols) { - // make sure if the templateId is unchanged. If it is changed, - // let planner - // reassign pool for the volume even if it ready. - Long volTemplateId = vol.getTemplateId(); - if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); - } - continue; - } - - StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); - if (!pool.isInMaintenance()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); - } - long rootVolDcId = pool.getDataCenterId(); - Long rootVolPodId = pool.getPodId(); - Long rootVolClusterId = pool.getClusterId(); - if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { - Long clusterIdSpecified = planToDeploy.getClusterId(); - if (clusterIdSpecified != null && rootVolClusterId != null) { - if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) { - // cannot satisfy the plan passed in to the - // planner - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: " + rootVolClusterId - + ", cluster specified: " + clusterIdSpecified); - } - throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " - + vm, Cluster.class, clusterIdSpecified); - } - } - plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId(), null, ctx); - }else{ - plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx); - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); - } - planChangedByVolume = true; - } - } - } - } - - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, account, params); - DeployDestination dest = null; - for (DeploymentPlanner planner : _planners) { - if (planner.canHandle(vmProfile, plan, avoids)) { - dest = planner.plan(vmProfile, plan, avoids); - } else { - continue; - } - if (dest != null) { - avoids.addHost(dest.getHost().getId()); - journal.record("Deployment found ", vmProfile, dest); - break; - } - } - - if (dest == null) { - if (planChangedByVolume) { - plan = originalPlan; - planChangedByVolume = false; - //do not enter volume reuse for next retry, since we want to look for resorces outside the volume's cluster - reuseVolume = false; - continue; - } - throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); - } - - long destHostId = dest.getHost().getId(); - vm.setPodId(dest.getPod().getId()); - - try { - if (!changeState(vm, Event.OperationRetry, destHostId, work, Step.Prepare)) { - throw new ConcurrentOperationException("Unable to update the state of the Virtual Machine"); - } - } catch (NoTransitionException e1) { - throw new ConcurrentOperationException(e1.getMessage()); - } - - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is being created in podId: " + vm.getPodIdToDeployIn()); - } - _networkMgr.prepare(vmProfile, dest, ctx); - if (vm.getHypervisorType() != HypervisorType.BareMetal) { - _storageMgr.prepare(vmProfile, dest, recreate); - recreate = false; - } - //since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity - if(!reuseVolume){ - reuseVolume = true; - } - - Commands cmds = null; - vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); - - VirtualMachineTO vmTO = hvGuru.implement(vmProfile); - - cmds = new Commands(OnError.Stop); - cmds.addCommand(new StartCommand(vmTO)); - - vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); - - - work = _workDao.findById(work.getId()); - if (work == null || work.getStep() != Step.Prepare) { - throw new ConcurrentOperationException("Work steps have been changed: " + work); - } - _workDao.updateStep(work, Step.Starting); - - _agentMgr.send(destHostId, cmds); - - _workDao.updateStep(work, Step.Started); - - - StartAnswer startAnswer = cmds.getAnswer(StartAnswer.class); - if (startAnswer != null && startAnswer.getResult()) { - String host_guid = startAnswer.getHost_guid(); - if( host_guid != null ) { - HostVO finalHost = _resourceMgr.findHostByGuid(host_guid); - if (finalHost == null ) { - throw new CloudRuntimeException("Host Guid " + host_guid + " doesn't exist in DB, something wrong here"); - } - destHostId = finalHost.getId(); - } - if (vmGuru.finalizeStart(vmProfile, destHostId, cmds, ctx)) { - if (!changeState(vm, Event.OperationSucceeded, destHostId, work, Step.Done)) { - throw new ConcurrentOperationException("Unable to transition to a new state."); - } - startedVm = vm; - if (s_logger.isDebugEnabled()) { - s_logger.debug("Start completed for VM " + vm); - } - return startedVm; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.info("The guru did not like the answers so stopping " + vm); - } - - StopCommand cmd = new StopCommand(vm.getInstanceName()); - StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); - if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); - _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); - throw new ExecutionException("Unable to stop " + vm + " so we are unable to retry the start operation"); - } - if (vmGuru.recreateNeeded(vmProfile, destHostId, cmds, ctx)) { - recreate = true; - } else { - throw new ExecutionException("Unable to start " + vm + " due to error in finalizeStart, not retrying"); - } - } - } - s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails())); - - } catch (OperationTimedoutException e) { - s_logger.debug("Unable to send the start command to host " + dest.getHost()); - if (e.isActive()) { - _haMgr.scheduleStop(vm, destHostId, WorkType.CheckStop); - } - canRetry = false; - throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e); - } catch (ResourceUnavailableException e) { - s_logger.info("Unable to contact resource.", e); - if (!avoids.add(e)) { - if (e.getScope() == Volume.class || e.getScope() == Nic.class) { - throw e; - } else { - s_logger.warn("unexpected ResourceUnavailableException : " + e.getScope().getName(), e); - throw e; - } - } - } catch (InsufficientCapacityException e) { - s_logger.info("Insufficient capacity ", e); - if (!avoids.add(e)) { - if (e.getScope() == Volume.class || e.getScope() == Nic.class) { - throw e; - } else { - s_logger.warn("unexpected InsufficientCapacityException : " + e.getScope().getName(), e); - } - } - } catch (Exception e) { - s_logger.error("Failed to start instance " + vm, e); - throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e); - } finally { - if (startedVm == null && canRetry) { - Step prevStep = work.getStep(); - _workDao.updateStep(work, Step.Release); - if (prevStep == Step.Started || prevStep == Step.Starting) { - cleanup(vmGuru, vmProfile, work, Event.OperationFailed, false, caller, account); - } else { - //if step is not starting/started, send cleanup command with force=true - cleanup(vmGuru, vmProfile, work, Event.OperationFailed, true, caller, account); - } - } - } - } - } finally { - if (startedVm == null) { - if (canRetry) { - try { - changeState(vm, Event.OperationFailed, null, work, Step.Done); - } catch (NoTransitionException e) { - throw new ConcurrentOperationException(e.getMessage()); - } - } - } - } - - return startedVm; - } - - @Override - public boolean stop(T vm, User user, Account account) throws ResourceUnavailableException { - try { - return advanceStop(vm, false, user, account); - } catch (OperationTimedoutException e) { - throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", vm.getHostId(), e); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e); - } - } - - protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { - VMInstanceVO vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); - try { - Answer answer = _agentMgr.send(vm.getHostId(), stop); - if (!answer.getResult()) { - s_logger.debug("Unable to stop VM due to " + answer.getDetails()); - return false; - } - - guru.finalizeStop(profile, (StopAnswer) answer); - } catch (AgentUnavailableException e) { - if (!force) { - return false; - } - } catch (OperationTimedoutException e) { - if (!force) { - return false; - } - } - - return true; - } - - protected boolean cleanup(VirtualMachineGuru guru, VirtualMachineProfile profile, ItWorkVO work, Event event, boolean force, User user, Account account) { - T vm = profile.getVirtualMachine(); - State state = vm.getState(); - s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state"); - if (state == State.Starting) { - Step step = work.getStep(); - if (step == Step.Starting && !force) { - s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step); - return false; - } - - if (step == Step.Started || step == Step.Starting || step == Step.Release) { - if (vm.getHostId() != null) { - if (!sendStop(guru, profile, force)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process"); - return false; - } - } - } - - if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) { - s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step); - return true; - } - } else if (state == State.Stopping) { - if (vm.getHostId() != null) { - if (!sendStop(guru, profile, force)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process"); - return false; - } - } - } else if (state == State.Migrating) { - if (vm.getHostId() != null) { - if (!sendStop(guru, profile, force)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); - return false; - } - } - if (vm.getLastHostId() != null) { - if (!sendStop(guru, profile, force)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); - return false; - } - } - } else if (state == State.Running) { - if (!sendStop(guru, profile, force)) { - s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process"); - return false; - } - } - - try { - _networkMgr.release(profile, force); - s_logger.debug("Successfully released network resources for the vm " + vm); - } catch (Exception e) { - s_logger.warn("Unable to release some network resources.", e); - } - - _storageMgr.release(profile); - s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state"); - return true; - } - - @Override - public boolean advanceStop(T vm, boolean forced, User user, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException { - State state = vm.getState(); - if (state == State.Stopped) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is already stopped: " + vm); - } - return true; - } - - if (state == State.Destroyed || state == State.Expunging || state == State.Error) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Stopped called on " + vm + " but the state is " + state); - } - return true; - } - // grab outstanding work item if any - ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId()); - } - } - Long hostId = vm.getHostId(); - if (hostId == null) { - if (!forced) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState()); - } - return false; - } - try { - stateTransitTo(vm, Event.AgentReportStopped, null, null); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - // mark outstanding work item if any as done - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating work item to Done, id:" + work.getId()); - } - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - return true; - } - - VirtualMachineGuru vmGuru = getVmGuru(vm); - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - - try { - if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) { - throw new ConcurrentOperationException("VM is being operated on."); - } - } catch (NoTransitionException e1) { - if (!forced) { - throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState()); - } - boolean doCleanup = false; - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to transition the state but we're moving on because it's forced stop"); - } - if (state == State.Starting || state == State.Migrating) { - if (work != null) { - doCleanup = true; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to cleanup VM: " + vm + " ,since outstanding work item is not found"); - } - throw new CloudRuntimeException("Work item not found, We cannot stop " + vm + " when it is in state " + vm.getState()); - } - } else if (state == State.Stopping) { - doCleanup = true; - } - - if (doCleanup) { - if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, forced, user, account)) { - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating work item to Done, id:" + work.getId()); - } - return changeState(vm, Event.AgentReportStopped, null, work, Step.Done); - } catch (NoTransitionException e) { - s_logger.warn("Unable to cleanup " + vm); - return false; - } - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Failed to cleanup VM: " + vm); - } - throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState()); - } - } - } - - if (vm.getState() != State.Stopping) { - throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState()); - } - - vmGuru.prepareStop(profile); - - StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); - boolean stopped = false; - StopAnswer answer = null; - try { - answer = (StopAnswer) _agentMgr.send(vm.getHostId(), stop); - stopped = answer.getResult(); - if (!stopped) { - throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); - } - vmGuru.finalizeStop(profile, answer); - - } catch (AgentUnavailableException e) { - } catch (OperationTimedoutException e) { - } finally { - if (!stopped) { - if (!forced) { - s_logger.warn("Unable to stop vm " + vm); - try { - stateTransitTo(vm, Event.OperationFailed, vm.getHostId()); - } catch (NoTransitionException e) { - s_logger.warn("Unable to transition the state " + vm); - } - return false; - } else { - s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop"); - vmGuru.finalizeStop(profile, answer); - } - } - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug(vm + " is stopped on the host. Proceeding to release resource held."); - } - - try { - _networkMgr.release(profile, forced); - s_logger.debug("Successfully released network resources for the vm " + vm); - } catch (Exception e) { - s_logger.warn("Unable to release some network resources.", e); - } - - try { - if (vm.getHypervisorType() != HypervisorType.BareMetal) { - _storageMgr.release(profile); - s_logger.debug("Successfully released storage resources for the vm " + vm); - } - } catch (Exception e) { - s_logger.warn("Unable to release storage resources.", e); - } - - try { - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId()); - } - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - - return stateTransitTo(vm, Event.OperationSucceeded, null, null); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - return false; - } - } - - private void setStateMachine() { - _stateMachine = VirtualMachine.State.getStateMachine(); - } - - protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) throws NoTransitionException { - vm.setReservationId(reservationId); - return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); - } - - @Override - public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException { - State oldState = vm.getState(); - if (oldState == State.Starting) { - if (e == Event.OperationSucceeded) { - vm.setLastHostId(hostId); - } - } else if (oldState == State.Stopping) { - if (e == Event.OperationSucceeded) { - vm.setLastHostId(vm.getHostId()); - } - } - return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); - } - - @Override - public boolean remove(T vm, User user, Account caller) { - return _vmDao.remove(vm.getId()); - } - - @Override - public boolean destroy(T vm, User user, Account caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Destroying vm " + vm); - } - if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find vm or vm is destroyed: " + vm); - } - return true; - } - - if (!advanceStop(vm, _forceStop, user, caller)) { - s_logger.debug("Unable to stop " + vm); - return false; - } - - try { - if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) { - s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); - return false; - } - } catch (NoTransitionException e) { - s_logger.debug(e.getMessage()); - return false; - } - - return true; - } - - protected boolean checkVmOnHost(VirtualMachine vm, long hostId) throws AgentUnavailableException, OperationTimedoutException { - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName())); - if (!answer.getResult() || answer.getState() == State.Stopped) { - return false; - } - - return true; - } - - @Override - public T storageMigration(T vm, StoragePool destPool) { - VirtualMachineGuru vmGuru = getVmGuru(vm); - - long vmId = vm.getId(); - vm = vmGuru.findById(vmId); - - try { - stateTransitTo(vm, VirtualMachine.Event.StorageMigrationRequested, null); - } catch (NoTransitionException e) { - s_logger.debug("Unable to migrate vm: " + e.toString()); - throw new CloudRuntimeException("Unable to migrate vm: " + e.toString()); - } - - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - boolean migrationResult = false; - try { - migrationResult = _storageMgr.StorageMigration(profile, destPool); - - if (migrationResult) { - //if the vm is migrated to different pod in basic mode, need to reallocate ip - - if (vm.getPodIdToDeployIn() != destPool.getPodId()) { - DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterIdToDeployIn(), destPool.getPodId(), null, null, null, null); - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, null, null, null, null); - _networkMgr.reallocate(vmProfile, plan); - } - - //when start the vm next time, don;'t look at last_host_id, only choose the host based on volume/storage pool - vm.setLastHostId(null); - vm.setPodId(destPool.getPodId()); - } else { - s_logger.debug("Storage migration failed"); - } - } catch (ConcurrentOperationException e) { - s_logger.debug("Failed to migration: " + e.toString()); - throw new CloudRuntimeException("Failed to migration: " + e.toString()); - } catch (InsufficientVirtualNetworkCapcityException e) { - s_logger.debug("Failed to migration: " + e.toString()); - throw new CloudRuntimeException("Failed to migration: " + e.toString()); - } catch (InsufficientAddressCapacityException e) { - s_logger.debug("Failed to migration: " + e.toString()); - throw new CloudRuntimeException("Failed to migration: " + e.toString()); - } catch (InsufficientCapacityException e) { - s_logger.debug("Failed to migration: " + e.toString()); - throw new CloudRuntimeException("Failed to migration: " + e.toString()); - } finally { - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); - } catch (NoTransitionException e) { - s_logger.debug("Failed to change vm state: " + e.toString()); - throw new CloudRuntimeException("Failed to change vm state: " + e.toString()); - } - } - - return vm; - } - - @Override - public T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException { - s_logger.info("Migrating " + vm + " to " + dest); - - long dstHostId = dest.getHost().getId(); - Host fromHost = _hostDao.findById(srcHostId); - if (fromHost == null) { - s_logger.info("Unable to find the host to migrate from: " + srcHostId); - throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId); - } - - if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) { - s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); - throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); - } - - VirtualMachineGuru vmGuru = getVmGuru(vm); - - long vmId = vm.getId(); - vm = vmGuru.findById(vmId); - if (vm == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find the vm " + vm); - } - throw new ManagementServerException("Unable to find a virtual machine with id " + vmId); - } - - if (vm.getState() != State.Running) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is not Running, unable to migrate the vm " + vm); - } - throw new VirtualMachineMigrationException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString()); - } - - short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; - if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; - } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; - } - - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - _networkMgr.prepareNicForMigration(profile, dest); - _storageMgr.prepareForMigration(profile, dest); - - VirtualMachineTO to = toVmTO(profile); - PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); - - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId()); - work.setStep(Step.Prepare); - work.setResourceType(ItWorkVO.ResourceType.Host); - work.setResourceId(dstHostId); - work = _workDao.persist(work); - - PrepareForMigrationAnswer pfma = null; - try { - pfma = (PrepareForMigrationAnswer) _agentMgr.send(dstHostId, pfmc); - if (!pfma.getResult()) { - String msg = "Unable to prepare for migration due to " + pfma.getDetails(); - pfma = null; - throw new AgentUnavailableException(msg, dstHostId); - } - } catch (OperationTimedoutException e1) { - throw new AgentUnavailableException("Operation timed out", dstHostId); - } finally { - if (pfma == null) { - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - } - - vm.setLastHostId(srcHostId); - try { - if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) { - s_logger.info("Migration cancelled because state has changed: " + vm); - throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm); - } - } catch (NoTransitionException e1) { - s_logger.info("Migration cancelled because " + e1.getMessage()); - throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage()); - } - - boolean migrated = false; - try { - boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); - MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows); - mc.setHostGuid(dest.getHost().getGuid()); - - try { - MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc); - if (!ma.getResult()) { - s_logger.error("Unable to migrate due to " + ma.getDetails()); - return null; - } - } catch (OperationTimedoutException e) { - if (e.isActive()) { - s_logger.warn("Active migration command so scheduling a restart for " + vm); - _haMgr.scheduleRestart(vm, true); - } - throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId); - } - - try { - if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) { - throw new ConcurrentOperationException("Unable to change the state for " + vm); - } - } catch (NoTransitionException e1) { - throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage()); - } - - try { - if (!checkVmOnHost(vm, dstHostId)) { - s_logger.error("Unable to complete migration for " + vm); - try { - _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null); - } catch (AgentUnavailableException e) { - s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId); - } - cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); - return null; - } - } catch (OperationTimedoutException e) { - } - - migrated = true; - return vm; - } finally { - if (!migrated) { - s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); - - _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " - + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs."); - try { - _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null); - } catch (AgentUnavailableException ae) { - s_logger.info("Looks like the destination Host is unavailable for cleanup"); - } - - try { - stateTransitTo(vm, Event.OperationFailed, srcHostId); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - } - - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - } - - @Override - public VirtualMachineTO toVmTO(VirtualMachineProfile profile) { - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getVirtualMachine().getHypervisorType()); - VirtualMachineTO to = hvGuru.implement(profile); - return to; - } - - protected void cancelWorkItems(long nodeId) { - GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem"); - - try { - if (scanLock.lock(3)) { - try { - List works = _workDao.listWorkInProgressFor(nodeId); - for (ItWorkVO work : works) { - s_logger.info("Handling unfinished work item: " + work); - try { - VMInstanceVO vm = _vmDao.findById(work.getInstanceId()); - if (vm != null) { - if (work.getType() == State.Starting) { - _haMgr.scheduleRestart(vm, true); - work.setManagementServerId(_nodeId); - _workDao.update(work.getId(), work); - } else if (work.getType() == State.Stopping) { - _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop); - work.setManagementServerId(_nodeId); - _workDao.update(work.getId(), work); - } else if (work.getType() == State.Migrating) { - _haMgr.scheduleMigration(vm); - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - } - } catch (Exception e) { - s_logger.error("Error while handling " + work, e); - } - } - } finally { - scanLock.unlock(); - } - } - } finally { - scanLock.releaseRef(); - } - } - - @Override - public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException { - VirtualMachineGuru vmGuru = _vmGurus.get(vmType); - VMInstanceVO vm = vmGuru.findById(vmId); - if (vm == null) { - s_logger.debug("Unable to find a VM for " + vmId); - return true; - } - - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - - Long hostId = vm.getHostId(); - if (hostId == null) { - s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm); - return true; - } - - Host host = _hostDao.findById(hostId); - - DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null); - ExcludeList excludes = new ExcludeList(); - excludes.addHost(hostId); - - DeployDestination dest = null; - while (true) { - for (DeploymentPlanner planner : _planners) { - if (planner.canHandle(profile, plan, excludes)) { - dest = planner.plan(profile, plan, excludes); - } else { - continue; - } - - if (dest != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Planner " + planner + " found " + dest + " for migrating to."); - } - break; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Planner " + planner + " was unable to find anything."); - } - } - - if (dest == null) { - throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId()); - } - - excludes.addHost(dest.getHost().getId()); - VMInstanceVO vmInstance = null; - try { - vmInstance = migrate(vm, srcHostId, dest); - } catch (ResourceUnavailableException e) { - s_logger.debug("Unable to migrate to unavailable " + dest); - } catch (ConcurrentOperationException e) { - s_logger.debug("Unable to migrate VM due to: " + e.getMessage()); - } catch (ManagementServerException e) { - s_logger.debug("Unable to migrate VM: " + e.getMessage()); - } catch (VirtualMachineMigrationException e) { - s_logger.debug("Got VirtualMachineMigrationException, Unable to migrate: " + e.getMessage()); - if (vm.getState() == State.Starting) { - s_logger.debug("VM seems to be still Starting, we should retry migration later"); - throw e; - } else { - s_logger.debug("Unable to migrate VM, VM is not in Running or even Starting state, current state: " + vm.getState().toString()); - } - } - if (vmInstance != null) { - return true; - } - try { - boolean result = advanceStop(vm, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); - return result; - } catch (ResourceUnavailableException e) { - s_logger.debug("Unable to stop VM due to " + e.getMessage()); - } catch (ConcurrentOperationException e) { - s_logger.debug("Unable to stop VM due to " + e.getMessage()); - } catch (OperationTimedoutException e) { - s_logger.debug("Unable to stop VM due to " + e.getMessage()); - } - return false; - } - } - - protected class CleanupTask implements Runnable { - @Override - public void run() { - s_logger.trace("VM Operation Thread Running"); - try { - _workDao.cleanup(_cleanupWait); - } catch (Exception e) { - s_logger.error("VM Operations failed due to ", e); - } - } - } - - @Override - public boolean isVirtualMachineUpgradable(VirtualMachine vm, ServiceOffering offering) { - Enumeration en = _hostAllocators.enumeration(); - boolean isMachineUpgradable = true; - while (isMachineUpgradable && en.hasMoreElements()) { - final HostAllocator allocator = en.nextElement(); - isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering); - } - - return isMachineUpgradable; - } - - @Override - public T reboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { - try { - return advanceReboot(vm, params, caller, account); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Unable to reboot a VM due to concurrent operation", e); - } - } - - @Override - public T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - T rebootedVm = null; - - DataCenter dc = _configMgr.getZone(vm.getDataCenterIdToDeployIn()); - Host host = _hostDao.findById(vm.getHostId()); - Cluster cluster = null; - if (host != null) { - cluster = _configMgr.getCluster(host.getClusterId()); - } - HostPodVO pod = _configMgr.getPod(host.getPodId()); - DeployDestination dest = new DeployDestination(dc, pod, cluster, host); - - try { - - Commands cmds = new Commands(OnError.Stop); - cmds.addCommand(new RebootCommand(vm.getInstanceName())); - _agentMgr.send(host.getId(), cmds); - - Answer rebootAnswer = cmds.getAnswer(RebootAnswer.class); - if (rebootAnswer != null && rebootAnswer.getResult()) { - rebootedVm = vm; - return rebootedVm; - } - s_logger.info("Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? " no reboot answer" : rebootAnswer.getDetails())); - } catch (OperationTimedoutException e) { - s_logger.warn("Unable to send the reboot command to host " + dest.getHost() + " for the vm " + vm + " due to operation timeout", e); - throw new CloudRuntimeException("Failed to reboot the vm on host " + dest.getHost()); - } - - return rebootedVm; - } - - @Override - public VMInstanceVO findByIdAndType(VirtualMachine.Type type, long vmId) { - VirtualMachineGuru guru = _vmGurus.get(type); - return guru.findById(vmId); - } - - public Command cleanup(String vmName) { - return new StopCommand(vmName); - } - - public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { - Commands commands = new Commands(OnError.Continue); - - Map infos = convertToInfos(startup); - - final List vms = _vmDao.listByHostId(hostId); - s_logger.debug("Found " + vms.size() + " VMs for host " + hostId); - for (VMInstanceVO vm : vms) { - AgentVmInfo info = infos.remove(vm.getId()); - VMInstanceVO castedVm = null; - if (info == null) { - info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped); - } - castedVm = info.guru.findById(vm.getId()); - - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(castedVm.getHypervisorType()); - Command command = compareState(hostId, castedVm, info, true, hvGuru.trackVmHostChange()); - if (command != null) { - commands.addCommand(command); - } - } - - for (final AgentVmInfo left : infos.values()) { - boolean found = false; - for (VirtualMachineGuru vmGuru : _vmGurus.values()) { - VMInstanceVO vm = vmGuru.findByName(left.name); - if (vm != null) { - found = true; - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - if(hvGuru.trackVmHostChange()) { - Command command = compareState(hostId, vm, left, true, true); - if (command != null) { - commands.addCommand(command); - } - } else { - s_logger.warn("Stopping a VM, VM " + left.name + " migrate from Host " + vm.getHostId() + " to Host " + hostId ); - commands.addCommand(cleanup(left.name)); - } - break; - } - } - if ( ! found ) { - s_logger.warn("Stopping a VM that we have no record of : " + left.name); - commands.addCommand(cleanup(left.name)); - } - } - - return commands; - } - - public Commands deltaHostSync(long hostId, Map newStates) { - Map states = convertDeltaToInfos(newStates); - Commands commands = new Commands(OnError.Continue); - - for (Map.Entry entry : states.entrySet()) { - AgentVmInfo info = entry.getValue(); - - VMInstanceVO vm = info.vm; - - Command command = null; - if (vm != null) { - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - command = compareState(hostId, vm, info, false, hvGuru.trackVmHostChange()); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cleaning up a VM that is no longer found: " + info.name); - } - command = cleanup(info.name); - } - - if (command != null) { - commands.addCommand(command); - } - } - - return commands; - } - - - - public void deltaSync(Map> newStates) { - Map states = convertToInfos(newStates); - - for (Map.Entry entry : states.entrySet()) { - AgentVmInfo info = entry.getValue(); - VMInstanceVO vm = info.vm; - Command command = null; - if (vm != null) { - Host host = _resourceMgr.findHostByGuid(info.getHostUuid()); - long hId = host.getId(); - - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - command = compareState(hId, vm, info, false, hvGuru.trackVmHostChange()); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cleaning up a VM that is no longer found : " + info.name); - } - command = cleanup(info.name); - } - if (command != null){ - try { - Host host = _resourceMgr.findHostByGuid(info.getHostUuid()); - if (host != null){ - Answer answer = _agentMgr.send(host.getId(), cleanup(info.name)); - if (!answer.getResult()) { - s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); - } - } - } catch (Exception e) { - s_logger.warn("Unable to stop a VM due to " + e.getMessage()); - } - } - } - } - - - public void fullSync(final long clusterId, Map> newStates) { - if (newStates==null)return; - Map infos = convertToInfos(newStates); - Set set_vms = Collections.synchronizedSet(new HashSet()); - set_vms.addAll(_vmDao.listByClusterId(clusterId)); - set_vms.addAll(_vmDao.listLHByClusterId(clusterId)); - - for (VMInstanceVO vm : set_vms) { - if (vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) continue; - AgentVmInfo info = infos.remove(vm.getId()); - VMInstanceVO castedVm = null; - if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting)) - || (info != null && (info.state == State.Running && vm.getState() == State.Starting))) - { - s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + " on agent"); - info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped); - - // Bug 13850- grab outstanding work item if any for this VM state so that we mark it as DONE after we change VM state, else it will remain pending - ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found an outstanding work item for this vm " + vm + " in state:" + vm.getState() + ", work id:" + work.getId()); - } - } - vm.setState(State.Running); // set it as running and let HA take care of it - _vmDao.persist(vm); - - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating outstanding work item to Done, id:" + work.getId()); - } - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - - castedVm = info.guru.findById(vm.getId()); - try { - Host host = _hostDao.findByGuid(info.getHostUuid()); - long hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId(); - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(castedVm.getHypervisorType()); - Command command = compareState(hostId, castedVm, info, true, hvGuru.trackVmHostChange()); - if (command != null){ - Answer answer = _agentMgr.send(hostId, command); - if (!answer.getResult()) { - s_logger.warn("Failed to update state of the VM due to " + answer.getDetails()); - } - } - } catch (Exception e) { - s_logger.warn("Unable to update state of the VM due to exception " + e.getMessage()); - e.printStackTrace(); - } - } - else if (info != null && (vm.getState() == State.Stopped || vm.getState() == State.Stopping)) { - Host host = _hostDao.findByGuid(info.getHostUuid()); - if (host != null){ - s_logger.warn("Stopping a VM which is stopped/stopping " + info.name); - vm.setState(State.Stopped); // set it as stop and clear it from host - vm.setHostId(null); - _vmDao.persist(vm); - try { - Answer answer = _agentMgr.send(host.getId(), cleanup(info.name)); - if (!answer.getResult()) { - s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); - } - } - catch (Exception e) { - s_logger.warn("Unable to stop a VM due to " + e.getMessage()); - } - } - } - else - // host id can change - if (info != null && vm.getState() == State.Running){ - // check for host id changes - Host host = _hostDao.findByGuid(info.getHostUuid()); - if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())){ - s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - } - } - /* else if(info == null && vm.getState() == State.Stopping) { //Handling CS-13376 - s_logger.warn("Marking the VM as Stopped as it was still stopping on the CS" +vm.getName()); - vm.setState(State.Stopped); // Setting the VM as stopped on the DB and clearing it from the host - vm.setLastHostId(vm.getHostId()); - vm.setHostId(null); - _vmDao.persist(vm); - }*/ - } - - for (final AgentVmInfo left : infos.values()) { - if (VirtualMachineName.isValidVmName(left.name)) continue; // if the vm follows cloudstack naming ignore it for stopping - try { - Host host = _hostDao.findByGuid(left.getHostUuid()); - if (host != null){ - s_logger.warn("Stopping a VM which we do not have any record of " + left.name); - Answer answer = _agentMgr.send(host.getId(), cleanup(left.name)); - if (!answer.getResult()) { - s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); - } - } - } catch (Exception e) { - s_logger.warn("Unable to stop a VM due to " + e.getMessage()); - } - } - - } - - - - protected Map convertToInfos(final Map> newStates) { - final HashMap map = new HashMap(); - if (newStates == null) { - return map; - } - Collection> vmGurus = _vmGurus.values(); - boolean is_alien_vm = true; - long alien_vm_count = -1; - for (Map.Entry> entry : newStates.entrySet()) { - is_alien_vm = true; - for (VirtualMachineGuru vmGuru : vmGurus) { - String name = entry.getKey(); - VMInstanceVO vm = vmGuru.findByName(name); - if (vm != null) { - map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue().second(), entry.getValue().first())); - is_alien_vm = false; - break; - } - Long id = vmGuru.convertToId(name); - if (id != null) { - map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null, entry.getValue().second(), entry.getValue().first())); - is_alien_vm = false; - break; - } - } - // alien VMs - if (is_alien_vm){ - map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, null, entry.getValue().second(), entry.getValue().first())); - s_logger.warn("Found an alien VM " + entry.getKey()); - } - } - return map; - } - - protected Map convertToInfos(StartupRoutingCommand cmd) { - final Map states = cmd.getVmStates(); - final HashMap map = new HashMap(); - if (states == null) { - return map; - } - Collection> vmGurus = _vmGurus.values(); - - for (Map.Entry entry : states.entrySet()) { - for (VirtualMachineGuru vmGuru : vmGurus) { - String name = entry.getKey(); - VMInstanceVO vm = vmGuru.findByName(name); - if (vm != null) { - map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue().getState(), entry.getValue().getHost() )); - break; - } - Long id = vmGuru.convertToId(name); - if (id != null) { - map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null,entry.getValue().getState(), entry.getValue().getHost() )); - break; - } - } - } - - return map; - } - - protected Map convertDeltaToInfos(final Map states) { - final HashMap map = new HashMap(); - - if (states == null) { - return map; - } - - Collection> vmGurus = _vmGurus.values(); - - for (Map.Entry entry : states.entrySet()) { - for (VirtualMachineGuru vmGuru : vmGurus) { - String name = entry.getKey(); - - VMInstanceVO vm = vmGuru.findByName(name); - - if (vm != null) { - map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue())); - break; - } - - Long id = vmGuru.convertToId(name); - if (id != null) { - map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null,entry.getValue())); - break; - } - } - } - - return map; - } - - - - /** - * compareState does as its name suggests and compares the states between - * management server and agent. It returns whether something should be - * cleaned up - * - */ - protected Command compareState(long hostId, VMInstanceVO vm, final AgentVmInfo info, final boolean fullSync, boolean trackExternalChange) { - State agentState = info.state; - final String agentName = info.name; - final State serverState = vm.getState(); - final String serverName = vm.getInstanceName(); - - Command command = null; - s_logger.debug("VM " + serverName + ": cs state = " + serverState + " and realState = " + agentState); - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM " + serverName + ": cs state = " + serverState + " and realState = " + agentState); - } - - if (agentState == State.Error) { - agentState = State.Stopped; - - short alertType = AlertManager.ALERT_TYPE_USERVM; - if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER; - } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY; - } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_SSVM; - } - - HostPodVO podVO = _podDao.findById(vm.getPodIdToDeployIn()); - DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterIdToDeployIn()); - HostVO hostVO = _hostDao.findById(vm.getHostId()); - - String hostDesc = "name: " + hostVO.getName() + " (id:" + hostVO.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); - _alertMgr.sendAlert(alertType, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getInstanceName() + ", id: " + vm.getId() + ") stopped on host " + hostDesc - + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped due to storage failure."); - } - - if (trackExternalChange) { - if (serverState == State.Starting) { - if (vm.getHostId() != null && vm.getHostId() != hostId) { - s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + ", skip status sync for vm: " - + vm.getInstanceName()); - return null; - } - } - if (vm.getHostId() == null || hostId != vm.getHostId()) { - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); - } catch (NoTransitionException e) { - } - } - } - - // during VM migration time, don't sync state will agent status update - if (serverState == State.Migrating) { - s_logger.debug("Skipping vm in migrating state: " + vm); - return null; - } - - if (trackExternalChange) { - if (serverState == State.Starting) { - if (vm.getHostId() != null && vm.getHostId() != hostId) { - s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + ", skip status sync for vm: " - + vm.getInstanceName()); - return null; - } - } - - if (serverState == State.Running) { - try { - // - // we had a bug that sometimes VM may be at Running State - // but host_id is null, we will cover it here. - // means that when CloudStack DB lost of host information, - // we will heal it with the info reported from host - // - if (vm.getHostId() == null || hostId != vm.getHostId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("detected host change when VM " + vm + " is at running state, VM could be live-migrated externally from host " + vm.getHostId() + " to host " + hostId); - } - - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); - } - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - } - } - - if (agentState == serverState) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Both states are " + agentState + " for " + vm); - } - assert (agentState == State.Stopped || agentState == State.Running) : "If the states we send up is changed, this must be changed."; - if (agentState == State.Running) { - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportRunning, hostId); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - // FIXME: What if someone comes in and sets it to stopping? Then - // what? - return null; - } - - s_logger.debug("State matches but the agent said stopped so let's send a cleanup command anyways."); - return cleanup(agentName); - } - - if (agentState == State.Shutdowned) { - if (serverState == State.Running || serverState == State.Starting || serverState == State.Stopping) { - try { - advanceStop(vm, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); - } catch (AgentUnavailableException e) { - assert (false) : "How do we hit this with forced on?"; - return null; - } catch (OperationTimedoutException e) { - assert (false) : "How do we hit this with forced on?"; - return null; - } catch (ConcurrentOperationException e) { - assert (false) : "How do we hit this with forced on?"; - return null; - } - } else { - s_logger.debug("Sending cleanup to a shutdowned vm: " + agentName); - command = cleanup(agentName); - } - } else if (agentState == State.Stopped) { - // This state means the VM on the agent was detected previously - // and now is gone. This is slightly different than if the VM - // was never completed but we still send down a Stop Command - // to ensure there's cleanup. - if (serverState == State.Running) { - // Our records showed that it should be running so let's restart - // it. - _haMgr.scheduleRestart(vm, false); - } else if (serverState == State.Stopping) { - _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop); - s_logger.debug("Scheduling a check stop for VM in stopping mode: " + vm); - } else if (serverState == State.Starting) { - s_logger.debug("Ignoring VM in starting mode: " + vm.getInstanceName()); - _haMgr.scheduleRestart(vm, false); - } - command = cleanup(agentName); - } else if (agentState == State.Running) { - if (serverState == State.Starting) { - if (fullSync) { - try { - ensureVmRunningContext(hostId, vm, Event.AgentReportRunning); - } catch (OperationTimedoutException e) { - s_logger.error("Exception during update for running vm: " + vm, e); - return null; - } catch (ResourceUnavailableException e) { - s_logger.error("Exception during update for running vm: " + vm, e); - return null; - }catch (InsufficientAddressCapacityException e) { - s_logger.error("Exception during update for running vm: " + vm, e); - return null; - }catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); - } - } - } else if (serverState == State.Stopping) { - s_logger.debug("Scheduling a stop command for " + vm); - _haMgr.scheduleStop(vm, hostId, WorkType.Stop); - } else { - s_logger.debug("server VM state " + serverState + " does not meet expectation of a running VM report from agent"); - - // just be careful not to stop VM for things we don't handle - // command = cleanup(agentName); - } - } - return command; - } - - private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, NoTransitionException, InsufficientAddressCapacityException { - VirtualMachineGuru vmGuru = getVmGuru(vm); - - s_logger.debug("VM state is starting on full sync so updating it to running"); - vm = findByIdAndType(vm.getType(), vm.getId()); - - // grab outstanding work item if any - ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found an outstanding work item for this vm " + vm + " in state:" + vm.getState() + ", work id:" + work.getId()); - } - } - - try { - stateTransitTo(vm, cause, hostId); - } catch (NoTransitionException e1) { - s_logger.warn(e1.getMessage()); - } - - s_logger.debug("VM's " + vm + " state is starting on full sync so updating it to Running"); - vm = vmGuru.findById(vm.getId()); // this should ensure vm has the most - // up to date info - - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); - List nics = _nicsDao.listByVmId(profile.getId()); - for (NicVO nic : nics) { - Network network = _networkMgr.getNetwork(nic.getNetworkId()); - NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, - _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); - profile.addNic(nicProfile); - } - - Commands cmds = new Commands(OnError.Stop); - s_logger.debug("Finalizing commands that need to be send to complete Start process for the vm " + vm); - - if (vmGuru.finalizeCommandsOnStart(cmds, profile)) { - if (cmds.size() != 0) { - _agentMgr.send(vm.getHostId(), cmds); - } - - if (vmGuru.finalizeStart(profile, vm.getHostId(), cmds, null)) { - stateTransitTo(vm, cause, vm.getHostId()); - } else { - s_logger.error("Unable to finish finialization for running vm: " + vm); - } - } else { - s_logger.error("Unable to finalize commands on start for vm: " + vm); - } - - if (work != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating outstanding work item to Done, id:" + work.getId()); - } - work.setStep(Step.Done); - _workDao.update(work.getId(), work); - } - } - - @Override - public boolean isRecurring() { - return true; - } - - @Override - public boolean processAnswers(long agentId, long seq, Answer[] answers) { - for (final Answer answer : answers) { - if (answer instanceof ClusterSyncAnswer) { - ClusterSyncAnswer hs = (ClusterSyncAnswer) answer; - if (!hs.isExceuted()){ - deltaSync(hs.getNewStates()); - hs.setExecuted(); - } - } - } - return true; - } - - @Override - public boolean processTimeout(long agentId, long seq) { - return true; - } - - @Override - public int getTimeout() { - return -1; - } - - @Override - public boolean processCommands(long agentId, long seq, Command[] cmds) { - boolean processed = false; - for (Command cmd : cmds) { - if (cmd instanceof PingRoutingCommand) { - PingRoutingCommand ping = (PingRoutingCommand) cmd; - if (ping.getNewStates() != null && ping.getNewStates().size() > 0) { - Commands commands = deltaHostSync(agentId, ping.getNewStates()); - if (commands.size() > 0) { - try { - _agentMgr.send(agentId, commands, this); - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent is now unavailable", e); - } - } - } - processed = true; - } - } - return processed; - } - - @Override - public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { - return null; - } - - @Override - public boolean processDisconnect(long agentId, Status state) { - return true; - } - - @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { - if (!(cmd instanceof StartupRoutingCommand)) { - return; - } - - if (forRebalance) { - s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process"); - return; - } - - if (forRebalance) { - s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process"); - return; - } - - Long clusterId = agent.getClusterId(); - long agentId = agent.getId(); - if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen - StartupRoutingCommand startup = (StartupRoutingCommand) cmd; - HashMap> allStates = startup.getClusterVMStateChanges(); - if (allStates != null){ - this.fullSync(clusterId, allStates); - } - - // initiate the cron job - ClusterSyncCommand syncCmd = new ClusterSyncCommand(Integer.parseInt(Config.ClusterDeltaSyncInterval.getDefaultValue()), clusterId); - try { - long seq_no = _agentMgr.send(agentId, new Commands(syncCmd), this); - s_logger.debug("Cluster VM sync started with jobid " + seq_no); - } catch (AgentUnavailableException e) { - s_logger.fatal("The Cluster VM sync process failed for cluster id " + clusterId + " with ", e); - } - } - else { // for others KVM and VMWare - StartupRoutingCommand startup = (StartupRoutingCommand) cmd; - Commands commands = fullHostSync(agentId, startup); - - if (commands.size() > 0) { - s_logger.debug("Sending clean commands to the agent"); - - try { - boolean error = false; - Answer[] answers = _agentMgr.send(agentId, commands); - for (Answer answer : answers) { - if (!answer.getResult()) { - s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); - error = true; - } - } - if (error) { - throw new ConnectionException(true, "Unable to stop VMs"); - } - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent is unavailable now", e); - throw new ConnectionException(true, "Unable to sync", e); - } catch (final OperationTimedoutException e) { - s_logger.warn("Agent is unavailable now", e); - throw new ConnectionException(true, "Unable to sync", e); - } - } - - } - } - - protected class TransitionTask implements Runnable { - @Override - public void run() { - GlobalLock lock = GlobalLock.getInternLock("TransitionChecking"); - if (lock == null) { - s_logger.debug("Couldn't get the global lock"); - return; - } - - if (!lock.lock(30)) { - s_logger.debug("Couldn't lock the db"); - return; - } - try { - lock.addRef(); - List instances = _vmDao.findVMInTransition(new Date(new Date().getTime() - (_operationTimeout * 1000)), State.Starting, State.Stopping); - for (VMInstanceVO instance : instances) { - State state = instance.getState(); - if (state == State.Stopping) { - _haMgr.scheduleStop(instance, instance.getHostId(), WorkType.CheckStop); - } else if (state == State.Starting) { - _haMgr.scheduleRestart(instance, true); - } - } - } catch (Exception e) { - s_logger.warn("Caught the following exception on transition checking", e); - } finally { - StackMaid.current().exitCleanup(); - lock.unlock(); - } - } - } - - protected class AgentVmInfo { - public String name; - public State state; - public String hostUuid; - public VMInstanceVO vm; - public VirtualMachineGuru guru; - - @SuppressWarnings("unchecked") - public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state, String host) { - this.name = name; - this.state = state; - this.vm = vm; - this.guru = (VirtualMachineGuru) guru; - this.hostUuid = host; - } - - public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state) { - this(name, guru, vm, state, null); - } - - public String getHostUuid() { - return hostUuid; - } - } - - @Override - public VMInstanceVO findById(long vmId) { - return _vmDao.findById(vmId); - } - - @Override - public void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId) { - ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId); - if (newServiceOffering == null) { - throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId); - } - - // Check that the VM is stopped - if (!vmInstance.getState().equals(State.Stopped)) { - s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState()); - throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + - "in state " + vmInstance.getState() - + "; make sure the virtual machine is stopped and not in an error state before upgrading."); - } - - // Check if the service offering being upgraded to is what the VM is already running with - if (vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + - "service offering (" + newServiceOffering.getName() + ")"); - } - - throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + - "has the requested service offering (" + newServiceOffering.getName() + ")"); - } - - ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); - - // Check that the service offering being upgraded to has the same Guest IP type as the VM's current service offering - // NOTE: With the new network refactoring in 2.2, we shouldn't need the check for same guest IP type anymore. - /* - * if (!currentServiceOffering.getGuestIpType().equals(newServiceOffering.getGuestIpType())) { String errorMsg = - * "The service offering being upgraded to has a guest IP type: " + newServiceOffering.getGuestIpType(); errorMsg += - * ". Please select a service offering with the same guest IP type as the VM's current service offering (" + - * currentServiceOffering.getGuestIpType() + ")."; throw new InvalidParameterValueException(errorMsg); } - */ - - // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service - // offering - if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { - throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() - + ", cannot switch between local storage and shared storage service offerings. Current offering " + - "useLocalStorage=" + currentServiceOffering.getUseLocalStorage() - + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); - } - - // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms - if (currentServiceOffering.getSystemUse() != newServiceOffering.getSystemUse()) { - throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering"); - } - - // Check that there are enough resources to upgrade the service offering - if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) { - throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + - "for an offering of " + newServiceOffering.getCpu() + " cpu(s) at " - + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); - } - - // Check that the service offering being upgraded to has all the tags of the current service offering - List currentTags = _configMgr.csvTagsToList(currentServiceOffering.getTags()); - List newTags = _configMgr.csvTagsToList(newServiceOffering.getTags()); - if (!newTags.containsAll(currentTags)) { - throw new InvalidParameterValueException("Unable to upgrade virtual machine; the new service offering " + - "does not have all the tags of the " - + "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + - "offering tags: " + newTags); - } - } - - @Override - public boolean upgradeVmDb(long vmId, long serviceOfferingId) { - VMInstanceVO vmForUpdate = _vmDao.createForUpdate(); - vmForUpdate.setServiceOfferingId(serviceOfferingId); - ServiceOffering newSvcOff = _configMgr.getServiceOffering(serviceOfferingId); - vmForUpdate.setHaEnabled(newSvcOff.getOfferHA()); - vmForUpdate.setLimitCpuUse(newSvcOff.getLimitCpuUse()); - vmForUpdate.setServiceOfferingId(newSvcOff.getId()); - return _vmDao.update(vmId, vmForUpdate); - } - - @Override - public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, - ResourceUnavailableException, InsufficientCapacityException { - - s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested); - VMInstanceVO vmVO = _vmDao.findById(vm.getId()); - ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), - _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); - - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, - null, null, null); - - DataCenter dc = _configMgr.getZone(network.getDataCenterId()); - Host host = _hostDao.findById(vm.getHostId()); - DeployDestination dest = new DeployDestination(dc, null, null, host); - - //check vm state - if (vm.getState() == State.Running) { - //1) allocate and prepare nic - NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true); - - //2) Convert vmProfile to vmTO - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); - VirtualMachineTO vmTO = hvGuru.implement(vmProfile); - - //3) Convert nicProfile to NicTO - NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); - - //4) plug the nic to the vm - VirtualMachineGuru vmGuru = getVmGuru(vmVO); - - s_logger.debug("Plugging nic for vm " + vm + " in network " + network); - if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) { - s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm is a part of network now"); - return nic; - } else { - s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); - return null; - } - } else if (vm.getState() == State.Stopped) { - //1) allocate nic - return _networkMgr.createNicForVm(network, requested, context, vmProfile, false); - } else { - s_logger.warn("Unable to add vm " + vm + " to network " + network); - throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", - DataCenter.class, vm.getDataCenterIdToDeployIn()); - } - } - - - @Override - public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType); - - NicTO nicTO = hvGuru.toNicTO(nic); - return nicTO; - } - - @Override - public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { - VMInstanceVO vmVO = _vmDao.findById(vm.getId()); - ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), - _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); - - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, - null, null, null); - - DataCenter dc = _configMgr.getZone(network.getDataCenterId()); - Host host = _hostDao.findById(vm.getHostId()); - DeployDestination dest = new DeployDestination(dc, null, null, host); - VirtualMachineGuru vmGuru = getVmGuru(vmVO); - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); - VirtualMachineTO vmTO = hvGuru.implement(vmProfile); - - Nic nic = null; - - if (broadcastUri != null) { - nic = _nicsDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri.toString()); - } else { - nic = _networkMgr.getNicInNetwork(vm.getId(), network.getId()); - } - - NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), - _networkMgr.getNetworkRate(network.getId(), vm.getId()), - _networkMgr.isSecurityGroupSupportedInNetwork(network), - _networkMgr.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); - - //1) Unplug the nic - NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType()); - s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network); - boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest); - if (result) { - s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network ); - } else { - s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); - return false; - } - - //2) Release the nic - _networkMgr.releaseNic(vmProfile, nic); - s_logger.debug("Successfully released nic " + nic + "for vm " + vm); - - //3) Remove the nic - _networkMgr.removeNic(vmProfile, nic); - return result; - } - -} +// 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.vm; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.Listener; +import com.cloud.agent.api.AgentControlAnswer; +import com.cloud.agent.api.AgentControlCommand; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckVirtualMachineAnswer; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.ClusterSyncAnswer; +import com.cloud.agent.api.ClusterSyncCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.MigrateAnswer; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PrepareForMigrationAnswer; +import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.StartAnswer; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.StartupRoutingCommand.VmState; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.agent.manager.allocator.HostAllocator; +import com.cloud.alert.AlertManager; +import com.cloud.capacity.CapacityManager; +import com.cloud.cluster.ClusterManager; +import com.cloud.cluster.StackMaid; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.consoleproxy.ConsoleProxyManager; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.deploy.DeploymentPlanner; +import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ConnectionException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ManagementServerException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.VirtualMachineMigrationException; +import com.cloud.ha.HighAvailabilityManager; +import com.cloud.ha.HighAvailabilityManager.WorkType; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.HypervisorGuru; +import com.cloud.hypervisor.HypervisorGuruManager; +import com.cloud.network.Network; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.offering.ServiceOffering; +import com.cloud.org.Cluster; +import com.cloud.resource.ResourceManager; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; +import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.StoragePoolDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserDao; +import com.cloud.utils.Journal; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExecutionException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.utils.fsm.StateMachine2; +import com.cloud.vm.ItWorkVO.Step; +import com.cloud.vm.VirtualMachine.Event; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.ConsoleProxyDao; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.SecondaryStorageVmDao; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.VMInstanceDao; + +@Local(value = VirtualMachineManager.class) +public class VirtualMachineManagerImpl implements VirtualMachineManager, Listener { + private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class); + + String _name; + @Inject + protected StorageManager _storageMgr; + @Inject + protected NetworkManager _networkMgr; + @Inject + protected AgentManager _agentMgr; + @Inject + protected VMInstanceDao _vmDao; + @Inject + protected ServiceOfferingDao _offeringDao; + @Inject + protected VMTemplateDao _templateDao; + @Inject + protected UserDao _userDao; + @Inject + protected AccountDao _accountDao; + @Inject + protected DomainDao _domainDao; + @Inject + protected ClusterManager _clusterMgr; + @Inject + protected ItWorkDao _workDao; + @Inject + protected UserVmDao _userVmDao; + @Inject + protected DomainRouterDao _routerDao; + @Inject + protected ConsoleProxyDao _consoleDao; + @Inject + protected SecondaryStorageVmDao _secondaryDao; + @Inject + protected NicDao _nicsDao; + @Inject + protected AccountManager _accountMgr; + @Inject + protected HostDao _hostDao; + @Inject + protected AlertManager _alertMgr; + @Inject + protected GuestOSCategoryDao _guestOsCategoryDao; + @Inject + protected GuestOSDao _guestOsDao; + @Inject + protected VolumeDao _volsDao; + @Inject + protected ConsoleProxyManager _consoleProxyMgr; + @Inject + protected ConfigurationManager _configMgr; + @Inject + protected CapacityManager _capacityMgr; + @Inject + protected HighAvailabilityManager _haMgr; + @Inject + protected HostPodDao _podDao; + @Inject + protected DataCenterDao _dcDao; + @Inject + protected StoragePoolDao _storagePoolDao; + @Inject + protected HypervisorGuruManager _hvGuruMgr; + @Inject + protected NetworkDao _networkDao; + + @Inject(adapter = DeploymentPlanner.class) + protected Adapters _planners; + + @Inject(adapter = HostAllocator.class) + protected Adapters _hostAllocators; + + @Inject + protected ResourceManager _resourceMgr; + + Map> _vmGurus = new HashMap>(); + protected StateMachine2 _stateMachine; + + ScheduledExecutorService _executor = null; + protected int _operationTimeout; + + protected int _retry; + protected long _nodeId; + protected long _cleanupWait; + protected long _cleanupInterval; + protected long _cancelWait; + protected long _opWaitInterval; + protected int _lockStateRetry; + protected boolean _forceStop; + + @Override + public void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru) { + synchronized (_vmGurus) { + _vmGurus.put(type, guru); + } + } + + @Override + @DB + public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, Pair rootDiskOffering, + List> dataDiskOfferings, List> networks, Map params, DeploymentPlan plan, + HypervisorType hyperType, Account owner) throws InsufficientCapacityException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating entries for VM: " + vm); + } + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, params); + + vm.setDataCenterId(plan.getDataCenterId()); + if (plan.getPodId() != null) { + vm.setPodId(plan.getPodId()); + } + assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; + + @SuppressWarnings("unchecked") + VirtualMachineGuru guru = (VirtualMachineGuru) _vmGurus.get(vm.getType()); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + vm = guru.persist(vm); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating nics for " + vm); + } + + try { + _networkMgr.allocate(vmProfile, networks); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); + } + + if (dataDiskOfferings == null) { + dataDiskOfferings = new ArrayList>(0); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocaing disks for " + vm); + } + + if (template.getFormat() == ImageFormat.ISO) { + _storageMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner); + } else if (template.getFormat() == ImageFormat.BAREMETAL) { + // Do nothing + } else { + _storageMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner); + } + + for (Pair offering : dataDiskOfferings) { + _storageMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner); + } + + txn.commit(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocation completed for VM: " + vm); + } + + return vm; + } + + @Override + public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, Long rootSize, Pair dataDiskOffering, + List> networks, DeploymentPlan plan, HypervisorType hyperType, Account owner) throws InsufficientCapacityException { + List> diskOfferings = new ArrayList>(1); + if (dataDiskOffering != null) { + diskOfferings.add(dataDiskOffering); + } + return allocate(vm, template, serviceOffering, new Pair(serviceOffering, rootSize), diskOfferings, networks, null, plan, hyperType, owner); + } + + @Override + public T allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, List> networks, DeploymentPlan plan, + HypervisorType hyperType, Account owner) throws InsufficientCapacityException { + return allocate(vm, template, serviceOffering, new Pair(serviceOffering, null), null, networks, null, plan, hyperType, owner); + } + + @SuppressWarnings("unchecked") + private VirtualMachineGuru getVmGuru(T vm) { + return (VirtualMachineGuru) _vmGurus.get(vm.getType()); + } + + @SuppressWarnings("unchecked") + private VirtualMachineGuru getBareMetalVmGuru(T vm) { + return (VirtualMachineGuru) _vmGurus.get(VirtualMachine.Type.UserBareMetal); + } + + @Override + public boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException { + try { + if (advanceExpunge(vm, caller, account)) { + // Mark vms as removed + remove(vm, caller, account); + return true; + } else { + s_logger.info("Did not expunge " + vm); + return false; + } + } catch (OperationTimedoutException e) { + throw new CloudRuntimeException("Operation timed out", e); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Concurrent operation ", e); + } + } + + @Override + public boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException { + if (vm == null || vm.getRemoved() != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find vm or vm is destroyed: " + vm); + } + return true; + } + + if (!this.advanceStop(vm, false, caller, account)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to stop the VM so we can't expunge it."); + } + } + + try { + if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) { + s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); + return false; + } + } catch (NoTransitionException e) { + s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); + return false; + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Destroying vm " + vm); + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + s_logger.debug("Cleaning up NICS"); + _networkMgr.cleanupNics(profile); + // Clean up volumes based on the vm's instance id + _storageMgr.cleanupVolumes(vm.getId()); + + VirtualMachineGuru guru = getVmGuru(vm); + guru.finalizeExpunge(vm); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expunged " + vm); + } + + return true; + } + + @Override + public boolean start() { + _executor.scheduleAtFixedRate(new CleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS); + cancelWorkItems(_nodeId); + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public boolean configure(String name, Map xmlParams) throws ConfigurationException { + _name = name; + + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + Map params = configDao.getConfiguration(xmlParams); + + _retry = NumbersUtil.parseInt(params.get(Config.StartRetry.key()), 10); + + ReservationContextImpl.setComponents(_userDao, _domainDao, _accountDao); + VirtualMachineProfileImpl.setComponents(_offeringDao, _templateDao, _accountDao); + + _cancelWait = NumbersUtil.parseLong(params.get(Config.VmOpCancelInterval.key()), 3600); + _cleanupWait = NumbersUtil.parseLong(params.get(Config.VmOpCleanupWait.key()), 3600); + _cleanupInterval = NumbersUtil.parseLong(params.get(Config.VmOpCleanupInterval.key()), 86400) * 1000; + _opWaitInterval = NumbersUtil.parseLong(params.get(Config.VmOpWaitInterval.key()), 120) * 1000; + _lockStateRetry = NumbersUtil.parseInt(params.get(Config.VmOpLockStateRetry.key()), 5); + _operationTimeout = NumbersUtil.parseInt(params.get(Config.Wait.key()), 1800) * 2; + _forceStop = Boolean.parseBoolean(params.get(Config.VmDestroyForcestop.key())); + + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup")); + _nodeId = _clusterMgr.getManagementNodeId(); + + _agentMgr.registerForHostEvents(this, true, true, true); + + return true; + } + + @Override + public String getName() { + return _name; + } + + protected VirtualMachineManagerImpl() { + setStateMachine(); + } + + @Override + public T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { + return start(vm, params, caller, account, null); + } + + @Override + public T start(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, + ResourceUnavailableException { + try { + return advanceStart(vm, params, caller, account, planToDeploy); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e); + } + } + + protected boolean checkWorkItems(VMInstanceVO vm, State state) throws ConcurrentOperationException { + while (true) { + ItWorkVO vo = _workDao.findByOutstandingWork(vm.getId(), state); + if (vo == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find work for VM: " + vm + " and state: " + state); + } + return true; + } + + if (vo.getStep() == Step.Done) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Work for " + vm + " is " + vo.getStep()); + } + return true; + } + + if (vo.getSecondsTaskIsInactive() > _cancelWait) { + s_logger.warn("The task item for vm " + vm + " has been inactive for " + vo.getSecondsTaskIsInactive()); + return false; + } + + try { + Thread.sleep(_opWaitInterval); + } catch (InterruptedException e) { + s_logger.info("Waiting for " + vm + " but is interrupted"); + throw new ConcurrentOperationException("Waiting for " + vm + " but is interrupted"); + } + s_logger.debug("Waiting some more to make sure there's no activity on " + vm); + } + + } + + @DB + protected Ternary changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) + throws ConcurrentOperationException { + long vmId = vm.getId(); + + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId()); + int retry = _lockStateRetry; + while (retry-- != 0) { + Transaction txn = Transaction.currentTxn(); + Ternary result = null; + txn.start(); + try { + Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); + work = _workDao.persist(work); + ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); + + if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + } + result = new Ternary(vmGuru.findById(vmId), context, work); + txn.commit(); + return result; + } + } catch (NoTransitionException e) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to transition into Starting state due to " + e.getMessage()); + } + } finally { + if (result == null) { + txn.rollback(); + } + } + + VMInstanceVO instance = _vmDao.findById(vmId); + if (instance == null) { + throw new ConcurrentOperationException("Unable to acquire lock on " + vm); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Determining why we're unable to update the state to Starting for " + instance + ". Retry=" + retry); + } + + State state = instance.getState(); + if (state == State.Running) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is already started: " + vm); + } + return null; + } + + if (state.isTransitional()) { + if (!checkWorkItems(vm, state)) { + throw new ConcurrentOperationException("There are concurrent operations on " + vm); + } else { + continue; + } + } + + if (state != State.Stopped) { + s_logger.debug("VM " + vm + " is not in a state to be started: " + state); + return null; + } + } + + throw new ConcurrentOperationException("Unable to change the state of " + vm); + } + + protected boolean changeState(T vm, Event event, Long hostId, ItWorkVO work, Step step) throws NoTransitionException { + // FIXME: We should do this better. + Step previousStep = work.getStep(); + _workDao.updateStep(work, step); + boolean result = false; + try { + result = stateTransitTo(vm, event, hostId); + return result; + } finally { + if (!result) { + _workDao.updateStep(work, previousStep); + } + } + } + + @Override + public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + return advanceStart(vm, params, caller, account, null); + } + + @Override + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) + throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + long vmId = vm.getId(); + VirtualMachineGuru vmGuru; + if (vm.getHypervisorType() == HypervisorType.BareMetal) { + vmGuru = getBareMetalVmGuru(vm); + } else { + vmGuru = getVmGuru(vm); + } + + vm = vmGuru.findById(vm.getId()); + Ternary start = changeToStartState(vmGuru, vm, caller, account); + if (start == null) { + return vmGuru.findById(vmId); + } + + vm = start.first(); + ReservationContext ctx = start.second(); + ItWorkVO work = start.third(); + + T startedVm = null; + ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); + VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Trying to deploy VM, vm has dcId: " + vm.getDataCenterIdToDeployIn() + " and podId: " + vm.getPodIdToDeployIn()); + } + DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), null, null, null, null, ctx); + if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ + if (s_logger.isDebugEnabled()) { + s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() + ", clusterId: " + + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); + } + plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); + } + + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + + boolean canRetry = true; + try { + Journal journal = start.second().getJournal(); + + ExcludeList avoids = null; + if (planToDeploy != null) { + avoids = planToDeploy.getAvoids(); + } + if (avoids == null) { + avoids = new ExcludeList(); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); + } + + + boolean planChangedByVolume = false; + boolean reuseVolume = true; + DataCenterDeployment originalPlan = plan; + + int retry = _retry; + boolean recreate = false; + while (retry-- != 0) { // It's != so that it can match -1. + + if(reuseVolume){ + // edit plan if this vm's ROOT volume is in READY state already + List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); + for (VolumeVO vol : vols) { + // make sure if the templateId is unchanged. If it is changed, + // let planner + // reassign pool for the volume even if it ready. + Long volTemplateId = vol.getTemplateId(); + if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); + } + continue; + } + + StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); + if (!pool.isInMaintenance()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); + } + long rootVolDcId = pool.getDataCenterId(); + Long rootVolPodId = pool.getPodId(); + Long rootVolClusterId = pool.getClusterId(); + if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { + Long clusterIdSpecified = planToDeploy.getClusterId(); + if (clusterIdSpecified != null && rootVolClusterId != null) { + if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) { + // cannot satisfy the plan passed in to the + // planner + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: " + rootVolClusterId + + ", cluster specified: " + clusterIdSpecified); + } + throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + + vm, Cluster.class, clusterIdSpecified); + } + } + plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId(), null, ctx); + }else{ + plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx); + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); + } + planChangedByVolume = true; + } + } + } + } + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, account, params); + DeployDestination dest = null; + for (DeploymentPlanner planner : _planners) { + if (planner.canHandle(vmProfile, plan, avoids)) { + dest = planner.plan(vmProfile, plan, avoids); + } else { + continue; + } + if (dest != null) { + avoids.addHost(dest.getHost().getId()); + journal.record("Deployment found ", vmProfile, dest); + break; + } + } + + if (dest == null) { + if (planChangedByVolume) { + plan = originalPlan; + planChangedByVolume = false; + //do not enter volume reuse for next retry, since we want to look for resorces outside the volume's cluster + reuseVolume = false; + continue; + } + throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); + } + + long destHostId = dest.getHost().getId(); + vm.setPodId(dest.getPod().getId()); + + try { + if (!changeState(vm, Event.OperationRetry, destHostId, work, Step.Prepare)) { + throw new ConcurrentOperationException("Unable to update the state of the Virtual Machine"); + } + } catch (NoTransitionException e1) { + throw new ConcurrentOperationException(e1.getMessage()); + } + + try { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is being created in podId: " + vm.getPodIdToDeployIn()); + } + _networkMgr.prepare(vmProfile, dest, ctx); + if (vm.getHypervisorType() != HypervisorType.BareMetal) { + _storageMgr.prepare(vmProfile, dest, recreate); + recreate = false; + } + //since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity + if(!reuseVolume){ + reuseVolume = true; + } + + Commands cmds = null; + vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); + + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + cmds = new Commands(OnError.Stop); + cmds.addCommand(new StartCommand(vmTO)); + + vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); + + + work = _workDao.findById(work.getId()); + if (work == null || work.getStep() != Step.Prepare) { + throw new ConcurrentOperationException("Work steps have been changed: " + work); + } + _workDao.updateStep(work, Step.Starting); + + _agentMgr.send(destHostId, cmds); + + _workDao.updateStep(work, Step.Started); + + + StartAnswer startAnswer = cmds.getAnswer(StartAnswer.class); + if (startAnswer != null && startAnswer.getResult()) { + String host_guid = startAnswer.getHost_guid(); + if( host_guid != null ) { + HostVO finalHost = _resourceMgr.findHostByGuid(host_guid); + if (finalHost == null ) { + throw new CloudRuntimeException("Host Guid " + host_guid + " doesn't exist in DB, something wrong here"); + } + destHostId = finalHost.getId(); + } + if (vmGuru.finalizeStart(vmProfile, destHostId, cmds, ctx)) { + if (!changeState(vm, Event.OperationSucceeded, destHostId, work, Step.Done)) { + throw new ConcurrentOperationException("Unable to transition to a new state."); + } + startedVm = vm; + if (s_logger.isDebugEnabled()) { + s_logger.debug("Start completed for VM " + vm); + } + return startedVm; + } else { + if (s_logger.isDebugEnabled()) { + s_logger.info("The guru did not like the answers so stopping " + vm); + } + + StopCommand cmd = new StopCommand(vm.getInstanceName()); + StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); + _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); + throw new ExecutionException("Unable to stop " + vm + " so we are unable to retry the start operation"); + } + if (vmGuru.recreateNeeded(vmProfile, destHostId, cmds, ctx)) { + recreate = true; + } else { + throw new ExecutionException("Unable to start " + vm + " due to error in finalizeStart, not retrying"); + } + } + } + s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails())); + + } catch (OperationTimedoutException e) { + s_logger.debug("Unable to send the start command to host " + dest.getHost()); + if (e.isActive()) { + _haMgr.scheduleStop(vm, destHostId, WorkType.CheckStop); + } + canRetry = false; + throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e); + } catch (ResourceUnavailableException e) { + s_logger.info("Unable to contact resource.", e); + if (!avoids.add(e)) { + if (e.getScope() == Volume.class || e.getScope() == Nic.class) { + throw e; + } else { + s_logger.warn("unexpected ResourceUnavailableException : " + e.getScope().getName(), e); + throw e; + } + } + } catch (InsufficientCapacityException e) { + s_logger.info("Insufficient capacity ", e); + if (!avoids.add(e)) { + if (e.getScope() == Volume.class || e.getScope() == Nic.class) { + throw e; + } else { + s_logger.warn("unexpected InsufficientCapacityException : " + e.getScope().getName(), e); + } + } + } catch (Exception e) { + s_logger.error("Failed to start instance " + vm, e); + throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e); + } finally { + if (startedVm == null && canRetry) { + Step prevStep = work.getStep(); + _workDao.updateStep(work, Step.Release); + if (prevStep == Step.Started || prevStep == Step.Starting) { + cleanup(vmGuru, vmProfile, work, Event.OperationFailed, false, caller, account); + } else { + //if step is not starting/started, send cleanup command with force=true + cleanup(vmGuru, vmProfile, work, Event.OperationFailed, true, caller, account); + } + } + } + } + } finally { + if (startedVm == null) { + if (canRetry) { + try { + changeState(vm, Event.OperationFailed, null, work, Step.Done); + } catch (NoTransitionException e) { + throw new ConcurrentOperationException(e.getMessage()); + } + } + } + } + + return startedVm; + } + + @Override + public boolean stop(T vm, User user, Account account) throws ResourceUnavailableException { + try { + return advanceStop(vm, false, user, account); + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", vm.getHostId(), e); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e); + } + } + + protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { + VMInstanceVO vm = profile.getVirtualMachine(); + StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); + try { + Answer answer = _agentMgr.send(vm.getHostId(), stop); + if (!answer.getResult()) { + s_logger.debug("Unable to stop VM due to " + answer.getDetails()); + return false; + } + + guru.finalizeStop(profile, (StopAnswer) answer); + } catch (AgentUnavailableException e) { + if (!force) { + return false; + } + } catch (OperationTimedoutException e) { + if (!force) { + return false; + } + } + + return true; + } + + protected boolean cleanup(VirtualMachineGuru guru, VirtualMachineProfile profile, ItWorkVO work, Event event, boolean force, User user, Account account) { + T vm = profile.getVirtualMachine(); + State state = vm.getState(); + s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state"); + if (state == State.Starting) { + Step step = work.getStep(); + if (step == Step.Starting && !force) { + s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step); + return false; + } + + if (step == Step.Started || step == Step.Starting || step == Step.Release) { + if (vm.getHostId() != null) { + if (!sendStop(guru, profile, force)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process"); + return false; + } + } + } + + if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) { + s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step); + return true; + } + } else if (state == State.Stopping) { + if (vm.getHostId() != null) { + if (!sendStop(guru, profile, force)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process"); + return false; + } + } + } else if (state == State.Migrating) { + if (vm.getHostId() != null) { + if (!sendStop(guru, profile, force)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); + return false; + } + } + if (vm.getLastHostId() != null) { + if (!sendStop(guru, profile, force)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process"); + return false; + } + } + } else if (state == State.Running) { + if (!sendStop(guru, profile, force)) { + s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process"); + return false; + } + } + + try { + _networkMgr.release(profile, force); + s_logger.debug("Successfully released network resources for the vm " + vm); + } catch (Exception e) { + s_logger.warn("Unable to release some network resources.", e); + } + + _storageMgr.release(profile); + s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state"); + return true; + } + + @Override + public boolean advanceStop(T vm, boolean forced, User user, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException { + State state = vm.getState(); + if (state == State.Stopped) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is already stopped: " + vm); + } + return true; + } + + if (state == State.Destroyed || state == State.Expunging || state == State.Error) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Stopped called on " + vm + " but the state is " + state); + } + return true; + } + // grab outstanding work item if any + ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId()); + } + } + Long hostId = vm.getHostId(); + if (hostId == null) { + if (!forced) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState()); + } + return false; + } + try { + stateTransitTo(vm, Event.AgentReportStopped, null, null); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + // mark outstanding work item if any as done + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating work item to Done, id:" + work.getId()); + } + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + return true; + } + + VirtualMachineGuru vmGuru = getVmGuru(vm); + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + + try { + if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) { + throw new ConcurrentOperationException("VM is being operated on."); + } + } catch (NoTransitionException e1) { + if (!forced) { + throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState()); + } + boolean doCleanup = false; + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to transition the state but we're moving on because it's forced stop"); + } + if (state == State.Starting || state == State.Migrating) { + if (work != null) { + doCleanup = true; + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to cleanup VM: " + vm + " ,since outstanding work item is not found"); + } + throw new CloudRuntimeException("Work item not found, We cannot stop " + vm + " when it is in state " + vm.getState()); + } + } else if (state == State.Stopping) { + doCleanup = true; + } + + if (doCleanup) { + if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, forced, user, account)) { + try { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating work item to Done, id:" + work.getId()); + } + return changeState(vm, Event.AgentReportStopped, null, work, Step.Done); + } catch (NoTransitionException e) { + s_logger.warn("Unable to cleanup " + vm); + return false; + } + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Failed to cleanup VM: " + vm); + } + throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState()); + } + } + } + + if (vm.getState() != State.Stopping) { + throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState()); + } + + vmGuru.prepareStop(profile); + + StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); + boolean stopped = false; + StopAnswer answer = null; + try { + answer = (StopAnswer) _agentMgr.send(vm.getHostId(), stop); + stopped = answer.getResult(); + if (!stopped) { + throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); + } + vmGuru.finalizeStop(profile, answer); + + } catch (AgentUnavailableException e) { + } catch (OperationTimedoutException e) { + } finally { + if (!stopped) { + if (!forced) { + s_logger.warn("Unable to stop vm " + vm); + try { + stateTransitTo(vm, Event.OperationFailed, vm.getHostId()); + } catch (NoTransitionException e) { + s_logger.warn("Unable to transition the state " + vm); + } + return false; + } else { + s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop"); + vmGuru.finalizeStop(profile, answer); + } + } + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug(vm + " is stopped on the host. Proceeding to release resource held."); + } + + try { + _networkMgr.release(profile, forced); + s_logger.debug("Successfully released network resources for the vm " + vm); + } catch (Exception e) { + s_logger.warn("Unable to release some network resources.", e); + } + + try { + if (vm.getHypervisorType() != HypervisorType.BareMetal) { + _storageMgr.release(profile); + s_logger.debug("Successfully released storage resources for the vm " + vm); + } + } catch (Exception e) { + s_logger.warn("Unable to release storage resources.", e); + } + + try { + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId()); + } + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + + return stateTransitTo(vm, Event.OperationSucceeded, null, null); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + return false; + } + } + + private void setStateMachine() { + _stateMachine = VirtualMachine.State.getStateMachine(); + } + + protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) throws NoTransitionException { + vm.setReservationId(reservationId); + return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); + } + + @Override + public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException { + State oldState = vm.getState(); + if (oldState == State.Starting) { + if (e == Event.OperationSucceeded) { + vm.setLastHostId(hostId); + } + } else if (oldState == State.Stopping) { + if (e == Event.OperationSucceeded) { + vm.setLastHostId(vm.getHostId()); + } + } + return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); + } + + @Override + public boolean remove(T vm, User user, Account caller) { + return _vmDao.remove(vm.getId()); + } + + @Override + public boolean destroy(T vm, User user, Account caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Destroying vm " + vm); + } + if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find vm or vm is destroyed: " + vm); + } + return true; + } + + if (!advanceStop(vm, _forceStop, user, caller)) { + s_logger.debug("Unable to stop " + vm); + return false; + } + + try { + if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) { + s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm); + return false; + } + } catch (NoTransitionException e) { + s_logger.debug(e.getMessage()); + return false; + } + + return true; + } + + protected boolean checkVmOnHost(VirtualMachine vm, long hostId) throws AgentUnavailableException, OperationTimedoutException { + CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName())); + if (!answer.getResult() || answer.getState() == State.Stopped) { + return false; + } + + return true; + } + + @Override + public T storageMigration(T vm, StoragePool destPool) { + VirtualMachineGuru vmGuru = getVmGuru(vm); + + long vmId = vm.getId(); + vm = vmGuru.findById(vmId); + + try { + stateTransitTo(vm, VirtualMachine.Event.StorageMigrationRequested, null); + } catch (NoTransitionException e) { + s_logger.debug("Unable to migrate vm: " + e.toString()); + throw new CloudRuntimeException("Unable to migrate vm: " + e.toString()); + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + boolean migrationResult = false; + try { + migrationResult = _storageMgr.StorageMigration(profile, destPool); + + if (migrationResult) { + //if the vm is migrated to different pod in basic mode, need to reallocate ip + + if (vm.getPodIdToDeployIn() != destPool.getPodId()) { + DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterIdToDeployIn(), destPool.getPodId(), null, null, null, null); + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, null, null, null, null); + _networkMgr.reallocate(vmProfile, plan); + } + + //when start the vm next time, don;'t look at last_host_id, only choose the host based on volume/storage pool + vm.setLastHostId(null); + vm.setPodId(destPool.getPodId()); + } else { + s_logger.debug("Storage migration failed"); + } + } catch (ConcurrentOperationException e) { + s_logger.debug("Failed to migration: " + e.toString()); + throw new CloudRuntimeException("Failed to migration: " + e.toString()); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.debug("Failed to migration: " + e.toString()); + throw new CloudRuntimeException("Failed to migration: " + e.toString()); + } catch (InsufficientAddressCapacityException e) { + s_logger.debug("Failed to migration: " + e.toString()); + throw new CloudRuntimeException("Failed to migration: " + e.toString()); + } catch (InsufficientCapacityException e) { + s_logger.debug("Failed to migration: " + e.toString()); + throw new CloudRuntimeException("Failed to migration: " + e.toString()); + } finally { + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); + } catch (NoTransitionException e) { + s_logger.debug("Failed to change vm state: " + e.toString()); + throw new CloudRuntimeException("Failed to change vm state: " + e.toString()); + } + } + + return vm; + } + + @Override + public T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, + VirtualMachineMigrationException { + s_logger.info("Migrating " + vm + " to " + dest); + + long dstHostId = dest.getHost().getId(); + Host fromHost = _hostDao.findById(srcHostId); + if (fromHost == null) { + s_logger.info("Unable to find the host to migrate from: " + srcHostId); + throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId); + } + + if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) { + s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); + throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); + } + + VirtualMachineGuru vmGuru = getVmGuru(vm); + + long vmId = vm.getId(); + vm = vmGuru.findById(vmId); + if (vm == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find the vm " + vm); + } + throw new ManagementServerException("Unable to find a virtual machine with id " + vmId); + } + + if (vm.getState() != State.Running) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is not Running, unable to migrate the vm " + vm); + } + throw new VirtualMachineMigrationException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString()); + } + + short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; + if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; + } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + _networkMgr.prepareNicForMigration(profile, dest); + _storageMgr.prepareForMigration(profile, dest); + + VirtualMachineTO to = toVmTO(profile); + PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); + + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId()); + work.setStep(Step.Prepare); + work.setResourceType(ItWorkVO.ResourceType.Host); + work.setResourceId(dstHostId); + work = _workDao.persist(work); + + PrepareForMigrationAnswer pfma = null; + try { + pfma = (PrepareForMigrationAnswer) _agentMgr.send(dstHostId, pfmc); + if (!pfma.getResult()) { + String msg = "Unable to prepare for migration due to " + pfma.getDetails(); + pfma = null; + throw new AgentUnavailableException(msg, dstHostId); + } + } catch (OperationTimedoutException e1) { + throw new AgentUnavailableException("Operation timed out", dstHostId); + } finally { + if (pfma == null) { + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + } + + vm.setLastHostId(srcHostId); + try { + if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) { + s_logger.info("Migration cancelled because state has changed: " + vm); + throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm); + } + } catch (NoTransitionException e1) { + s_logger.info("Migration cancelled because " + e1.getMessage()); + throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage()); + } + + boolean migrated = false; + try { + boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); + MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows); + mc.setHostGuid(dest.getHost().getGuid()); + + try { + MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc); + if (!ma.getResult()) { + s_logger.error("Unable to migrate due to " + ma.getDetails()); + return null; + } + } catch (OperationTimedoutException e) { + if (e.isActive()) { + s_logger.warn("Active migration command so scheduling a restart for " + vm); + _haMgr.scheduleRestart(vm, true); + } + throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId); + } + + try { + if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) { + throw new ConcurrentOperationException("Unable to change the state for " + vm); + } + } catch (NoTransitionException e1) { + throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage()); + } + + try { + if (!checkVmOnHost(vm, dstHostId)) { + s_logger.error("Unable to complete migration for " + vm); + try { + _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null); + } catch (AgentUnavailableException e) { + s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId); + } + cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + return null; + } + } catch (OperationTimedoutException e) { + } + + migrated = true; + return vm; + } finally { + if (!migrated) { + s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); + + _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs."); + try { + _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null); + } catch (AgentUnavailableException ae) { + s_logger.info("Looks like the destination Host is unavailable for cleanup"); + } + + try { + stateTransitTo(vm, Event.OperationFailed, srcHostId); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + } + + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + } + + @Override + public VirtualMachineTO toVmTO(VirtualMachineProfile profile) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO to = hvGuru.implement(profile); + return to; + } + + protected void cancelWorkItems(long nodeId) { + GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem"); + + try { + if (scanLock.lock(3)) { + try { + List works = _workDao.listWorkInProgressFor(nodeId); + for (ItWorkVO work : works) { + s_logger.info("Handling unfinished work item: " + work); + try { + VMInstanceVO vm = _vmDao.findById(work.getInstanceId()); + if (vm != null) { + if (work.getType() == State.Starting) { + _haMgr.scheduleRestart(vm, true); + work.setManagementServerId(_nodeId); + _workDao.update(work.getId(), work); + } else if (work.getType() == State.Stopping) { + _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop); + work.setManagementServerId(_nodeId); + _workDao.update(work.getId(), work); + } else if (work.getType() == State.Migrating) { + _haMgr.scheduleMigration(vm); + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + } + } catch (Exception e) { + s_logger.error("Error while handling " + work, e); + } + } + } finally { + scanLock.unlock(); + } + } + } finally { + scanLock.releaseRef(); + } + } + + @Override + public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException { + VirtualMachineGuru vmGuru = _vmGurus.get(vmType); + VMInstanceVO vm = vmGuru.findById(vmId); + if (vm == null) { + s_logger.debug("Unable to find a VM for " + vmId); + return true; + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + + Long hostId = vm.getHostId(); + if (hostId == null) { + s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm); + return true; + } + + Host host = _hostDao.findById(hostId); + + DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null); + ExcludeList excludes = new ExcludeList(); + excludes.addHost(hostId); + + DeployDestination dest = null; + while (true) { + for (DeploymentPlanner planner : _planners) { + if (planner.canHandle(profile, plan, excludes)) { + dest = planner.plan(profile, plan, excludes); + } else { + continue; + } + + if (dest != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Planner " + planner + " found " + dest + " for migrating to."); + } + break; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Planner " + planner + " was unable to find anything."); + } + } + + if (dest == null) { + throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId()); + } + + excludes.addHost(dest.getHost().getId()); + VMInstanceVO vmInstance = null; + try { + vmInstance = migrate(vm, srcHostId, dest); + } catch (ResourceUnavailableException e) { + s_logger.debug("Unable to migrate to unavailable " + dest); + } catch (ConcurrentOperationException e) { + s_logger.debug("Unable to migrate VM due to: " + e.getMessage()); + } catch (ManagementServerException e) { + s_logger.debug("Unable to migrate VM: " + e.getMessage()); + } catch (VirtualMachineMigrationException e) { + s_logger.debug("Got VirtualMachineMigrationException, Unable to migrate: " + e.getMessage()); + if (vm.getState() == State.Starting) { + s_logger.debug("VM seems to be still Starting, we should retry migration later"); + throw e; + } else { + s_logger.debug("Unable to migrate VM, VM is not in Running or even Starting state, current state: " + vm.getState().toString()); + } + } + if (vmInstance != null) { + return true; + } + try { + boolean result = advanceStop(vm, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + return result; + } catch (ResourceUnavailableException e) { + s_logger.debug("Unable to stop VM due to " + e.getMessage()); + } catch (ConcurrentOperationException e) { + s_logger.debug("Unable to stop VM due to " + e.getMessage()); + } catch (OperationTimedoutException e) { + s_logger.debug("Unable to stop VM due to " + e.getMessage()); + } + return false; + } + } + + protected class CleanupTask implements Runnable { + @Override + public void run() { + s_logger.trace("VM Operation Thread Running"); + try { + _workDao.cleanup(_cleanupWait); + } catch (Exception e) { + s_logger.error("VM Operations failed due to ", e); + } + } + } + + @Override + public boolean isVirtualMachineUpgradable(VirtualMachine vm, ServiceOffering offering) { + Enumeration en = _hostAllocators.enumeration(); + boolean isMachineUpgradable = true; + while (isMachineUpgradable && en.hasMoreElements()) { + final HostAllocator allocator = en.nextElement(); + isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering); + } + + return isMachineUpgradable; + } + + @Override + public T reboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { + try { + return advanceReboot(vm, params, caller, account); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Unable to reboot a VM due to concurrent operation", e); + } + } + + @Override + public T advanceReboot(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + T rebootedVm = null; + + DataCenter dc = _configMgr.getZone(vm.getDataCenterIdToDeployIn()); + Host host = _hostDao.findById(vm.getHostId()); + Cluster cluster = null; + if (host != null) { + cluster = _configMgr.getCluster(host.getClusterId()); + } + HostPodVO pod = _configMgr.getPod(host.getPodId()); + DeployDestination dest = new DeployDestination(dc, pod, cluster, host); + + try { + + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand(new RebootCommand(vm.getInstanceName())); + _agentMgr.send(host.getId(), cmds); + + Answer rebootAnswer = cmds.getAnswer(RebootAnswer.class); + if (rebootAnswer != null && rebootAnswer.getResult()) { + rebootedVm = vm; + return rebootedVm; + } + s_logger.info("Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? " no reboot answer" : rebootAnswer.getDetails())); + } catch (OperationTimedoutException e) { + s_logger.warn("Unable to send the reboot command to host " + dest.getHost() + " for the vm " + vm + " due to operation timeout", e); + throw new CloudRuntimeException("Failed to reboot the vm on host " + dest.getHost()); + } + + return rebootedVm; + } + + @Override + public VMInstanceVO findByIdAndType(VirtualMachine.Type type, long vmId) { + VirtualMachineGuru guru = _vmGurus.get(type); + return guru.findById(vmId); + } + + public Command cleanup(String vmName) { + return new StopCommand(vmName); + } + + public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { + Commands commands = new Commands(OnError.Continue); + + Map infos = convertToInfos(startup); + + final List vms = _vmDao.listByHostId(hostId); + s_logger.debug("Found " + vms.size() + " VMs for host " + hostId); + for (VMInstanceVO vm : vms) { + AgentVmInfo info = infos.remove(vm.getId()); + VMInstanceVO castedVm = null; + if (info == null) { + info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped); + } + castedVm = info.guru.findById(vm.getId()); + + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(castedVm.getHypervisorType()); + Command command = compareState(hostId, castedVm, info, true, hvGuru.trackVmHostChange()); + if (command != null) { + commands.addCommand(command); + } + } + + for (final AgentVmInfo left : infos.values()) { + boolean found = false; + for (VirtualMachineGuru vmGuru : _vmGurus.values()) { + VMInstanceVO vm = vmGuru.findByName(left.name); + if (vm != null) { + found = true; + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + if(hvGuru.trackVmHostChange()) { + Command command = compareState(hostId, vm, left, true, true); + if (command != null) { + commands.addCommand(command); + } + } else { + s_logger.warn("Stopping a VM, VM " + left.name + " migrate from Host " + vm.getHostId() + " to Host " + hostId ); + commands.addCommand(cleanup(left.name)); + } + break; + } + } + if ( ! found ) { + s_logger.warn("Stopping a VM that we have no record of : " + left.name); + commands.addCommand(cleanup(left.name)); + } + } + + return commands; + } + + public Commands deltaHostSync(long hostId, Map newStates) { + Map states = convertDeltaToInfos(newStates); + Commands commands = new Commands(OnError.Continue); + + for (Map.Entry entry : states.entrySet()) { + AgentVmInfo info = entry.getValue(); + + VMInstanceVO vm = info.vm; + + Command command = null; + if (vm != null) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + command = compareState(hostId, vm, info, false, hvGuru.trackVmHostChange()); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cleaning up a VM that is no longer found: " + info.name); + } + command = cleanup(info.name); + } + + if (command != null) { + commands.addCommand(command); + } + } + + return commands; + } + + + + public void deltaSync(Map> newStates) { + Map states = convertToInfos(newStates); + + for (Map.Entry entry : states.entrySet()) { + AgentVmInfo info = entry.getValue(); + VMInstanceVO vm = info.vm; + Command command = null; + if (vm != null) { + Host host = _resourceMgr.findHostByGuid(info.getHostUuid()); + long hId = host.getId(); + + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + command = compareState(hId, vm, info, false, hvGuru.trackVmHostChange()); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cleaning up a VM that is no longer found : " + info.name); + } + command = cleanup(info.name); + } + if (command != null){ + try { + Host host = _resourceMgr.findHostByGuid(info.getHostUuid()); + if (host != null){ + Answer answer = _agentMgr.send(host.getId(), cleanup(info.name)); + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to stop a VM due to " + e.getMessage()); + } + } + } + } + + + public void fullSync(final long clusterId, Map> newStates) { + if (newStates==null)return; + Map infos = convertToInfos(newStates); + Set set_vms = Collections.synchronizedSet(new HashSet()); + set_vms.addAll(_vmDao.listByClusterId(clusterId)); + set_vms.addAll(_vmDao.listLHByClusterId(clusterId)); + + for (VMInstanceVO vm : set_vms) { + if (vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) continue; + AgentVmInfo info = infos.remove(vm.getId()); + VMInstanceVO castedVm = null; + if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting)) + || (info != null && (info.state == State.Running && vm.getState() == State.Starting))) + { + s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + " on agent"); + info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped); + + // Bug 13850- grab outstanding work item if any for this VM state so that we mark it as DONE after we change VM state, else it will remain pending + ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found an outstanding work item for this vm " + vm + " in state:" + vm.getState() + ", work id:" + work.getId()); + } + } + vm.setState(State.Running); // set it as running and let HA take care of it + _vmDao.persist(vm); + + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating outstanding work item to Done, id:" + work.getId()); + } + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + + castedVm = info.guru.findById(vm.getId()); + try { + Host host = _hostDao.findByGuid(info.getHostUuid()); + long hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId(); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(castedVm.getHypervisorType()); + Command command = compareState(hostId, castedVm, info, true, hvGuru.trackVmHostChange()); + if (command != null){ + Answer answer = _agentMgr.send(hostId, command); + if (!answer.getResult()) { + s_logger.warn("Failed to update state of the VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to update state of the VM due to exception " + e.getMessage()); + e.printStackTrace(); + } + } + else if (info != null && (vm.getState() == State.Stopped || vm.getState() == State.Stopping)) { + Host host = _hostDao.findByGuid(info.getHostUuid()); + if (host != null){ + s_logger.warn("Stopping a VM which is stopped/stopping " + info.name); + vm.setState(State.Stopped); // set it as stop and clear it from host + vm.setHostId(null); + _vmDao.persist(vm); + try { + Answer answer = _agentMgr.send(host.getId(), cleanup(info.name)); + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + } + } + catch (Exception e) { + s_logger.warn("Unable to stop a VM due to " + e.getMessage()); + } + } + } + else + // host id can change + if (info != null && vm.getState() == State.Running){ + // check for host id changes + Host host = _hostDao.findByGuid(info.getHostUuid()); + if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())){ + s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + } + } + /* else if(info == null && vm.getState() == State.Stopping) { //Handling CS-13376 + s_logger.warn("Marking the VM as Stopped as it was still stopping on the CS" +vm.getName()); + vm.setState(State.Stopped); // Setting the VM as stopped on the DB and clearing it from the host + vm.setLastHostId(vm.getHostId()); + vm.setHostId(null); + _vmDao.persist(vm); + }*/ + } + + for (final AgentVmInfo left : infos.values()) { + if (VirtualMachineName.isValidVmName(left.name)) continue; // if the vm follows cloudstack naming ignore it for stopping + try { + Host host = _hostDao.findByGuid(left.getHostUuid()); + if (host != null){ + s_logger.warn("Stopping a VM which we do not have any record of " + left.name); + Answer answer = _agentMgr.send(host.getId(), cleanup(left.name)); + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Unable to stop a VM due to " + e.getMessage()); + } + } + + } + + + + protected Map convertToInfos(final Map> newStates) { + final HashMap map = new HashMap(); + if (newStates == null) { + return map; + } + Collection> vmGurus = _vmGurus.values(); + boolean is_alien_vm = true; + long alien_vm_count = -1; + for (Map.Entry> entry : newStates.entrySet()) { + is_alien_vm = true; + for (VirtualMachineGuru vmGuru : vmGurus) { + String name = entry.getKey(); + VMInstanceVO vm = vmGuru.findByName(name); + if (vm != null) { + map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue().second(), entry.getValue().first())); + is_alien_vm = false; + break; + } + Long id = vmGuru.convertToId(name); + if (id != null) { + map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null, entry.getValue().second(), entry.getValue().first())); + is_alien_vm = false; + break; + } + } + // alien VMs + if (is_alien_vm){ + map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, null, entry.getValue().second(), entry.getValue().first())); + s_logger.warn("Found an alien VM " + entry.getKey()); + } + } + return map; + } + + protected Map convertToInfos(StartupRoutingCommand cmd) { + final Map states = cmd.getVmStates(); + final HashMap map = new HashMap(); + if (states == null) { + return map; + } + Collection> vmGurus = _vmGurus.values(); + + for (Map.Entry entry : states.entrySet()) { + for (VirtualMachineGuru vmGuru : vmGurus) { + String name = entry.getKey(); + VMInstanceVO vm = vmGuru.findByName(name); + if (vm != null) { + map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue().getState(), entry.getValue().getHost() )); + break; + } + Long id = vmGuru.convertToId(name); + if (id != null) { + map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null,entry.getValue().getState(), entry.getValue().getHost() )); + break; + } + } + } + + return map; + } + + protected Map convertDeltaToInfos(final Map states) { + final HashMap map = new HashMap(); + + if (states == null) { + return map; + } + + Collection> vmGurus = _vmGurus.values(); + + for (Map.Entry entry : states.entrySet()) { + for (VirtualMachineGuru vmGuru : vmGurus) { + String name = entry.getKey(); + + VMInstanceVO vm = vmGuru.findByName(name); + + if (vm != null) { + map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vmGuru, vm, entry.getValue())); + break; + } + + Long id = vmGuru.convertToId(name); + if (id != null) { + map.put(id, new AgentVmInfo(entry.getKey(), vmGuru, null,entry.getValue())); + break; + } + } + } + + return map; + } + + + + /** + * compareState does as its name suggests and compares the states between + * management server and agent. It returns whether something should be + * cleaned up + * + */ + protected Command compareState(long hostId, VMInstanceVO vm, final AgentVmInfo info, final boolean fullSync, boolean trackExternalChange) { + State agentState = info.state; + final String agentName = info.name; + final State serverState = vm.getState(); + final String serverName = vm.getInstanceName(); + + Command command = null; + s_logger.debug("VM " + serverName + ": cs state = " + serverState + " and realState = " + agentState); + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM " + serverName + ": cs state = " + serverState + " and realState = " + agentState); + } + + if (agentState == State.Error) { + agentState = State.Stopped; + + short alertType = AlertManager.ALERT_TYPE_USERVM; + if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER; + } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY; + } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_SSVM; + } + + HostPodVO podVO = _podDao.findById(vm.getPodIdToDeployIn()); + DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterIdToDeployIn()); + HostVO hostVO = _hostDao.findById(vm.getHostId()); + + String hostDesc = "name: " + hostVO.getName() + " (id:" + hostVO.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); + _alertMgr.sendAlert(alertType, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getInstanceName() + ", id: " + vm.getId() + ") stopped on host " + hostDesc + + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped due to storage failure."); + } + + if (trackExternalChange) { + if (serverState == State.Starting) { + if (vm.getHostId() != null && vm.getHostId() != hostId) { + s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + ", skip status sync for vm: " + + vm.getInstanceName()); + return null; + } + } + if (vm.getHostId() == null || hostId != vm.getHostId()) { + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); + } catch (NoTransitionException e) { + } + } + } + + // during VM migration time, don't sync state will agent status update + if (serverState == State.Migrating) { + s_logger.debug("Skipping vm in migrating state: " + vm); + return null; + } + + if (trackExternalChange) { + if (serverState == State.Starting) { + if (vm.getHostId() != null && vm.getHostId() != hostId) { + s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + ", skip status sync for vm: " + + vm.getInstanceName()); + return null; + } + } + + if (serverState == State.Running) { + try { + // + // we had a bug that sometimes VM may be at Running State + // but host_id is null, we will cover it here. + // means that when CloudStack DB lost of host information, + // we will heal it with the info reported from host + // + if (vm.getHostId() == null || hostId != vm.getHostId()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("detected host change when VM " + vm + " is at running state, VM could be live-migrated externally from host " + vm.getHostId() + " to host " + hostId); + } + + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); + } + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + } + } + + if (agentState == serverState) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Both states are " + agentState + " for " + vm); + } + assert (agentState == State.Stopped || agentState == State.Running) : "If the states we send up is changed, this must be changed."; + if (agentState == State.Running) { + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportRunning, hostId); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + // FIXME: What if someone comes in and sets it to stopping? Then + // what? + return null; + } + + s_logger.debug("State matches but the agent said stopped so let's send a cleanup command anyways."); + return cleanup(agentName); + } + + if (agentState == State.Shutdowned) { + if (serverState == State.Running || serverState == State.Starting || serverState == State.Stopping) { + try { + advanceStop(vm, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + } catch (AgentUnavailableException e) { + assert (false) : "How do we hit this with forced on?"; + return null; + } catch (OperationTimedoutException e) { + assert (false) : "How do we hit this with forced on?"; + return null; + } catch (ConcurrentOperationException e) { + assert (false) : "How do we hit this with forced on?"; + return null; + } + } else { + s_logger.debug("Sending cleanup to a shutdowned vm: " + agentName); + command = cleanup(agentName); + } + } else if (agentState == State.Stopped) { + // This state means the VM on the agent was detected previously + // and now is gone. This is slightly different than if the VM + // was never completed but we still send down a Stop Command + // to ensure there's cleanup. + if (serverState == State.Running) { + // Our records showed that it should be running so let's restart + // it. + _haMgr.scheduleRestart(vm, false); + } else if (serverState == State.Stopping) { + _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop); + s_logger.debug("Scheduling a check stop for VM in stopping mode: " + vm); + } else if (serverState == State.Starting) { + s_logger.debug("Ignoring VM in starting mode: " + vm.getInstanceName()); + _haMgr.scheduleRestart(vm, false); + } + command = cleanup(agentName); + } else if (agentState == State.Running) { + if (serverState == State.Starting) { + if (fullSync) { + try { + ensureVmRunningContext(hostId, vm, Event.AgentReportRunning); + } catch (OperationTimedoutException e) { + s_logger.error("Exception during update for running vm: " + vm, e); + return null; + } catch (ResourceUnavailableException e) { + s_logger.error("Exception during update for running vm: " + vm, e); + return null; + }catch (InsufficientAddressCapacityException e) { + s_logger.error("Exception during update for running vm: " + vm, e); + return null; + }catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + } + } else if (serverState == State.Stopping) { + s_logger.debug("Scheduling a stop command for " + vm); + _haMgr.scheduleStop(vm, hostId, WorkType.Stop); + } else { + s_logger.debug("server VM state " + serverState + " does not meet expectation of a running VM report from agent"); + + // just be careful not to stop VM for things we don't handle + // command = cleanup(agentName); + } + } + return command; + } + + private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, NoTransitionException, InsufficientAddressCapacityException { + VirtualMachineGuru vmGuru = getVmGuru(vm); + + s_logger.debug("VM state is starting on full sync so updating it to running"); + vm = findByIdAndType(vm.getType(), vm.getId()); + + // grab outstanding work item if any + ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState()); + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found an outstanding work item for this vm " + vm + " in state:" + vm.getState() + ", work id:" + work.getId()); + } + } + + try { + stateTransitTo(vm, cause, hostId); + } catch (NoTransitionException e1) { + s_logger.warn(e1.getMessage()); + } + + s_logger.debug("VM's " + vm + " state is starting on full sync so updating it to Running"); + vm = vmGuru.findById(vm.getId()); // this should ensure vm has the most + // up to date info + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + List nics = _nicsDao.listByVmId(profile.getId()); + for (NicVO nic : nics) { + Network network = _networkMgr.getNetwork(nic.getNetworkId()); + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); + profile.addNic(nicProfile); + } + + Commands cmds = new Commands(OnError.Stop); + s_logger.debug("Finalizing commands that need to be send to complete Start process for the vm " + vm); + + if (vmGuru.finalizeCommandsOnStart(cmds, profile)) { + if (cmds.size() != 0) { + _agentMgr.send(vm.getHostId(), cmds); + } + + if (vmGuru.finalizeStart(profile, vm.getHostId(), cmds, null)) { + stateTransitTo(vm, cause, vm.getHostId()); + } else { + s_logger.error("Unable to finish finialization for running vm: " + vm); + } + } else { + s_logger.error("Unable to finalize commands on start for vm: " + vm); + } + + if (work != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating outstanding work item to Done, id:" + work.getId()); + } + work.setStep(Step.Done); + _workDao.update(work.getId(), work); + } + } + + @Override + public boolean isRecurring() { + return true; + } + + @Override + public boolean processAnswers(long agentId, long seq, Answer[] answers) { + for (final Answer answer : answers) { + if (answer instanceof ClusterSyncAnswer) { + ClusterSyncAnswer hs = (ClusterSyncAnswer) answer; + if (!hs.isExceuted()){ + deltaSync(hs.getNewStates()); + hs.setExecuted(); + } + } + } + return true; + } + + @Override + public boolean processTimeout(long agentId, long seq) { + return true; + } + + @Override + public int getTimeout() { + return -1; + } + + @Override + public boolean processCommands(long agentId, long seq, Command[] cmds) { + boolean processed = false; + for (Command cmd : cmds) { + if (cmd instanceof PingRoutingCommand) { + PingRoutingCommand ping = (PingRoutingCommand) cmd; + if (ping.getNewStates() != null && ping.getNewStates().size() > 0) { + Commands commands = deltaHostSync(agentId, ping.getNewStates()); + if (commands.size() > 0) { + try { + _agentMgr.send(agentId, commands, this); + } catch (final AgentUnavailableException e) { + s_logger.warn("Agent is now unavailable", e); + } + } + } + processed = true; + } + } + return processed; + } + + @Override + public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { + return null; + } + + @Override + public boolean processDisconnect(long agentId, Status state) { + return true; + } + + @Override + public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + if (!(cmd instanceof StartupRoutingCommand)) { + return; + } + + if (forRebalance) { + s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process"); + return; + } + + if (forRebalance) { + s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process"); + return; + } + + Long clusterId = agent.getClusterId(); + long agentId = agent.getId(); + if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen + StartupRoutingCommand startup = (StartupRoutingCommand) cmd; + HashMap> allStates = startup.getClusterVMStateChanges(); + if (allStates != null){ + this.fullSync(clusterId, allStates); + } + + // initiate the cron job + ClusterSyncCommand syncCmd = new ClusterSyncCommand(Integer.parseInt(Config.ClusterDeltaSyncInterval.getDefaultValue()), clusterId); + try { + long seq_no = _agentMgr.send(agentId, new Commands(syncCmd), this); + s_logger.debug("Cluster VM sync started with jobid " + seq_no); + } catch (AgentUnavailableException e) { + s_logger.fatal("The Cluster VM sync process failed for cluster id " + clusterId + " with ", e); + } + } + else { // for others KVM and VMWare + StartupRoutingCommand startup = (StartupRoutingCommand) cmd; + Commands commands = fullHostSync(agentId, startup); + + if (commands.size() > 0) { + s_logger.debug("Sending clean commands to the agent"); + + try { + boolean error = false; + Answer[] answers = _agentMgr.send(agentId, commands); + for (Answer answer : answers) { + if (!answer.getResult()) { + s_logger.warn("Unable to stop a VM due to " + answer.getDetails()); + error = true; + } + } + if (error) { + throw new ConnectionException(true, "Unable to stop VMs"); + } + } catch (final AgentUnavailableException e) { + s_logger.warn("Agent is unavailable now", e); + throw new ConnectionException(true, "Unable to sync", e); + } catch (final OperationTimedoutException e) { + s_logger.warn("Agent is unavailable now", e); + throw new ConnectionException(true, "Unable to sync", e); + } + } + + } + } + + protected class TransitionTask implements Runnable { + @Override + public void run() { + GlobalLock lock = GlobalLock.getInternLock("TransitionChecking"); + if (lock == null) { + s_logger.debug("Couldn't get the global lock"); + return; + } + + if (!lock.lock(30)) { + s_logger.debug("Couldn't lock the db"); + return; + } + try { + lock.addRef(); + List instances = _vmDao.findVMInTransition(new Date(new Date().getTime() - (_operationTimeout * 1000)), State.Starting, State.Stopping); + for (VMInstanceVO instance : instances) { + State state = instance.getState(); + if (state == State.Stopping) { + _haMgr.scheduleStop(instance, instance.getHostId(), WorkType.CheckStop); + } else if (state == State.Starting) { + _haMgr.scheduleRestart(instance, true); + } + } + } catch (Exception e) { + s_logger.warn("Caught the following exception on transition checking", e); + } finally { + StackMaid.current().exitCleanup(); + lock.unlock(); + } + } + } + + protected class AgentVmInfo { + public String name; + public State state; + public String hostUuid; + public VMInstanceVO vm; + public VirtualMachineGuru guru; + + @SuppressWarnings("unchecked") + public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state, String host) { + this.name = name; + this.state = state; + this.vm = vm; + this.guru = (VirtualMachineGuru) guru; + this.hostUuid = host; + } + + public AgentVmInfo(String name, VirtualMachineGuru guru, VMInstanceVO vm, State state) { + this(name, guru, vm, state, null); + } + + public String getHostUuid() { + return hostUuid; + } + } + + @Override + public VMInstanceVO findById(long vmId) { + return _vmDao.findById(vmId); + } + + @Override + public void checkIfCanUpgrade(VirtualMachine vmInstance, long newServiceOfferingId) { + ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId); + if (newServiceOffering == null) { + throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId); + } + + // Check that the VM is stopped + if (!vmInstance.getState().equals(State.Stopped)) { + s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState()); + throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + + "in state " + vmInstance.getState() + + "; make sure the virtual machine is stopped and not in an error state before upgrading."); + } + + // Check if the service offering being upgraded to is what the VM is already running with + if (vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + + "service offering (" + newServiceOffering.getName() + ")"); + } + + throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + + "has the requested service offering (" + newServiceOffering.getName() + ")"); + } + + ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); + + // Check that the service offering being upgraded to has the same Guest IP type as the VM's current service offering + // NOTE: With the new network refactoring in 2.2, we shouldn't need the check for same guest IP type anymore. + /* + * if (!currentServiceOffering.getGuestIpType().equals(newServiceOffering.getGuestIpType())) { String errorMsg = + * "The service offering being upgraded to has a guest IP type: " + newServiceOffering.getGuestIpType(); errorMsg += + * ". Please select a service offering with the same guest IP type as the VM's current service offering (" + + * currentServiceOffering.getGuestIpType() + ")."; throw new InvalidParameterValueException(errorMsg); } + */ + + // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service + // offering + if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { + throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + + ", cannot switch between local storage and shared storage service offerings. Current offering " + + "useLocalStorage=" + currentServiceOffering.getUseLocalStorage() + + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); + } + + // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms + if (currentServiceOffering.getSystemUse() != newServiceOffering.getSystemUse()) { + throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering"); + } + + // Check that there are enough resources to upgrade the service offering + if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) { + throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + + "for an offering of " + newServiceOffering.getCpu() + " cpu(s) at " + + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); + } + + // Check that the service offering being upgraded to has all the tags of the current service offering + List currentTags = _configMgr.csvTagsToList(currentServiceOffering.getTags()); + List newTags = _configMgr.csvTagsToList(newServiceOffering.getTags()); + if (!newTags.containsAll(currentTags)) { + throw new InvalidParameterValueException("Unable to upgrade virtual machine; the new service offering " + + "does not have all the tags of the " + + "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + + "offering tags: " + newTags); + } + } + + @Override + public boolean upgradeVmDb(long vmId, long serviceOfferingId) { + VMInstanceVO vmForUpdate = _vmDao.createForUpdate(); + vmForUpdate.setServiceOfferingId(serviceOfferingId); + ServiceOffering newSvcOff = _configMgr.getServiceOffering(serviceOfferingId); + vmForUpdate.setHaEnabled(newSvcOff.getOfferHA()); + vmForUpdate.setLimitCpuUse(newSvcOff.getLimitCpuUse()); + vmForUpdate.setServiceOfferingId(newSvcOff.getId()); + return _vmDao.update(vmId, vmForUpdate); + } + + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested); + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + + //check vm state + if (vm.getState() == State.Running) { + //1) allocate and prepare nic + NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true); + + //2) Convert vmProfile to vmTO + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + //3) Convert nicProfile to NicTO + NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); + + //4) plug the nic to the vm + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + + s_logger.debug("Plugging nic for vm " + vm + " in network " + network); + if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) { + s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm is a part of network now"); + return nic; + } else { + s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); + return null; + } + } else if (vm.getState() == State.Stopped) { + //1) allocate nic + return _networkMgr.createNicForVm(network, requested, context, vmProfile, false); + } else { + s_logger.warn("Unable to add vm " + vm + " to network " + network); + throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", + DataCenter.class, vm.getDataCenterIdToDeployIn()); + } + } + + + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType); + + NicTO nicTO = hvGuru.toNicTO(nic); + return nicTO; + } + + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + Nic nic = null; + + if (broadcastUri != null) { + nic = _nicsDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri.toString()); + } else { + nic = _networkMgr.getNicInNetwork(vm.getId(), network.getId()); + } + + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + _networkMgr.getNetworkRate(network.getId(), vm.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(network), + _networkMgr.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + + //1) Unplug the nic + NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType()); + s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network); + boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest); + if (result) { + s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network ); + } else { + s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); + return false; + } + + //2) Release the nic + _networkMgr.releaseNic(vmProfile, nic); + s_logger.debug("Successfully released nic " + nic + "for vm " + vm); + + //3) Remove the nic + _networkMgr.removeNic(vmProfile, nic); + return result; + } + +} diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 7e3a1ee9f5b..abd62f46320 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1,2330 +1,2448 @@ -# 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 -SET foreign_key_checks = 0; -use cloud; - -DROP VIEW IF EXISTS `cloud`.`port_forwarding_rules_view`; -DROP TABLE IF EXISTS `cloud`.`configuration`; -DROP TABLE IF EXISTS `cloud`.`ip_forwarding`; -DROP TABLE IF EXISTS `cloud`.`management_agent`; -DROP TABLE IF EXISTS `cloud`.`host`; -DROP TABLE IF EXISTS `cloud`.`mshost`; -DROP TABLE IF EXISTS `cloud`.`service_offering`; -DROP TABLE IF EXISTS `cloud`.`user`; -DROP TABLE IF EXISTS `cloud`.`user_ip_address`; -DROP TABLE IF EXISTS `cloud`.`user_statistics`; -DROP TABLE IF EXISTS `cloud`.`vm_template`; -DROP TABLE IF EXISTS `cloud`.`vm_instance`; -DROP TABLE IF EXISTS `cloud`.`domain_router`; -DROP TABLE IF EXISTS `cloud`.`event`; -DROP TABLE IF EXISTS `cloud`.`host_details`; -DROP TABLE IF EXISTS `cloud`.`host_pod_ref`; -DROP TABLE IF EXISTS `cloud`.`host_zone_ref`; -DROP TABLE IF EXISTS `cloud`.`data_ceneter`; -DROP TABLE IF EXISTS `cloud`.`volumes`; -DROP TABLE IF EXISTS `cloud`.`storage`; -DROP TABLE IF EXISTS `cloud`.`data_center`; -DROP TABLE IF EXISTS `cloud`.`pricing`; -DROP TABLE IF EXISTS `cloud`.`sequence`; -DROP TABLE IF EXISTS `cloud`.`user_vm`; -DROP TABLE IF EXISTS `cloud`.`template_host_ref`; -DROP TABLE IF EXISTS `cloud`.`volume_host_ref`; -DROP TABLE IF EXISTS `cloud`.`upload`; -DROP TABLE IF EXISTS `cloud`.`template_zone_ref`; -DROP TABLE IF EXISTS `cloud`.`dc_vnet_alloc`; -DROP TABLE IF EXISTS `cloud`.`dc_ip_address_alloc`; -DROP TABLE IF EXISTS `cloud`.`vlan`; -DROP TABLE IF EXISTS `cloud`.`host_vlan_map`; -DROP TABLE IF EXISTS `cloud`.`pod_vlan_map`; -DROP TABLE IF EXISTS `cloud`.`vm_host`; -DROP TABLE IF EXISTS `cloud`.`op_ha_work`; -DROP TABLE IF EXISTS `cloud`.`op_dc_vnet_alloc`; -DROP TABLE IF EXISTS `cloud`.`op_dc_ip_address_alloc`; -DROP TABLE IF EXISTS `cloud`.`op_vm_host`; -DROP TABLE IF EXISTS `cloud`.`op_host_queue`; -DROP TABLE IF EXISTS `cloud`.`console_proxy`; -DROP TABLE IF EXISTS `cloud`.`secondary_storage_vm`; -DROP TABLE IF EXISTS `cloud`.`domain`; -DROP TABLE IF EXISTS `cloud`.`account`; -DROP TABLE IF EXISTS `cloud`.`limit`; -DROP TABLE IF EXISTS `cloud`.`op_host_capacity`; -DROP TABLE IF EXISTS `cloud`.`alert`; -DROP TABLE IF EXISTS `cloud`.`op_lock`; -DROP TABLE IF EXISTS `cloud`.`op_host_upgrade`; -DROP TABLE IF EXISTS `cloud`.`snapshots`; -DROP TABLE IF EXISTS `cloud`.`scheduled_volume_backups`; -DROP TABLE IF EXISTS `cloud`.`disk_offering`; -DROP TABLE IF EXISTS `cloud`.`security_group`; -DROP TABLE IF EXISTS `cloud`.`network_rule_config`; -DROP TABLE IF EXISTS `cloud`.`host_details`; -DROP TABLE IF EXISTS `cloud`.`launch_permission`; -DROP TABLE IF EXISTS `cloud`.`resource_limit`; -DROP TABLE IF EXISTS `cloud`.`async_job`; -DROP TABLE IF EXISTS `cloud`.`sync_queue`; -DROP TABLE IF EXISTS `cloud`.`sync_queue_item`; -DROP TABLE IF EXISTS `cloud`.`security_group_vm_map`; -DROP TABLE IF EXISTS `cloud`.`load_balancer_vm_map`; -DROP TABLE IF EXISTS `cloud`.`load_balancer_stickiness_policies`; -DROP TABLE IF EXISTS `cloud`.`load_balancer_inline_ip_map`; -DROP TABLE IF EXISTS `cloud`.`storage_pool`; -DROP TABLE IF EXISTS `cloud`.`storage_pool_host_ref`; -DROP TABLE IF EXISTS `cloud`.`template_spool_ref`; -DROP TABLE IF EXISTS `cloud`.`guest_os`; -DROP TABLE IF EXISTS `cloud`.`snapshot_policy`; -DROP TABLE IF EXISTS `cloud`.`snapshot_policy_ref`; -DROP TABLE IF EXISTS `cloud`.`snapshot_schedule`; -DROP TABLE IF EXISTS `cloud`.`op_pod_vlan_alloc`; -DROP TABLE IF EXISTS `cloud`.`storage_pool_details`; -DROP TABLE IF EXISTS `cloud`.`cluster`; -DROP TABLE IF EXISTS `cloud`.`nics`; -DROP TABLE IF EXISTS `cloud`.`networks`; -DROP TABLE IF EXISTS `cloud`.`op_networks`; -DROP TABLE IF EXISTS `cloud`.`network_offerings`; -DROP TABLE IF EXISTS `cloud`.`account_network_ref`; -DROP TABLE IF EXISTS `cloud`.`domain_network_ref`; -DROP TABLE IF EXISTS `cloud`.`instance_group`; -DROP TABLE IF EXISTS `cloud`.`instance_group_vm_map`; -DROP TABLE IF EXISTS `cloud`.`op_it_work`; -DROP TABLE IF EXISTS `cloud`.`load_balancing_ip_map`; -DROP TABLE IF EXISTS `cloud`.`load_balancing_rules`; -DROP TABLE IF EXISTS `cloud`.`port_forwarding_rules`; -DROP TABLE IF EXISTS `cloud`.`firewall_rules`; -DROP TABLE IF EXISTS `cloud`.`firewall_rules_cidrs`; -DROP TABLE IF EXISTS `cloud`.`ssh_keypairs`; -DROP TABLE IF EXISTS `cloud`.`usage_event`; -DROP TABLE IF EXISTS `cloud`.`host_tags`; -DROP TABLE IF EXISTS `cloud`.`version`; -DROP TABLE IF EXISTS `cloud`.`account_vlan_map`; -DROP TABLE IF EXISTS `cloud`.`cluster_details`; -DROP TABLE IF EXISTS `cloud`.`guest_os_category`; -DROP TABLE IF EXISTS `cloud`.`guest_os_hypervisor`; -DROP TABLE IF EXISTS `cloud`.`op_dc_link_local_ip_address_alloc`; -DROP TABLE IF EXISTS `cloud`.`op_host`; -DROP TABLE IF EXISTS `cloud`.`op_nwgrp_work`; -DROP TABLE IF EXISTS `cloud`.`op_vm_ruleset_log`; -DROP TABLE IF EXISTS `cloud`.`ovs_tunnel_network`; -DROP TABLE IF EXISTS `cloud`.`ovs_tunnel_interface`; -DROP TABLE IF EXISTS `cloud`.`remote_access_vpn`; -DROP TABLE IF EXISTS `cloud`.`resource_count`; -DROP TABLE IF EXISTS `cloud`.`security_ingress_rule`; -DROP TABLE IF EXISTS `cloud`.`security_group_rule`; -DROP TABLE IF EXISTS `cloud`.`stack_maid`; -DROP TABLE IF EXISTS `cloud`.`storage_pool_work`; -DROP TABLE IF EXISTS `cloud`.`user_vm_details`; -DROP TABLE IF EXISTS `cloud`.`vpn_users`; -DROP TABLE IF EXISTS `cloud`.`data_center_details`; -DROP TABLE IF EXISTS `cloud`.`network_tags`; -DROP TABLE IF EXISTS `cloud`.`op_host_transfer`; -DROP TABLE IF EXISTS `cloud`.`projects`; -DROP TABLE IF EXISTS `cloud`.`physical_network`; -DROP TABLE IF EXISTS `cloud`.`physical_network_tags`; -DROP TABLE IF EXISTS `cloud`.`physical_network_isolation_methods`; -DROP TABLE IF EXISTS `cloud`.`physical_network_traffic_types`; -DROP TABLE IF EXISTS `cloud`.`physical_network_service_providers`; -DROP TABLE IF EXISTS `cloud`.`virtual_router_elements`; -DROP TABLE IF EXISTS `cloud`.`dc_storage_network_ip_range`; -DROP TABLE IF EXISTS `cloud`.`op_dc_storage_network_ip_address`; -DROP TABLE IF EXISTS `cloud`.`cluster_vsm_map`; -DROP TABLE IF EXISTS `cloud`.`virtual_supervisor_module`; -DROP TABLE IF EXISTS `cloud`.`port_profile`; -DROP TABLE IF EXISTS `cloud`.`s2s_customer_gateway`; -DROP TABLE IF EXISTS `cloud`.`s2s_vpn_gateway`; -DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; - -CREATE TABLE `cloud`.`version` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', - `version` char(40) NOT NULL UNIQUE COMMENT 'version', - `updated` datetime NOT NULL COMMENT 'Date this version table was updated', - `step` char(32) NOT NULL COMMENT 'Step in the upgrade to this version', - PRIMARY KEY (`id`), - INDEX `i_version__version`(`version`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `version` (`version`, `updated`, `step`) VALUES('@VERSION@', now(), 'Complete'); - -CREATE TABLE `cloud`.`op_it_work` ( - `id` char(40) COMMENT 'reservation id', - `mgmt_server_id` bigint unsigned COMMENT 'management server id', - `created_at` bigint unsigned NOT NULL COMMENT 'when was this work detail created', - `thread` varchar(255) NOT NULL COMMENT 'thread name', - `type` char(32) NOT NULL COMMENT 'type of work', - `vm_type` char(32) NOT NULL COMMENT 'type of vm', - `step` char(32) NOT NULL COMMENT 'state', - `updated_at` bigint unsigned NOT NULL COMMENT 'time it was taken over', - `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', - `resource_type` char(32) COMMENT 'type of resource being worked on', - `resource_id` bigint unsigned COMMENT 'resource id being worked on', - PRIMARY KEY (`id`), - CONSTRAINT `fk_op_it_work__mgmt_server_id` FOREIGN KEY (`mgmt_server_id`) REFERENCES `mshost`(`msid`), - CONSTRAINT `fk_op_it_work__instance_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - INDEX `i_op_it_work__step`(`step`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_networks`( - `id` bigint unsigned NOT NULL UNIQUE KEY, - `mac_address_seq` bigint unsigned NOT NULL DEFAULT 1 COMMENT 'mac address', - `nics_count` int unsigned NOT NULL DEFAULT 0 COMMENT '# of nics', - `gc` tinyint unsigned NOT NULL DEFAULT 1 COMMENT 'gc this network or not', - `check_for_gc` tinyint unsigned NOT NULL DEFAULT 1 COMMENT 'check this network for gc or not', - PRIMARY KEY(`id`), - CONSTRAINT `fk_op_networks__id` FOREIGN KEY (`id`) REFERENCES `networks`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`networks` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `name` varchar(255) COMMENT 'name for this network', - `uuid` varchar(40), - `display_text` varchar(255) COMMENT 'display text for this network', - `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', - `broadcast_domain_type` varchar(32) NOT NULL COMMENT 'type of broadcast domain used', - `broadcast_uri` varchar(255) COMMENT 'broadcast domain specifier', - `gateway` varchar(15) COMMENT 'gateway for this network configuration', - `cidr` varchar(18) COMMENT 'network cidr', - `mode` varchar(32) COMMENT 'How to retrieve ip address in this network', - `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id that this configuration is created from', - `physical_network_id` bigint unsigned COMMENT 'physical network id that this configuration is based on', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this configuration is used in', - `guru_name` varchar(255) NOT NULL COMMENT 'who is responsible for this type of network configuration', - `state` varchar(32) NOT NULL COMMENT 'what state is this configuration in', - `related` bigint unsigned NOT NULL COMMENT 'related to what other network configuration', - `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', - `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', - `dns1` varchar(255) COMMENT 'comma separated DNS list', - `dns2` varchar(255) COMMENT 'comma separated DNS list', - `guru_data` varchar(1024) COMMENT 'data stored by the network guru that setup this network', - `set_fields` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'which fields are set already', - `acl_type` varchar(15) COMMENT 'ACL access type. Null for system networks, can be Account/Domain for Guest networks', - `network_domain` varchar(255) COMMENT 'domain', - `reservation_id` char(40) COMMENT 'reservation id', - `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', - `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the network', - `created` datetime NOT NULL COMMENT 'date created', - `removed` datetime COMMENT 'date removed if not null', - `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network provides an ability to define ip ranges', - `vpc_id` bigint unsigned COMMENT 'vpc this network belongs to', - PRIMARY KEY (`id`), - CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), - CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), - CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), - CONSTRAINT `fk_networks__vpc_id` FOREIGN KEY(`vpc_id`) REFERENCES `vpc`(`id`), - CONSTRAINT `uc_networks__uuid` UNIQUE (`uuid`), - INDEX `i_networks__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`account_network_ref` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `account_id` bigint unsigned NOT NULL COMMENT 'account id', - `network_id` bigint unsigned NOT NULL COMMENT 'network id', - `is_owner` smallint(1) NOT NULL COMMENT 'is the owner of the network', - PRIMARY KEY (`id`), - CONSTRAINT `fk_account_network_ref__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_account_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`nics` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(40), - `instance_id` bigint unsigned COMMENT 'vm instance id', - `mac_address` varchar(17) COMMENT 'mac address', - `ip4_address` char(40) COMMENT 'ip4 address', - `netmask` varchar(15) COMMENT 'netmask for ip4 address', - `gateway` varchar(15) COMMENT 'gateway', - `ip_type` varchar(32) COMMENT 'type of ip', - `broadcast_uri` varchar(255) COMMENT 'broadcast uri', - `network_id` bigint unsigned NOT NULL COMMENT 'network configuration id', - `mode` varchar(32) COMMENT 'mode of getting ip address', - `state` varchar(32) NOT NULL COMMENT 'state of the creation', - `strategy` varchar(32) NOT NULL COMMENT 'reservation strategy', - `reserver_name` varchar(255) COMMENT 'Name of the component that reserved the ip address', - `reservation_id` varchar(64) COMMENT 'id for the reservation', - `device_id` int(10) COMMENT 'device id for the network when plugged into the virtual machine', - `update_time` timestamp NOT NULL COMMENT 'time the state was changed', - `isolation_uri` varchar(255) COMMENT 'id for isolation', - `ip6_address` char(40) COMMENT 'ip6 address', - `default_nic` tinyint NOT NULL COMMENT "None", - `vm_type` varchar(32) COMMENT 'type of vm: System or User vm', - `created` datetime NOT NULL COMMENT 'date created', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_nics__instance_id` FOREIGN KEY `fk_nics__instance_id`(`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_nics__networks_id` FOREIGN KEY `fk_nics__networks_id`(`network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `uc_nics__uuid` UNIQUE (`uuid`), - INDEX `i_nics__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`network_offerings` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', - `name` varchar(64) COMMENT 'name of the network offering', - `uuid` varchar(40), - `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the network offering', - `display_text` varchar(255) NOT NULL COMMENT 'text to display to users', - `nw_rate` smallint unsigned COMMENT 'network rate throttle mbits/s', - `mc_rate` smallint unsigned COMMENT 'mcast rate throttle mbits/s', - `traffic_type` varchar(32) NOT NULL COMMENT 'traffic type carried on this network', - `tags` varchar(4096) COMMENT 'tags supported by this offering', - `system_only` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network offering for system use only', - `specify_vlan` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Should the user specify vlan', - `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', - `conserve_mode` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is this network offering is IP conserve mode enabled', - `created` datetime NOT NULL COMMENT 'time the entry was created', - `removed` datetime DEFAULT NULL COMMENT 'time the entry was removed', - `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if network offering is default', - `availability` varchar(255) NOT NULL COMMENT 'availability of the network', - `dedicated_lb_service` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'true if the network offering provides a dedicated load balancer for each network', - `shared_source_nat_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides the shared source nat service', - `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', - `redundant_router_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides the redundant router service', - `state` char(32) COMMENT 'state of the network offering that has Disabled value by default', - `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', - `elastic_ip_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic ip service', - `elastic_lb_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic lb service', - `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides an ability to define ip ranges', - PRIMARY KEY (`id`), - INDEX `i_network_offerings__system_only`(`system_only`), - INDEX `i_network_offerings__removed`(`removed`), - CONSTRAINT `uc_network_offerings__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`cluster` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', - `name` varchar(255) COMMENT 'name for the cluster', - `uuid` varchar(40) COMMENT 'uuid is different with following guid, while the later one is generated by hypervisor resource', - `guid` varchar(255) UNIQUE DEFAULT NULL COMMENT 'guid for the cluster', - `pod_id` bigint unsigned NOT NULL COMMENT 'pod id', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id', - `hypervisor_type` varchar(32), - `cluster_type` varchar(64) DEFAULT 'CloudManaged', - `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this cluster enabled for allocation for new resources', - `managed_state` varchar(32) NOT NULL DEFAULT 'Managed' COMMENT 'Is this cluster managed by cloudstack', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_cluster__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_cluster__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`), - UNIQUE `i_cluster__pod_id__name`(`pod_id`, `name`), - INDEX `i_cluster__allocation_state`(`allocation_state`), - INDEX `i_cluster__removed`(`removed`), - CONSTRAINT `uc_cluster__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`cluster_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `cluster_id` bigint unsigned NOT NULL COMMENT 'cluster id', - `name` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_cluster_details__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cluster`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_host_upgrade` ( - `host_id` bigint unsigned NOT NULL UNIQUE COMMENT 'host id', - `version` varchar(20) NOT NULL COMMENT 'version', - `state` varchar(20) NOT NULL COMMENT 'state', - PRIMARY KEY (`host_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_lock` ( - `key` varchar(128) NOT NULL UNIQUE COMMENT 'primary key of the table', - `mac` varchar(17) NOT NULL COMMENT 'management server id of the server that holds this lock', - `ip` char(40) NOT NULL COMMENT 'name of the thread that holds this lock', - `thread` varchar(255) NOT NULL COMMENT 'Thread id that acquired this lock', - `acquired_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Time acquired', - `waiters` int NOT NULL DEFAULT 0 COMMENT 'How many have the thread acquired this lock (reentrant)', - PRIMARY KEY (`key`), - INDEX `i_op_lock__mac_ip_thread`(`mac`, `ip`, `thread`) -) ENGINE=Memory DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`configuration` ( - `category` varchar(255) NOT NULL DEFAULT 'Advanced', - `instance` varchar(255) NOT NULL, - `component` varchar(255) NOT NULL DEFAULT 'management-server', - `name` varchar(255) NOT NULL, - `value` varchar(4095), - `description` varchar(1024), - PRIMARY KEY (`name`), - INDEX `i_configuration__instance`(`instance`), - INDEX `i_configuration__name`(`name`), - INDEX `i_configuration__category`(`category`), - INDEX `i_configuration__component`(`component`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_ha_work` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', - `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs to be ha.', - `type` varchar(32) NOT NULL COMMENT 'type of work', - `vm_type` varchar(32) NOT NULL COMMENT 'VM type', - `state` varchar(32) NOT NULL COMMENT 'state of the vm instance when this happened.', - `mgmt_server_id` bigint unsigned COMMENT 'management server that has taken up the work of doing ha', - `host_id` bigint unsigned COMMENT 'host that the vm is suppose to be on', - `created` datetime NOT NULL COMMENT 'time the entry was requested', - `tried` int(10) unsigned COMMENT '# of times tried', - `taken` datetime COMMENT 'time it was taken by the management server', - `step` varchar(32) NOT NULL COMMENT 'Step in the work', - `time_to_try` bigint COMMENT 'time to try do this work', - `updated` bigint unsigned NOT NULL COMMENT 'time the VM state was updated when it was stored into work queue', - PRIMARY KEY (`id`), - CONSTRAINT `fk_op_ha_work__instance_id` FOREIGN KEY `fk_op_ha_work__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, - INDEX `i_op_ha_work__instance_id`(`instance_id`), - CONSTRAINT `fk_op_ha_work__host_id` FOREIGN KEY `fk_op_ha_work__host_id` (`host_id`) REFERENCES `host` (`id`), - INDEX `i_op_ha_work__host_id`(`host_id`), - INDEX `i_op_ha_work__step`(`step`), - INDEX `i_op_ha_work__type`(`type`), - CONSTRAINT `fk_op_ha_work__mgmt_server_id` FOREIGN KEY `fk_op_ha_work__mgmt_server_id`(`mgmt_server_id`) REFERENCES `mshost`(`msid`), - INDEX `i_op_ha_work__mgmt_server_id`(`mgmt_server_id`) - -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`sequence` ( - `name` varchar(64) UNIQUE NOT NULL COMMENT 'name of the sequence', - `value` bigint unsigned NOT NULL COMMENT 'sequence value', - PRIMARY KEY (`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('vm_instance_seq', 1); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('vm_template_seq', 200); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('public_mac_address_seq', 1); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('private_mac_address_seq', 1); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('storage_pool_seq', 200); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('volume_seq', 1); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('networks_seq', 200); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('checkpoint_seq', 1); -INSERT INTO `cloud`.`sequence` (name, value) VALUES ('physical_networks_seq', 200); - -CREATE TABLE `cloud`.`volumes` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', - `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', - `domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to', - `pool_id` bigint unsigned COMMENT 'pool it belongs to. foreign key to storage_pool table', - `last_pool_id` bigint unsigned COMMENT 'last pool it belongs to.', - `instance_id` bigint unsigned NULL COMMENT 'vm instance it belongs to. foreign key to vm_instance table', - `device_id` bigint unsigned NULL COMMENT 'which device inside vm instance it is ', - `name` varchar(255) COMMENT 'A user specified name for the volume', - `uuid` varchar(40), - `size` bigint unsigned NOT NULL COMMENT 'total size', - `folder` varchar(255) COMMENT 'The folder where the volume is saved', - `path` varchar(255) COMMENT 'Path', - `pod_id` bigint unsigned COMMENT 'pod this volume belongs to', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center this volume belongs to', - `iscsi_name` varchar(255) COMMENT 'iscsi target name', - `host_ip` char(40) COMMENT 'host ip address for convenience', - `volume_type` varchar(64) NOT NULL COMMENT 'root, swap or data', - `pool_type` varchar(64) COMMENT 'type of the pool', - `disk_offering_id` bigint unsigned NOT NULL COMMENT 'can be null for system VMs', - `template_id` bigint unsigned COMMENT 'fk to vm_template.id', - `first_snapshot_backup_uuid` varchar (255) COMMENT 'The first snapshot that was ever taken for this volume', - `recreatable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this volume recreatable?', - `created` datetime COMMENT 'Date Created', - `attached` datetime COMMENT 'Date Attached', - `updated` datetime COMMENT 'Date updated for attach/detach', - `removed` datetime COMMENT 'Date removed. not null if removed', - `state` varchar(32) COMMENT 'State machine', - `chain_info` text COMMENT 'save possible disk chain info in primary storage', - `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated', - PRIMARY KEY (`id`), - INDEX `i_volumes__removed`(`removed`), - INDEX `i_volumes__pod_id`(`pod_id`), - INDEX `i_volumes__data_center_id`(`data_center_id`), - CONSTRAINT `fk_volumes__account_id` FOREIGN KEY `fk_volumes__account_id` (`account_id`) REFERENCES `account` (`id`), - INDEX `i_volumes__account_id`(`account_id`), - CONSTRAINT `fk_volumes__pool_id` FOREIGN KEY `fk_volumes__pool_id` (`pool_id`) REFERENCES `storage_pool` (`id`), - INDEX `i_volumes__pool_id`(`pool_id`), - INDEX `i_volumes__last_pool_id`(`last_pool_id`), - CONSTRAINT `fk_volumes__instance_id` FOREIGN KEY `fk_volumes__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, - INDEX `i_volumes__instance_id`(`instance_id`), - INDEX `i_volumes__state`(`state`), - INDEX `i_volumes__update_count`(`update_count`), - CONSTRAINT `uc_volumes__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`snapshots` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', - `data_center_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', - `domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to', - `volume_id` bigint unsigned NOT NULL COMMENT 'volume it belongs to. foreign key to volume table', - `disk_offering_id` bigint unsigned NOT NULL COMMENT 'from original volume', - `status` varchar(32) COMMENT 'snapshot creation status', - `path` varchar(255) COMMENT 'Path', - `name` varchar(255) NOT NULL COMMENT 'snapshot name', - `uuid` varchar(40), - `snapshot_type` int(4) NOT NULL COMMENT 'type of snapshot, e.g. manual, recurring', - `type_description` varchar(25) COMMENT 'description of the type of snapshot, e.g. manual, recurring', - `size` bigint unsigned NOT NULL COMMENT 'original disk size of snapshot', - `created` datetime COMMENT 'Date Created', - `removed` datetime COMMENT 'Date removed. not null if removed', - `backup_snap_id` varchar(255) COMMENT 'Back up uuid of the snapshot', - `swift_id` bigint unsigned COMMENT 'which swift', - `sechost_id` bigint unsigned COMMENT 'secondary storage host id', - `prev_snap_id` bigint unsigned COMMENT 'Id of the most recent snapshot', - `hypervisor_type` varchar(32) NOT NULL COMMENT 'hypervisor that the snapshot was taken under', - `version` varchar(32) COMMENT 'snapshot version', - PRIMARY KEY (`id`), - CONSTRAINT `uc_snapshots__uuid` UNIQUE (`uuid`), - INDEX `i_snapshots__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vlan` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `uuid` varchar(40), - `vlan_id` varchar(255), - `vlan_gateway` varchar(255), - `vlan_netmask` varchar(255), - `description` varchar(255), - `vlan_type` varchar(255), - `data_center_id` bigint unsigned NOT NULL, - `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', - PRIMARY KEY (`id`), - #CONSTRAINT `fk_vlan__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `fk_vlan__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), - CONSTRAINT `uc_vlan__uuid` UNIQUE (`uuid`), - CONSTRAINT `fk_vlan__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`pod_vlan_map` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `pod_id` bigint unsigned NOT NULL COMMENT 'pod id. foreign key to pod table', - `vlan_db_id` bigint unsigned NOT NULL COMMENT 'database id of vlan. foreign key to vlan table', - PRIMARY KEY (`id`), - CONSTRAINT `fk_pod_vlan_map__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, - INDEX `i_pod_vlan_map__pod_id`(`pod_id`), - CONSTRAINT `fk_pod_vlan_map__vlan_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan` (`id`) ON DELETE CASCADE, - INDEX `i_pod_vlan_map__vlan_id`(`vlan_db_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`account_vlan_map` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `account_id` bigint unsigned NOT NULL COMMENT 'account id. foreign key to account table', - `vlan_db_id` bigint unsigned NOT NULL COMMENT 'database id of vlan. foreign key to vlan table', - PRIMARY KEY (`id`), - CONSTRAINT `fk_account_vlan_map__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, - INDEX `i_account_vlan_map__account_id`(`account_id`), - CONSTRAINT `fk_account_vlan_map__vlan_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan` (`id`) ON DELETE CASCADE, - INDEX `i_account_vlan_map__vlan_id`(`vlan_db_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`data_center` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `name` varchar(255), - `uuid` varchar(40), - `description` varchar(255), - `dns1` varchar(255) NOT NULL, - `dns2` varchar(255), - `internal_dns1` varchar(255) NOT NULL, - `internal_dns2` varchar(255), - `gateway` varchar(15), - `netmask` varchar(15), - `router_mac_address` varchar(17) NOT NULL DEFAULT '02:00:00:00:00:01' COMMENT 'mac address for the router within the domain', - `mac_address` bigint unsigned NOT NULL DEFAULT '1' COMMENT 'Next available mac address for the ethernet card interacting with public internet', - `guest_network_cidr` varchar(18), - `domain` varchar(100) COMMENT 'Network domain name of the Vms of the zone', - `domain_id` bigint unsigned COMMENT 'domain id for the parent domain to this zone (null signifies public zone)', - `networktype` varchar(255) NOT NULL DEFAULT 'Basic' COMMENT 'Network type of the zone', - `dns_provider` char(64) DEFAULT 'VirtualRouter', - `gateway_provider` char(64) DEFAULT 'VirtualRouter', - `firewall_provider` char(64) DEFAULT 'VirtualRouter', - `dhcp_provider` char(64) DEFAULT 'VirtualRouter', - `lb_provider` char(64) DEFAULT 'VirtualRouter', - `vpn_provider` char(64) DEFAULT 'VirtualRouter', - `userdata_provider` char(64) DEFAULT 'VirtualRouter', - `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this data center enabled for allocation for new resources', - `zone_token` varchar(255), - `is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_data_center__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`), - INDEX `i_data_center__domain_id`(`domain_id`), - INDEX `i_data_center__allocation_state`(`allocation_state`), - INDEX `i_data_center__zone_token`(`zone_token`), - INDEX `i_data_center__removed`(`removed`), - CONSTRAINT `uc_data_center__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_dc_ip_address_alloc` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', - `ip_address` char(40) NOT NULL COMMENT 'ip address', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center it belongs to', - `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', - `nic_id` bigint unsigned NULL COMMENT 'nic id', - `reservation_id` char(40) NULL COMMENT 'reservation id', - `taken` datetime COMMENT 'Date taken', - `mac_address` bigint unsigned NOT NULL COMMENT 'mac address for management ips', - PRIMARY KEY (`id`), - CONSTRAINT `fk_op_dc_ip_address_alloc__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - INDEX `i_op_dc_ip_address_alloc__pod_id__data_center_id__taken` (`pod_id`, `data_center_id`, `taken`, `nic_id`), - UNIQUE `i_op_dc_ip_address_alloc__ip_address__data_center_id`(`ip_address`, `data_center_id`), - CONSTRAINT `fk_op_dc_ip_address_alloc__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, - INDEX `i_op_dc_ip_address_alloc__pod_id`(`pod_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_dc_link_local_ip_address_alloc` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', - `ip_address` char(40) NOT NULL COMMENT 'ip address', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center it belongs to', - `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', - `nic_id` bigint unsigned NULL COMMENT 'instance id', - `reservation_id` char(40) NULL COMMENT 'reservation id used to reserve this network', - `taken` datetime COMMENT 'Date taken', - PRIMARY KEY (`id`), - INDEX `i_op_dc_link_local_ip_address_alloc__pod_id`(`pod_id`), - INDEX `i_op_dc_link_local_ip_address_alloc__data_center_id`(`data_center_id`), - INDEX `i_op_dc_link_local_ip_address_alloc__nic_id_reservation_id`(`nic_id`,`reservation_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`dc_storage_network_ip_range` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `uuid` varchar(40), - `start_ip` char(40) NOT NULL COMMENT 'start ip address', - `end_ip` char(40) NOT NULL COMMENT 'end ip address', - `gateway` varchar(15) NOT NULL COMMENT 'gateway ip address', - `vlan` int unsigned DEFAULT NULL COMMENT 'vlan the storage network on', - `netmask` varchar(15) NOT NULL COMMENT 'netmask for storage network', - `data_center_id` bigint unsigned NOT NULL, - `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', - `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', - PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_ip_range__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `fk_storage_ip_range__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), - CONSTRAINT `fk_storage_ip_range__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`), - CONSTRAINT `uc_storage_ip_range__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_dc_storage_network_ip_address` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', - `range_id` bigint unsigned NOT NULL COMMENT 'id of ip range in dc_storage_network_ip_range', - `ip_address` char(40) NOT NULL COMMENT 'ip address', - `mac_address` bigint unsigned NOT NULL COMMENT 'mac address for storage ips', - `taken` datetime COMMENT 'Date taken', - PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`host_pod_ref` ( - `id` bigint unsigned NOT NULL UNIQUE auto_increment, - `name` varchar(255), - `uuid` varchar(40), - `data_center_id` bigint unsigned NOT NULL, - `gateway` varchar(255) NOT NULL COMMENT 'gateway for the pod', - `cidr_address` varchar(15) NOT NULL COMMENT 'CIDR address for the pod', - `cidr_size` bigint unsigned NOT NULL COMMENT 'CIDR size for the pod', - `description` varchar(255) COMMENT 'store private ip range in startIP-endIP format', - `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this Pod enabled for allocation for new resources', - `external_dhcp` tinyint NOT NULL DEFAULT 0 COMMENT 'Is this Pod using external DHCP', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - UNIQUE KEY (`name`, `data_center_id`), - INDEX `i_host_pod_ref__data_center_id`(`data_center_id`), - INDEX `i_host_pod_ref__allocation_state`(`allocation_state`), - INDEX `i_host_pod_ref__removed`(`removed`), - CONSTRAINT `uc_host_pod_ref__uuid` UNIQUE (`uuid`) - -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_dc_vnet_alloc` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary id', - `vnet` varchar(18) NOT NULL COMMENT 'vnet', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network the vnet belongs to', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center the vnet belongs to', - `reservation_id` char(40) NULL COMMENT 'reservation id', - `account_id` bigint unsigned NULL COMMENT 'account the vnet belongs to right now', - `taken` datetime COMMENT 'Date taken', - PRIMARY KEY (`id`), - UNIQUE `i_op_dc_vnet_alloc__vnet__data_center_id__account_id`(`vnet`, `data_center_id`, `account_id`), - INDEX `i_op_dc_vnet_alloc__dc_taken`(`data_center_id`, `taken`), - UNIQUE `i_op_dc_vnet_alloc__vnet__data_center_id`(`vnet`, `data_center_id`), - CONSTRAINT `fk_op_dc_vnet_alloc__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_op_dc_vnet_alloc__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`firewall_rules` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `ip_address_id` bigint unsigned COMMENT 'id of the corresponding ip address', - `start_port` int(10) COMMENT 'starting port of a port range', - `end_port` int(10) COMMENT 'end port of a port range', - `state` char(32) NOT NULL COMMENT 'current state of this rule', - `protocol` char(16) NOT NULL default 'TCP' COMMENT 'protocol to open these ports for', - `purpose` char(32) NOT NULL COMMENT 'why are these ports opened?', - `account_id` bigint unsigned NOT NULL COMMENT 'owner id', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', - `network_id` bigint unsigned NOT NULL COMMENT 'network id', - `xid` char(40) NOT NULL COMMENT 'external id', - `created` datetime COMMENT 'Date created', - `icmp_code` int(10) COMMENT 'The ICMP code (if protocol=ICMP). A value of -1 means all codes for the given ICMP type.', - `icmp_type` int(10) COMMENT 'The ICMP type (if protocol=ICMP). A value of -1 means all types.', - `related` bigint unsigned COMMENT 'related to what other firewall rule', - `type` varchar(10) NOT NULL DEFAULT 'USER', - `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', - `traffic_type` char(32) COMMENT 'the traffic type of the rule, can be Ingress or Egress', - PRIMARY KEY (`id`), - CONSTRAINT `fk_firewall_rules__ip_address_id` FOREIGN KEY(`ip_address_id`) REFERENCES `user_ip_address`(`id`), - CONSTRAINT `fk_firewall_rules__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_firewall_rules__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_firewall_rules__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_firewall_rules__related` FOREIGN KEY(`related`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_firewall_rules__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, - INDEX `i_firewall_rules__purpose`(`purpose`), - CONSTRAINT `uc_firewall_rules__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`firewall_rules_cidrs` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `firewall_rule_id` bigint(20) unsigned NOT NULL COMMENT 'firewall rule id', - `source_cidr` varchar(18) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `fk_firewall_cidrs_firewall_rules` (`firewall_rule_id`), - UNIQUE INDEX `unique_rule_cidrs` (`firewall_rule_id`, `source_cidr`), - CONSTRAINT `fk_firewall_cidrs_firewall_rules` FOREIGN KEY (`firewall_rule_id`) REFERENCES `firewall_rules` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`load_balancing_rules` ( - `id` bigint unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `description` varchar(4096) NULL COMMENT 'description', - `default_port_start` int(10) NOT NULL COMMENT 'default private port range start', - `default_port_end` int(10) NOT NULL COMMENT 'default destination port range end', - `algorithm` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_load_balancing_rules__id` FOREIGN KEY(`id`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`load_balancer_vm_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `load_balancer_id` bigint unsigned NOT NULL, - `instance_id` bigint unsigned NOT NULL, - `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', - PRIMARY KEY (`id`), - UNIQUE KEY (`load_balancer_id`, `instance_id`), - CONSTRAINT `fk_load_balancer_vm_map__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_load_balancer_vm_map__instance_id` FOREIGN KEY(`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`load_balancer_stickiness_policies` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `load_balancer_id` bigint unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `description` varchar(4096) NULL COMMENT 'description', - `method_name` varchar(255) NOT NULL, - `params` varchar(4096) NOT NULL, - `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', - PRIMARY KEY (`id`), - CONSTRAINT `fk_load_balancer_stickiness_policies__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`inline_load_balancer_nic_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `load_balancer_id` bigint unsigned NOT NULL, - `public_ip_address` char(40) NOT NULL, - `nic_id` bigint unsigned NULL COMMENT 'nic id', - PRIMARY KEY (`id`), - UNIQUE KEY (`nic_id`), - CONSTRAINT `fk_inline_load_balancer_nic_map__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_inline_load_balancer_nic_map__nic_id` FOREIGN KEY(`nic_id`) REFERENCES `nics`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`port_forwarding_rules` ( - `id` bigint unsigned NOT NULL COMMENT 'id', - `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance id', - `dest_ip_address` char(40) NOT NULL COMMENT 'id_address', - `dest_port_start` int(10) NOT NULL COMMENT 'starting port of the port range to map to', - `dest_port_end` int(10) NOT NULL COMMENT 'end port of the the port range to map to', - PRIMARY KEY (`id`), - CONSTRAINT `fk_port_forwarding_rules__id` FOREIGN KEY(`id`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_port_forwarding_rules__instance_id` FOREIGN KEY `fk_port_forwarding_rules__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`host` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255) NOT NULL, - `uuid` varchar(40) COMMENT 'this uuid is different with guid below, the later one is used by hypervisor resource', - `status` varchar(32) NOT NULL, - `type` varchar(32) NOT NULL, - `private_ip_address` char(40) NOT NULL, - `private_netmask` varchar(15), - `private_mac_address` varchar(17), - `storage_ip_address` char(40), - `storage_netmask` varchar(15), - `storage_mac_address` varchar(17), - `storage_ip_address_2` char(40), - `storage_mac_address_2` varchar(17), - `storage_netmask_2` varchar(15), - `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', - `public_ip_address` char(40), - `public_netmask` varchar(15), - `public_mac_address` varchar(17), - `proxy_port` int(10) unsigned, - `data_center_id` bigint unsigned NOT NULL, - `pod_id` bigint unsigned, - `cpus` int(10) unsigned, - `speed` int(10) unsigned, - `url` varchar(255) COMMENT 'iqn for the servers', - `fs_type` varchar(32), - `hypervisor_type` varchar(32) COMMENT 'hypervisor type, can be NONE for storage', - `hypervisor_version` varchar(32) COMMENT 'hypervisor version', - `ram` bigint unsigned, - `resource` varchar(255) DEFAULT NULL COMMENT 'If it is a local resource, this is the class name', - `version` varchar(40) NOT NULL, - `parent` varchar(255) COMMENT 'parent path for the storage server', - `total_size` bigint unsigned COMMENT 'TotalSize', - `capabilities` varchar(255) COMMENT 'host capabilities in comma separated list', - `guid` varchar(255) UNIQUE, - `available` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is this host ready for more resources?', - `setup` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this host already setup?', - `dom0_memory` bigint unsigned NOT NULL COMMENT 'memory used by dom0 for computing and routing servers', - `last_ping` int(10) unsigned NOT NULL COMMENT 'time in seconds from the start of machine of the last ping', - `mgmt_server_id` bigint unsigned COMMENT 'ManagementServer this host is connected to.', - `disconnected` datetime COMMENT 'Time this was disconnected', - `created` datetime COMMENT 'date the host first signed on', - `removed` datetime COMMENT 'date removed if not null', - `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'atomic increase count making status update operation atomical', - `resource_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this host enabled for allocation for new resources', - PRIMARY KEY (`id`), - INDEX `i_host__removed`(`removed`), - INDEX `i_host__last_ping`(`last_ping`), - INDEX `i_host__status`(`status`), - INDEX `i_host__data_center_id`(`data_center_id`), - CONSTRAINT `fk_host__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, - INDEX `i_host__pod_id`(`pod_id`), - CONSTRAINT `fk_host__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cloud`.`cluster`(`id`), - CONSTRAINT `uc_host__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_host` ( - `id` bigint unsigned NOT NULL UNIQUE COMMENT 'host id', - `sequence` bigint unsigned DEFAULT 1 NOT NULL COMMENT 'sequence for the host communication', - PRIMARY KEY (`id`), - CONSTRAINT `fk_op_host__id` FOREIGN KEY (`id`) REFERENCES `host`(`id`) ON DELETE CASCADE -) ENGINE = InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`account_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `account_id` bigint unsigned NOT NULL COMMENT 'account id', - `name` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_account_details__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE -)ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`host_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL COMMENT 'host id', - `name` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`mshost` ( - `id` bigint unsigned NOT NULL auto_increment, - `msid` bigint unsigned NOT NULL UNIQUE COMMENT 'management server id derived from MAC address', - `runid` bigint NOT NULL DEFAULT 0 COMMENT 'run id, combined with msid to form a cluster session', - `name` varchar(255), - `state` varchar(10) NOT NULL DEFAULT 'Down', - `version` varchar(255), - `service_ip` char(40) NOT NULL, - `service_port` integer NOT NULL, - `last_update` DATETIME NULL COMMENT 'Last record update time', - `removed` datetime COMMENT 'date removed if not null', - `alert_count` integer NOT NULL DEFAULT 0, - PRIMARY KEY (`id`), - INDEX `i_mshost__removed`(`removed`), - INDEX `i_mshost__last_update`(`last_update`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`mshost_peer` ( - `id` bigint unsigned NOT NULL auto_increment, - `owner_mshost` bigint unsigned NOT NULL, - `peer_mshost` bigint unsigned NOT NULL, - `peer_runid` bigint NOT NULL, - `peer_state` varchar(10) NOT NULL DEFAULT 'Down', - `last_update` DATETIME NULL COMMENT 'Last record update time', - - PRIMARY KEY (`id`), - CONSTRAINT `fk_mshost_peer__owner_mshost` FOREIGN KEY (`owner_mshost`) REFERENCES `mshost`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_mshost_peer__peer_mshost` FOREIGN KEY (`peer_mshost`) REFERENCES `mshost`(`id`), - UNIQUE `i_mshost_peer__owner_peer_runid`(`owner_mshost`, `peer_mshost`, `peer_runid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`host_tags` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL COMMENT 'host id', - `tag` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_host_tags__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`user` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `username` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `account_id` bigint unsigned NOT NULL, - `firstname` varchar(255) default NULL, - `lastname` varchar(255) default NULL, - `email` varchar(255) default NULL, - `state` varchar(10) NOT NULL default 'enabled', - `api_key` varchar(255) default NULL, - `secret_key` varchar(255) default NULL, - `created` datetime NOT NULL COMMENT 'date created', - `removed` datetime COMMENT 'date removed', - `timezone` varchar(30) default NULL, - `registration_token` varchar(255) default NULL, - `is_registered` tinyint NOT NULL DEFAULT 0 COMMENT '1: yes, 0: no', - PRIMARY KEY (`id`), - INDEX `i_user__removed`(`removed`), - INDEX `i_user__secret_key_removed`(`secret_key`, `removed`), - UNIQUE `i_user__api_key`(`api_key`), - CONSTRAINT `fk_user__account_id` FOREIGN KEY `fk_user__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, - INDEX `i_user__account_id`(`account_id`), - CONSTRAINT `uc_user__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`event` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `type` varchar(32) NOT NULL, - `state` varchar(32) NOT NULL DEFAULT 'Completed', - `description` varchar(1024) NOT NULL, - `user_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `created` datetime NOT NULL, - `level` varchar(16) NOT NULL, - `start_id` bigint unsigned NOT NULL DEFAULT 0, - `parameters` varchar(1024) NULL, - PRIMARY KEY (`id`), - CONSTRAINT `uc_event__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`user_ip_address` ( - `id` bigint unsigned NOT NULL UNIQUE auto_increment, - `uuid` varchar(40), - `account_id` bigint unsigned NULL, - `domain_id` bigint unsigned NULL, - `public_ip_address` char(40) NOT NULL, - `data_center_id` bigint unsigned NOT NULL COMMENT 'zone that it belongs to', - `source_nat` int(1) unsigned NOT NULL default '0', - `allocated` datetime NULL COMMENT 'Date this ip was allocated to someone', - `vlan_db_id` bigint unsigned NOT NULL, - `one_to_one_nat` int(1) unsigned NOT NULL default '0', - `vm_id` bigint unsigned COMMENT 'vm id the one_to_one nat ip is assigned to', - `state` char(32) NOT NULL default 'Free' COMMENT 'state of the ip address', - `mac_address` bigint unsigned NOT NULL COMMENT 'mac address of this ip', - `source_network_id` bigint unsigned NOT NULL COMMENT 'network id ip belongs to', - `network_id` bigint unsigned COMMENT 'network this public ip address is associated with', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', - `is_system` int(1) unsigned NOT NULL default '0', - `vpc_id` bigint unsigned COMMENT 'vpc the ip address is associated with', - PRIMARY KEY (`id`), - UNIQUE (`public_ip_address`, `source_network_id`), - CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `fk_user_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `fk_user_ip_address__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`), - CONSTRAINT `fk_user_ip_address__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance`(`id`), - CONSTRAINT `fk_user_ip_address__vlan_db_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_user_ip_address__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_user_ip_address__uuid` UNIQUE (`uuid`), - CONSTRAINT `fk_user_ip_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_user_ip_address__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, - INDEX `i_user_ip_address__allocated`(`allocated`), - INDEX `i_user_ip_address__source_nat`(`source_nat`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`user_statistics` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT, - `data_center_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `public_ip_address` char(40), - `device_id` bigint unsigned NOT NULL, - `device_type` varchar(32) NOT NULL, - `network_id` bigint unsigned, - `net_bytes_received` bigint unsigned NOT NULL default '0', - `net_bytes_sent` bigint unsigned NOT NULL default '0', - `current_bytes_received` bigint unsigned NOT NULL default '0', - `current_bytes_sent` bigint unsigned NOT NULL default '0', - `agg_bytes_received` bigint unsigned NOT NULL default '0', - `agg_bytes_sent` bigint unsigned NOT NULL default '0', - PRIMARY KEY (`id`), - UNIQUE KEY (`account_id`, `data_center_id`, `public_ip_address`, `device_id`, `device_type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vm_template` ( - `id` bigint unsigned NOT NULL auto_increment, - `unique_name` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - `public` int(1) unsigned NOT NULL, - `featured` int(1) unsigned NOT NULL, - `type` varchar(32) NULL, - `hvm` int(1) unsigned NOT NULL COMMENT 'requires HVM', - `bits` int(6) unsigned NOT NULL COMMENT '32 bit or 64 bit', - `url` varchar(255) NULL COMMENT 'the url where the template exists externally', - `format` varchar(32) NOT NULL COMMENT 'format for the template', - `created` datetime NOT NULL COMMENT 'Date created', - `removed` datetime COMMENT 'Date removed if not null', - `account_id` bigint unsigned NOT NULL COMMENT 'id of the account that created this template', - `checksum` varchar(255) COMMENT 'checksum for the template root disk', - `display_text` varchar(4096) NULL COMMENT 'Description text set by the admin for display purpose only', - `enable_password` int(1) unsigned NOT NULL default 1 COMMENT 'true if this template supports password reset', - `enable_sshkey` int(1) unsigned NOT NULL default 0 COMMENT 'true if this template supports sshkey reset', - `guest_os_id` bigint unsigned NOT NULL COMMENT 'the OS of the template', - `bootable` int(1) unsigned NOT NULL default 1 COMMENT 'true if this template represents a bootable ISO', - `prepopulate` int(1) unsigned NOT NULL default 0 COMMENT 'prepopulate this template to primary storage', - `cross_zones` int(1) unsigned NOT NULL default 0 COMMENT 'Make this template available in all zones', - `extractable` int(1) unsigned NOT NULL default 0 COMMENT 'Is this template extractable', - `hypervisor_type` varchar(32) COMMENT 'hypervisor that the template belongs to', - `source_template_id` bigint unsigned COMMENT 'Id of the original template, if this template is created from snapshot', - `template_tag` varchar(255) COMMENT 'template tag', - `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', - PRIMARY KEY (`id`), - INDEX `i_vm_template__removed`(`removed`), - CONSTRAINT `uc_vm_template__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vm_template_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `template_id` bigint unsigned NOT NULL COMMENT 'template id', - `name` varchar(255) NOT NULL, - `value` varchar(1024) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_vm_template_details__template_id` FOREIGN KEY `fk_vm_template_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vm_instance` ( - `id` bigint unsigned UNIQUE NOT NULL, - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - `instance_name` varchar(255) NOT NULL COMMENT 'name of the vm instance running on the hosts', - `state` varchar(32) NOT NULL, - `vm_template_id` bigint unsigned, - `guest_os_id` bigint unsigned NOT NULL, - `private_mac_address` varchar(17), - `private_ip_address` char(40), - `pod_id` bigint unsigned, - `data_center_id` bigint unsigned NOT NULL COMMENT 'Data Center the instance belongs to', - `host_id` bigint unsigned, - `last_host_id` bigint unsigned COMMENT 'tentative host for first run or last host that it has been running on', - `proxy_id` bigint unsigned NULL COMMENT 'console proxy allocated in previous session', - `proxy_assign_time` DATETIME NULL COMMENT 'time when console proxy was assigned', - `vnc_password` varchar(255) NOT NULL COMMENT 'vnc password', - `ha_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Should HA be enabled for this VM', - `limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the cpu usage to service offering', - `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated', - `update_time` datetime COMMENT 'date the destroy was requested', - `created` datetime NOT NULL COMMENT 'date created', - `removed` datetime COMMENT 'date removed if not null', - `type` varchar(32) NOT NULL COMMENT 'type of vm it is', - `vm_type` varchar(32) NOT NULL COMMENT 'vm type', - `account_id` bigint unsigned NOT NULL COMMENT 'user id of owner', - `domain_id` bigint unsigned NOT NULL, - `service_offering_id` bigint unsigned NOT NULL COMMENT 'service offering id', - `reservation_id` char(40) COMMENT 'reservation id', - `hypervisor_type` char(32) COMMENT 'hypervisor type', - PRIMARY KEY (`id`), - INDEX `i_vm_instance__removed`(`removed`), - INDEX `i_vm_instance__type`(`type`), - INDEX `i_vm_instance__pod_id`(`pod_id`), - INDEX `i_vm_instance__update_time`(`update_time`), - INDEX `i_vm_instance__update_count`(`update_count`), - INDEX `i_vm_instance__state`(`state`), - INDEX `i_vm_instance__data_center_id`(`data_center_id`), - CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY `fk_vm_instance__host_id` (`host_id`) REFERENCES `host` (`id`), - CONSTRAINT `fk_vm_instance__last_host_id` FOREIGN KEY `fk_vm_instance__last_host_id` (`last_host_id`) REFERENCES `host`(`id`), - CONSTRAINT `fk_vm_instance__template_id` FOREIGN KEY `fk_vm_instance__template_id` (`vm_template_id`) REFERENCES `vm_template` (`id`), - INDEX `i_vm_instance__template_id`(`vm_template_id`), - CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY `fk_vm_instance__account_id` (`account_id`) REFERENCES `account` (`id`), - CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY `fk_vm_instance__service_offering_id` (`service_offering_id`) REFERENCES `service_offering` (`id`), - CONSTRAINT `uc_vm_instance_uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`user_vm` ( - `id` bigint unsigned UNIQUE NOT NULL, - `iso_id` bigint unsigned, - `display_name` varchar(255), - `user_data` varchar(2048), - `update_parameters` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Defines if the parameters have been updated for the vm', - PRIMARY KEY (`id`), - CONSTRAINT `fk_user_vm__id` FOREIGN KEY `fk_user_vm__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- note, uer_vm_details is now used for all VMs (not just for user vms) -CREATE TABLE `cloud`.`user_vm_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `vm_id` bigint unsigned NOT NULL COMMENT 'vm id', - `name` varchar(255) NOT NULL, - `value` varchar(1024) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_user_vm_details__vm_id` FOREIGN KEY `fk_user_vm_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`domain_router` ( - `id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key', - `element_id` bigint unsigned NOT NULL COMMENT 'correlated virtual router provider ID', - `public_mac_address` varchar(17) COMMENT 'mac address of the public facing network card', - `public_ip_address` char(40) COMMENT 'public ip address used for source net', - `public_netmask` varchar(15) COMMENT 'netmask used for the domR', - `guest_netmask` varchar(15) COMMENT 'netmask used for the guest network', - `guest_ip_address` char(40) COMMENT ' ip address in the guest network', - `is_redundant_router` int(1) unsigned NOT NULL COMMENT 'if in redundant router mode', - `priority` int(4) unsigned COMMENT 'priority of router in the redundant router mode', - `is_priority_bumpup` int(1) unsigned NOT NULL COMMENT 'if the priority has been bumped up', - `redundant_state` varchar(64) NOT NULL COMMENT 'the state of redundant virtual router', - `stop_pending` int(1) unsigned NOT NULL COMMENT 'if this router would be stopped after we can connect to it', - `role` varchar(64) NOT NULL COMMENT 'type of role played by this router', - `template_version` varchar(100) COMMENT 'template version', - `scripts_version` varchar(100) COMMENT 'scripts version', - `vpc_id` bigint unsigned COMMENT 'correlated virtual router vpc ID', - PRIMARY KEY (`id`), - CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`), - CONSTRAINT `fk_domain_router__vpc_id` FOREIGN KEY `fk_domain_router__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) -) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance'; - -CREATE TABLE `cloud`.`upload` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL, - `type_id` bigint unsigned NOT NULL, - `type` varchar(255), - `mode` varchar(255), - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `job_id` varchar(255), - `upload_pct` int(10) unsigned, - `upload_state` varchar(255), - `error_str` varchar(255), - `url` varchar(255), - `install_path` varchar(255), - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`template_host_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL, - `template_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `job_id` varchar(255), - `download_pct` int(10) unsigned, - `size` bigint unsigned, - `physical_size` bigint unsigned DEFAULT 0, - `download_state` varchar(255), - `error_str` varchar(255), - `local_path` varchar(255), - `install_path` varchar(255), - `url` varchar(255), - `destroyed` tinyint(1) COMMENT 'indicates whether the template_host entry was destroyed by the user or not', - `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', - PRIMARY KEY (`id`), - CONSTRAINT `fk_template_host_ref__host_id` FOREIGN KEY `fk_template_host_ref__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, - INDEX `i_template_host_ref__host_id`(`host_id`), - CONSTRAINT `fk_template_host_ref__template_id` FOREIGN KEY `fk_template_host_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), - INDEX `i_template_host_ref__template_id`(`template_id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`volume_host_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL, - `volume_id` bigint unsigned NOT NULL, - `zone_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `job_id` varchar(255), - `download_pct` int(10) unsigned, - `size` bigint unsigned, - `physical_size` bigint unsigned DEFAULT 0, - `download_state` varchar(255), - `checksum` varchar(255) COMMENT 'checksum for the data disk', - `error_str` varchar(255), - `local_path` varchar(255), - `install_path` varchar(255), - `url` varchar(255), - `format` varchar(32) NOT NULL COMMENT 'format for the volume', - `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', - PRIMARY KEY (`id`), - CONSTRAINT `fk_volume_host_ref__host_id` FOREIGN KEY `fk_volume_host_ref__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, - INDEX `i_volume_host_ref__host_id`(`host_id`), - CONSTRAINT `fk_volume_host_ref__volume_id` FOREIGN KEY `fk_volume_host_ref__volume_id` (`volume_id`) REFERENCES `volumes` (`id`), - INDEX `i_volume_host_ref__volume_id`(`volume_id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`template_swift_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `swift_id` bigint unsigned NOT NULL, - `template_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `path` varchar(255), - `size` bigint unsigned, - `physical_size` bigint unsigned DEFAULT 0, - PRIMARY KEY (`id`), - CONSTRAINT `fk_template_swift_ref__swift_id` FOREIGN KEY `fk_template_swift_ref__swift_id` (`swift_id`) REFERENCES `swift` (`id`) ON DELETE CASCADE, - INDEX `i_template_swift_ref__swift_id`(`swift_id`), - CONSTRAINT `fk_template_swift_ref__template_id` FOREIGN KEY `fk_template_swift_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), - INDEX `i_template_swift_ref__template_id`(`template_id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`template_zone_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `zone_id` bigint unsigned NOT NULL, - `template_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_template_zone_ref__zone_id` FOREIGN KEY `fk_template_zone_ref__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, - INDEX `i_template_zone_ref__zone_id`(`zone_id`), - CONSTRAINT `fk_template_zone_ref__template_id` FOREIGN KEY `fk_template_zone_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`) ON DELETE CASCADE, - INDEX `i_template_zone_ref__template_id`(`template_id`), - INDEX `i_template_zone_ref__removed`(`removed`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`console_proxy` ( - `id` bigint unsigned NOT NULL auto_increment, - `public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card', - `public_ip_address` char(40) COMMENT 'public ip address for the console proxy', - `public_netmask` varchar(15) COMMENT 'public netmask used for the console proxy', - `active_session` int(10) NOT NULL DEFAULT 0 COMMENT 'active session number', - `last_update` DATETIME NULL COMMENT 'Last session update time', - `session_details` BLOB NULL COMMENT 'session detail info', - PRIMARY KEY (`id`), - CONSTRAINT `fk_console_proxy__id` FOREIGN KEY `fk_console_proxy__id`(`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`secondary_storage_vm` ( - `id` bigint unsigned NOT NULL auto_increment, - `public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card', - `public_ip_address` char(40) COMMENT 'public ip address for the sec storage vm', - `public_netmask` varchar(15) COMMENT 'public netmask used for the sec storage vm', - `guid` varchar(255) COMMENT 'copied from guid of secondary storage host', - `nfs_share` varchar(255) COMMENT 'server and path exported by the nfs server ', - `last_update` DATETIME NULL COMMENT 'Last session update time', - `role` varchar(64) NOT NULL DEFAULT 'templateProcessor' COMMENT 'work role of secondary storage host(templateProcessor | commandExecutor)', - PRIMARY KEY (`id`), - CONSTRAINT `fk_secondary_storage_vm__id` FOREIGN KEY `fk_secondary_storage_vm__id`(`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`domain` ( - `id` bigint unsigned NOT NULL auto_increment, - `parent` bigint unsigned, - `name` varchar(255), - `uuid` varchar(40), - `owner` bigint unsigned NOT NULL, - `path` varchar(255) NOT NULL, - `level` int(10) NOT NULL DEFAULT 0, - `child_count` int(10) NOT NULL DEFAULT 0, - `next_child_seq` bigint unsigned NOT NULL DEFAULT 1, - `removed` datetime COMMENT 'date removed', - `state` char(32) NOT NULL default 'Active' COMMENT 'state of the domain', - `network_domain` varchar(255), - `type` varchar(255) NOT NULL DEFAULT 'Normal' COMMENT 'type of the domain - can be Normal or Project', - PRIMARY KEY (`id`), - UNIQUE (parent, name, removed), - INDEX `i_domain__path`(`path`), - INDEX `i_domain__removed`(`removed`), - CONSTRAINT `uc_domain__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`account` ( - `id` bigint unsigned NOT NULL auto_increment, - `account_name` varchar(100) COMMENT 'an account name set by the creator of the account, defaults to username for single accounts', - `uuid` varchar(40), - `type` int(1) unsigned NOT NULL, - `domain_id` bigint unsigned, - `state` varchar(10) NOT NULL default 'enabled', - `removed` datetime COMMENT 'date removed', - `cleanup_needed` tinyint(1) NOT NULL default '0', - `network_domain` varchar(255), - `default_zone_id` bigint unsigned, - PRIMARY KEY (`id`), - INDEX i_account__removed(`removed`), - CONSTRAINT `fk_account__default_zone_id` FOREIGN KEY `fk_account__default_zone_id`(`default_zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_account__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`resource_limit` ( - `id` bigint unsigned NOT NULL auto_increment, - `domain_id` bigint unsigned, - `account_id` bigint unsigned, - `type` varchar(255), - `max` bigint NOT NULL default '-1', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`resource_count` ( - `id` bigint unsigned NOT NULL auto_increment, - `account_id` bigint unsigned, - `domain_id` bigint unsigned, - `type` varchar(255), - `count` bigint NOT NULL default '0', - PRIMARY KEY (`id`), - CONSTRAINT `fk_resource_count__account_id` FOREIGN KEY `fk_resource_count__account_id`(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_resource_count__domain_id` FOREIGN KEY `fk_resource_count__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - INDEX `i_resource_count__type`(`type`), - UNIQUE `i_resource_count__type_accountId`(`type`, `account_id`), - UNIQUE `i_resource_count__type_domaintId`(`type`, `domain_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_host_capacity` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned, - `data_center_id` bigint unsigned NOT NULL, - `pod_id` bigint unsigned, - `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', - `used_capacity` bigint signed NOT NULL, - `reserved_capacity` bigint signed NOT NULL, - `total_capacity` bigint signed NOT NULL, - `capacity_type` int(1) unsigned NOT NULL, - `capacity_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this capacity enabled for allocation for new resources', - `update_time` datetime COMMENT 'time the capacity was last updated', - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - INDEX `i_op_host_capacity__host_type`(`host_id`, `capacity_type`), - INDEX `i_op_host_capacity__pod_id`(`pod_id`), - INDEX `i_op_host_capacity__data_center_id`(`data_center_id`), - INDEX `i_op_host_capacity__cluster_id`(`cluster_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`alert` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `type` int(1) unsigned NOT NULL, - `cluster_id` bigint unsigned, - `pod_id` bigint unsigned, - `data_center_id` bigint unsigned NOT NULL, - `subject` varchar(999) COMMENT 'according to SMTP spec, max subject length is 1000 including the CRLF character, so allow enough space to fit long pod/zone/host names', - `sent_count` int(3) unsigned NOT NULL, - `created` DATETIME NULL COMMENT 'when this alert type was created', - `last_sent` DATETIME NULL COMMENT 'Last time the alert was sent', - `resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)', - PRIMARY KEY (`id`), - CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`async_job` ( - `id` bigint unsigned NOT NULL auto_increment, - `user_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `session_key` varchar(64) COMMENT 'all async-job manage to apply session based security enforcement', - `instance_type` varchar(64) COMMENT 'instance_type and instance_id work together to allow attaching an instance object to a job', - `instance_id` bigint unsigned, - `job_cmd` varchar(64) NOT NULL COMMENT 'command name', - `job_cmd_originator` varchar(64) COMMENT 'command originator', - `job_cmd_info` text COMMENT 'command parameter info', - `job_cmd_ver` int(1) COMMENT 'command version', - `callback_type` int(1) COMMENT 'call back type, 0 : polling, 1 : email', - `callback_address` varchar(128) COMMENT 'call back address by callback_type', - `job_status` int(1) COMMENT 'general job execution status', - `job_process_status` int(1) COMMENT 'job specific process status for asynchronize progress update', - `job_result_code` int(1) COMMENT 'job result code, specify error code corresponding to result message', - `job_result` text COMMENT 'job result info', - `job_init_msid` bigint COMMENT 'the initiating msid', - `job_complete_msid` bigint COMMENT 'completing msid', - `created` datetime COMMENT 'date created', - `last_updated` datetime COMMENT 'date created', - `last_polled` datetime COMMENT 'date polled', - `removed` datetime COMMENT 'date removed', - `uuid` varchar(40), - PRIMARY KEY (`id`), - INDEX `i_async_job__removed`(`removed`), - INDEX `i_async__user_id`(`user_id`), - INDEX `i_async__account_id`(`account_id`), - INDEX `i_async__instance_type_id`(`instance_type`,`instance_id`), - INDEX `i_async__job_cmd`(`job_cmd`), - INDEX `i_async__created`(`created`), - INDEX `i_async__last_updated`(`last_updated`), - INDEX `i_async__last_poll`(`last_polled`), - CONSTRAINT `uc_async__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`sync_queue` ( - `id` bigint unsigned NOT NULL auto_increment, - `sync_objtype` varchar(64) NOT NULL, - `sync_objid` bigint unsigned NOT NULL, - `queue_proc_msid` bigint, - `queue_proc_number` bigint COMMENT 'process number, increase 1 for each iteration', - `queue_proc_time` datetime COMMENT 'last time to process the queue', - `created` datetime COMMENT 'date created', - `last_updated` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - UNIQUE `i_sync_queue__objtype__objid`(`sync_objtype`, `sync_objid`), - INDEX `i_sync_queue__created`(`created`), - INDEX `i_sync_queue__last_updated`(`last_updated`), - INDEX `i_sync_queue__queue_proc_time`(`queue_proc_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`stack_maid` ( - `id` bigint unsigned NOT NULL auto_increment, - `msid` bigint unsigned NOT NULL, - `thread_id` bigint unsigned NOT NULL, - `seq` int unsigned NOT NULL, - `cleanup_delegate` varchar(128), - `cleanup_context` text, - `created` datetime, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`sync_queue_item` ( - `id` bigint unsigned NOT NULL auto_increment, - `queue_id` bigint unsigned NOT NULL, - `content_type` varchar(64), - `content_id` bigint, - `queue_proc_msid` bigint COMMENT 'owner msid when the queue item is being processed', - `queue_proc_number` bigint COMMENT 'used to distinguish raw items and items being in process', - `created` datetime COMMENT 'time created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_sync_queue_item__queue_id` FOREIGN KEY `fk_sync_queue_item__queue_id` (`queue_id`) REFERENCES `sync_queue` (`id`) ON DELETE CASCADE, - INDEX `i_sync_queue_item__queue_id`(`queue_id`), - INDEX `i_sync_queue_item__created`(`created`), - INDEX `i_sync_queue_item__queue_proc_number`(`queue_proc_number`), - INDEX `i_sync_queue_item__queue_proc_msid`(`queue_proc_msid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`disk_offering` ( - `id` bigint unsigned NOT NULL auto_increment, - `domain_id` bigint unsigned, - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - `display_text` varchar(4096) NULL COMMENT 'Descrianaption text set by the admin for display purpose only', - `disk_size` bigint unsigned NOT NULL COMMENT 'disk space in byte', - `type` varchar(32) COMMENT 'inheritted by who?', - `tags` varchar(4096) COMMENT 'comma separated tags about the disk_offering', - `recreatable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'The root disk is always recreatable', - `use_local_storage` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Indicates whether local storage pools should be used', - `unique_name` varchar(32) UNIQUE COMMENT 'unique name', - `system_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'is this offering for system used only', - `customized` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0 implies not customized by default', - `removed` datetime COMMENT 'date removed', - `created` datetime COMMENT 'date the disk offering was created', - `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', - PRIMARY KEY (`id`), - INDEX `i_disk_offering__removed`(`removed`), - CONSTRAINT `uc_disk_offering__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`service_offering` ( - `id` bigint unsigned NOT NULL, - `cpu` int(10) unsigned NOT NULL COMMENT '# of cores', - `speed` int(10) unsigned NOT NULL COMMENT 'speed per core in mhz', - `ram_size` bigint unsigned NOT NULL, - `nw_rate` smallint unsigned default 200 COMMENT 'network rate throttle mbits/s', - `mc_rate` smallint unsigned default 10 COMMENT 'mcast rate throttle mbits/s', - `ha_enabled` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Enable HA', - `limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the CPU usage to service offering', - `host_tag` varchar(255) COMMENT 'host tag specified by the service_offering', - `default_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'is this offering a default system offering', - `vm_type` varchar(32) COMMENT 'type of offering specified for system offerings', - `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', - PRIMARY KEY (`id`), - CONSTRAINT `fk_service_offering__id` FOREIGN KEY `fk_service_offering__id`(`id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`network_rule_config` ( - `id` bigint unsigned NOT NULL auto_increment, - `security_group_id` bigint unsigned NOT NULL, - `public_port` varchar(10) default NULL, - `private_port` varchar(10) default NULL, - `protocol` varchar(16) NOT NULL default 'TCP', - `create_status` varchar(32) COMMENT 'rule creation status', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`remote_access_vpn` ( - `vpn_server_addr_id` bigint unsigned UNIQUE NOT NULL, - `account_id` bigint unsigned NOT NULL, - `network_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `local_ip` char(40) NOT NULL, - `ip_range` varchar(32) NOT NULL, - `ipsec_psk` varchar(256) NOT NULL, - `state` char(32) NOT NULL, - PRIMARY KEY (`vpn_server_addr_id`), - CONSTRAINT `fk_remote_access_vpn__account_id` FOREIGN KEY `fk_remote_access_vpn__account_id`(`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_remote_access_vpn__domain_id` FOREIGN KEY `fk_remote_access_vpn__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_remote_access_vpn__network_id` FOREIGN KEY `fk_remote_access_vpn__network_id` (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_remote_access_vpn__vpn_server_addr_id` FOREIGN KEY `fk_remote_access_vpn__vpn_server_addr_id` (`vpn_server_addr_id`) REFERENCES `user_ip_address` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vpn_users` ( - `id` bigint unsigned NOT NULL UNIQUE auto_increment, - `uuid` varchar(40), - `owner_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `username` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `state` char(32) NOT NULL COMMENT 'What state is this vpn user in', - PRIMARY KEY (`id`), - CONSTRAINT `fk_vpn_users__owner_id` FOREIGN KEY (`owner_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_vpn_users__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - INDEX `i_vpn_users_username`(`username`), - UNIQUE `i_vpn_users__account_id__username`(`owner_id`, `username`), - CONSTRAINT `uc_vpn_users__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`storage_pool` ( - `id` bigint unsigned UNIQUE NOT NULL, - `name` varchar(255) COMMENT 'should be NOT NULL', - `uuid` varchar(255) UNIQUE, - `pool_type` varchar(32) NOT NULL, - `port` int unsigned NOT NULL, - `data_center_id` bigint unsigned NOT NULL, - `pod_id` bigint unsigned, - `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', - `available_bytes` bigint unsigned, - `capacity_bytes` bigint unsigned, - `host_address` varchar(255) NOT NULL COMMENT 'FQDN or IP of storage server', - `path` varchar(255) NOT NULL COMMENT 'Filesystem path that is shared', - `created` datetime COMMENT 'date the pool created', - `removed` datetime COMMENT 'date removed if not null', - `update_time` DATETIME, - `status` varchar(32), - PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_pool__pod_id` FOREIGN KEY `fk_storage_pool__pod_id` (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, - INDEX `i_storage_pool__pod_id`(`pod_id`), - CONSTRAINT `fk_storage_pool__cluster_id` FOREIGN KEY `fk_storage_pool__cluster_id`(`cluster_id`) REFERENCES `cloud`.`cluster`(`id`), - INDEX `i_storage_pool__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`storage_pool_details` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', - `pool_id` bigint unsigned NOT NULL COMMENT 'pool the detail is related to', - `name` varchar(255) NOT NULL COMMENT 'name of the detail', - `value` varchar(255) NOT NULL COMMENT 'value of the detail', - PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_pool_details__pool_id` FOREIGN KEY `fk_storage_pool_details__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE, - INDEX `i_storage_pool_details__name__value`(`name`(128), `value`(128)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`storage_pool_host_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `host_id` bigint unsigned NOT NULL, - `pool_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `local_path` varchar(255), - PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_pool_host_ref__host_id` FOREIGN KEY `fk_storage_pool_host_ref__host_id`(`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_storage_pool_host_ref__pool_id` FOREIGN KEY `fk_storage_pool_host_ref__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`template_spool_ref` ( - `id` bigint unsigned NOT NULL auto_increment, - `pool_id` bigint unsigned NOT NULL, - `template_id` bigint unsigned NOT NULL, - `created` DATETIME NOT NULL, - `last_updated` DATETIME, - `job_id` varchar(255), - `download_pct` int(10) unsigned, - `download_state` varchar(255), - `error_str` varchar(255), - `local_path` varchar(255), - `install_path` varchar(255), - `template_size` bigint unsigned NOT NULL COMMENT 'the size of the template on the pool', - `marked_for_gc` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'if true, the garbage collector will evict the template from this pool.', - PRIMARY KEY (`id`), - UNIQUE `i_template_spool_ref__template_id__pool_id`(`template_id`, `pool_id`), - CONSTRAINT `fk_template_spool_ref__template_id` FOREIGN KEY (`template_id`) REFERENCES `vm_template`(`id`), - CONSTRAINT `fk_template_spool_ref__pool_id` FOREIGN KEY (`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`guest_os` ( - `id` bigint unsigned NOT NULL auto_increment, - `category_id` bigint unsigned NOT NULL, - `name` varchar(255), - `uuid` varchar(40), - `display_name` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `uc_guest_os__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`guest_os_hypervisor` ( - `id` bigint unsigned NOT NULL auto_increment, - `hypervisor_type` varchar(32) NOT NULL, - `guest_os_name` varchar(255) NOT NULL, - `guest_os_id` bigint unsigned NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`guest_os_category` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - PRIMARY KEY (`id`), - CONSTRAINT `uc_guest_os_category__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`hypervisor_capabilities` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `hypervisor_type` varchar(32) NOT NULL, - `hypervisor_version` varchar(32), - `max_guests_limit` bigint unsigned DEFAULT 50, - `security_group_enabled` int(1) unsigned DEFAULT 1 COMMENT 'Is security group supported', - PRIMARY KEY (`id`), - CONSTRAINT `uc_hypervisor_capabilities__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', 'default', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', 'XCP 1.0', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6 FP1', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6 SP2', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '6.0', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '6.0.2', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', 'default', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.0', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.1', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '5.0', 128, 0); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('KVM', 'default', 50, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', 'default', 25, 1); -INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', '2.3', 25, 1); - -CREATE TABLE `cloud`.`launch_permission` ( - `id` bigint unsigned NOT NULL auto_increment, - `template_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`snapshot_policy` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `volume_id` bigint unsigned NOT NULL, - `schedule` varchar(100) NOT NULL COMMENT 'schedule time of execution', - `timezone` varchar(100) NOT NULL COMMENT 'the timezone in which the schedule time is specified', - `interval` int(4) NOT NULL default 4 COMMENT 'backup schedule, e.g. hourly, daily, etc.', - `max_snaps` int(8) NOT NULL default 0 COMMENT 'maximum number of snapshots to maintain', - `active` tinyint(1) unsigned NOT NULL COMMENT 'Is the policy active', - PRIMARY KEY (`id`), - CONSTRAINT `uc_snapshot_policy__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`snapshot_schedule` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `volume_id` bigint unsigned NOT NULL COMMENT 'The volume for which this snapshot is being taken', - `policy_id` bigint unsigned NOT NULL COMMENT 'One of the policyIds for which this snapshot was taken', - `scheduled_timestamp` datetime NOT NULL COMMENT 'Time at which the snapshot was scheduled for execution', - `async_job_id` bigint unsigned COMMENT 'If this schedule is being executed, it is the id of the create aysnc_job. Before that it is null', - `snapshot_id` bigint unsigned COMMENT 'If this schedule is being executed, then the corresponding snapshot has this id. Before that it is null', - UNIQUE (volume_id, policy_id), - CONSTRAINT `uc_snapshot_schedule__uuid` UNIQUE (`uuid`), - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_pod_vlan_alloc` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary id', - `vlan` varchar(18) NOT NULL COMMENT 'vlan id', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center the pod belongs to', - `pod_id` bigint unsigned NOT NULL COMMENT 'pod the vlan belongs to', - `account_id` bigint unsigned NULL COMMENT 'account the vlan belongs to right now', - `taken` datetime COMMENT 'Date taken', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`security_group` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - `description` varchar(4096) NULL, - `domain_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - UNIQUE (`name`, `account_id`), - PRIMARY KEY (`id`), - CONSTRAINT `uc_security_group__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`security_group_rule` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `security_group_id` bigint unsigned NOT NULL, - `type` varchar(10) default 'ingress', - `start_port` varchar(10) default NULL, - `end_port` varchar(10) default NULL, - `protocol` varchar(16) NOT NULL default 'TCP', - `allowed_network_id` bigint unsigned, - `allowed_ip_cidr` varchar(44), - `create_status` varchar(32) COMMENT 'rule creation status', - PRIMARY KEY (`id`), - CONSTRAINT `uc_security_group_rule__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`security_group_vm_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `security_group_id` bigint unsigned NOT NULL, - `instance_id` bigint unsigned NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_nwgrp_work` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', - `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs rules to be synced.', - `mgmt_server_id` bigint unsigned COMMENT 'management server that has taken up the work of doing rule sync', - `created` datetime NOT NULL COMMENT 'time the entry was requested', - `taken` datetime COMMENT 'time it was taken by the management server', - `step` varchar(32) NOT NULL COMMENT 'Step in the work', - `seq_no` bigint unsigned COMMENT 'seq number to be sent to agent, uniquely identifies ruleset update', - PRIMARY KEY (`id`), - INDEX `i_op_nwgrp_work__instance_id`(`instance_id`), - INDEX `i_op_nwgrp_work__mgmt_server_id`(`mgmt_server_id`), - INDEX `i_op_nwgrp_work__taken`(`taken`), - INDEX `i_op_nwgrp_work__step`(`step`), - INDEX `i_op_nwgrp_work__seq_no`(`seq_no`) -) ENGINE=MEMORY DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_vm_ruleset_log` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', - `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs rules to be synced.', - `created` datetime NOT NULL COMMENT 'time the entry was requested', - `logsequence` bigint unsigned COMMENT 'seq number to be sent to agent, uniquely identifies ruleset update', - PRIMARY KEY (`id`), - UNIQUE `u_op_vm_ruleset_log__instance_id`(`instance_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`instance_group` ( - `id` bigint unsigned NOT NULL UNIQUE auto_increment, - `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', - `name` varchar(255) NOT NULL, - `uuid` varchar(40), - `removed` datetime COMMENT 'date the group was removed', - `created` datetime COMMENT 'date the group was created', - PRIMARY KEY (`id`), - INDEX `i_instance_group__removed`(`removed`), - CONSTRAINT `uc_instance_group__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`instance_group_vm_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `group_id` bigint unsigned NOT NULL, - `instance_id` bigint unsigned NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`ssh_keypairs` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `account_id` bigint unsigned NOT NULL COMMENT 'owner, foreign key to account table', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain, foreign key to domain table', - `keypair_name` varchar(256) NOT NULL COMMENT 'name of the key pair', - `fingerprint` varchar(128) NOT NULL COMMENT 'fingerprint for the ssh public key', - `public_key` varchar(5120) NOT NULL COMMENT 'public key of the ssh key pair', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`usage_event` ( - `id` bigint unsigned NOT NULL auto_increment, - `type` varchar(32) NOT NULL, - `account_id` bigint unsigned NOT NULL, - `created` datetime NOT NULL, - `zone_id` bigint unsigned NOT NULL, - `resource_id` bigint unsigned, - `resource_name` varchar(255), - `offering_id` bigint unsigned, - `template_id` bigint unsigned, - `size` bigint unsigned, - `resource_type` varchar(32), - `processed` tinyint NOT NULL default '0', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`ovs_tunnel_interface` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `ip` varchar(16) DEFAULT NULL, - `netmask` varchar(16) DEFAULT NULL, - `mac` varchar(18) DEFAULT NULL, - `host_id` bigint DEFAULT NULL, - `label` varchar(45) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `cloud`.`ovs_tunnel_interface` (`ip`, `netmask`, `mac`, `host_id`, `label`) VALUES ('0', '0', '0', 0, 'lock'); - -CREATE TABLE `cloud`.`ovs_tunnel_network`( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, - `from` bigint unsigned COMMENT 'from host id', - `to` bigint unsigned COMMENT 'to host id', - `network_id` bigint unsigned COMMENT 'network identifier', - `key` int unsigned COMMENT 'gre key', - `port_name` varchar(32) COMMENT 'in port on open vswitch', - `state` varchar(16) default 'FAILED' COMMENT 'result of tunnel creatation', - PRIMARY KEY(`from`, `to`, `network_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `cloud`.`ovs_tunnel_network` (`from`, `to`, `network_id`, `key`, `port_name`, `state`) VALUES (0, 0, 0, 0, 'lock', 'SUCCESS'); - -CREATE TABLE `cloud`.`storage_pool_work` ( - `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', - `pool_id` bigint unsigned NOT NULL COMMENT 'storage pool associated with the vm', - `vm_id` bigint unsigned NOT NULL COMMENT 'vm identifier', - `stopped_for_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was stopped during maintenance', - `started_after_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was started after maintenance', - `mgmt_server_id` bigint unsigned NOT NULL COMMENT 'management server id', - PRIMARY KEY (`id`), - UNIQUE (pool_id,vm_id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`data_center_details` ( - `id` bigint unsigned NOT NULL auto_increment, - `dc_id` bigint unsigned NOT NULL COMMENT 'dc id', - `name` varchar(255) NOT NULL, - `value` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - CONSTRAINT `fk_dc_details__dc_id` FOREIGN KEY (`dc_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`domain_network_ref` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', - `network_id` bigint unsigned NOT NULL COMMENT 'network id', - `subdomain_access` int(1) unsigned COMMENT '1 if network can be accessible from the subdomain', - PRIMARY KEY (`id`), - CONSTRAINT `fk_domain_network_ref__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_domain_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`cmd_exec_log` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `host_id` bigint unsigned NOT NULL COMMENT 'host id of the system VM agent that command is sent to', - `instance_id` bigint unsigned NOT NULL COMMENT 'instance id of the system VM that command is executed on', - `command_name` varchar(255) NOT NULL COMMENT 'command name', - `weight` integer NOT NULL DEFAULT 1 COMMENT 'command weight in consideration of the load factor added to host that is executing the command', - `created` datetime NOT NULL COMMENT 'date created', - PRIMARY KEY (`id`), - INDEX `i_cmd_exec_log__host_id`(`host_id`), - INDEX `i_cmd_exec_log__instance_id`(`instance_id`), - CONSTRAINT `fk_cmd_exec_log_ref__inst_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`keystore` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `name` varchar(64) NOT NULL COMMENT 'unique name for the certifiation', - `certificate` text NOT NULL COMMENT 'the actual certificate being stored in the db', - `key` text COMMENT 'private key associated wih the certificate', - `domain_suffix` varchar(256) NOT NULL COMMENT 'DNS domain suffix associated with the certificate', - `seq` int, - PRIMARY KEY (`id`), - UNIQUE(name) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`swift` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `uuid` varchar(40), - `url` varchar(255) NOT NULL, - `account` varchar(255) NOT NULL COMMENT ' account in swift', - `username` varchar(255) NOT NULL COMMENT ' username in swift', - `key` varchar(255) NOT NULL COMMENT 'token for this user', - `created` datetime COMMENT 'date the swift first signed on', - PRIMARY KEY (`id`), - CONSTRAINT `uc_swift__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`op_host_transfer` ( - `id` bigint unsigned UNIQUE NOT NULL COMMENT 'Id of the host', - `initial_mgmt_server_id` bigint unsigned COMMENT 'management server the host is transfered from', - `future_mgmt_server_id` bigint unsigned COMMENT 'management server the host is transfered to', - `state` varchar(32) NOT NULL COMMENT 'the transfer state of the host', - `created` datetime NOT NULL COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_op_host_transfer__id` FOREIGN KEY `fk_op_host_transfer__id` (`id`) REFERENCES `host` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_op_host_transfer__initial_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__initial_mgmt_server_id`(`initial_mgmt_server_id`) REFERENCES `mshost`(`msid`), - CONSTRAINT `fk_op_host_transfer__future_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__future_mgmt_server_id`(`future_mgmt_server_id`) REFERENCES `mshost`(`msid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`projects` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255) COMMENT 'project name', - `uuid` varchar(40), - `display_text` varchar(255) COMMENT 'project name', - `project_account_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `created` datetime COMMENT 'date created', - `removed` datetime COMMENT 'date removed', - `state` varchar(255) NOT NULL COMMENT 'state of the project (Active/Inactive/Suspended)', - PRIMARY KEY (`id`), - CONSTRAINT `fk_projects__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_projects__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - INDEX `i_projects__removed`(`removed`), - CONSTRAINT `uc_projects__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`project_account` ( - `id` bigint unsigned NOT NULL auto_increment, - `account_id` bigint unsigned NOT NULL COMMENT'account id', - `account_role` varchar(255) NOT NULL DEFAULT 'Regular' COMMENT 'Account role in the project (Owner or Regular)', - `project_id` bigint unsigned NOT NULL COMMENT 'project id', - `project_account_id` bigint unsigned NOT NULL, - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_project_account__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_project_account__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_project_account__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - UNIQUE (`account_id`, `project_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`project_invitations` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `project_id` bigint unsigned NOT NULL COMMENT 'project id', - `account_id` bigint unsigned COMMENT 'account id', - `domain_id` bigint unsigned COMMENT 'domain id', - `email` varchar(255) COMMENT 'email', - `token` varchar(255) COMMENT 'token', - `state` varchar(255) NOT NULL DEFAULT 'Pending' COMMENT 'the state of the invitation', - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_project_invitations__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_project_invitations__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_project_invitations__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, - UNIQUE (`project_id`, `account_id`), - UNIQUE (`project_id`, `email`), - UNIQUE (`project_id`, `token`), - CONSTRAINT `uc_project_invitations__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`elastic_lb_vm_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `ip_addr_id` bigint unsigned NOT NULL, - `elb_vm_id` bigint unsigned NOT NULL, - `lb_id` bigint unsigned, - PRIMARY KEY (`id`), - CONSTRAINT `fk_elastic_lb_vm_map__ip_id` FOREIGN KEY `fk_elastic_lb_vm_map__ip_id` (`ip_addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_elastic_lb_vm_map__elb_vm_id` FOREIGN KEY `fk_elastic_lb_vm_map__elb_vm_id` (`elb_vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_elastic_lb_vm_map__lb_id` FOREIGN KEY `fk_elastic_lb_vm_map__lb_id` (`lb_id`) REFERENCES `load_balancing_rules` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `ntwk_offering_service_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `network_offering_id` bigint unsigned NOT NULL COMMENT 'network_offering_id', - `service` varchar(255) NOT NULL COMMENT 'service', - `provider` varchar(255) COMMENT 'service provider', - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_ntwk_offering_service_map__network_offering_id` FOREIGN KEY(`network_offering_id`) REFERENCES `network_offerings`(`id`) ON DELETE CASCADE, - UNIQUE (`network_offering_id`, `service`, `provider`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `ntwk_service_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `network_id` bigint unsigned NOT NULL COMMENT 'network_id', - `service` varchar(255) NOT NULL COMMENT 'service', - `provider` varchar(255) COMMENT 'service provider', - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_ntwk_service_map__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - UNIQUE (`network_id`, `service`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`physical_network` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(40), - `name` varchar(255) NOT NULL, - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this physical network belongs to', - `vnet` varchar(255), - `speed` varchar(32), - `domain_id` bigint unsigned COMMENT 'foreign key to domain id', - `broadcast_domain_range` varchar(32) NOT NULL DEFAULT 'POD' COMMENT 'range of broadcast domain : POD/ZONE', - `state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'what state is this configuration in', - `created` datetime COMMENT 'date created', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_physical_network__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_physical_network__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), - CONSTRAINT `uc_physical_networks__uuid` UNIQUE (`uuid`), - INDEX `i_physical_network__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`physical_network_tags` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', - `tag` varchar(255) NOT NULL COMMENT 'tag', - PRIMARY KEY (`id`), - CONSTRAINT `fk_physical_network_tags__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, - UNIQUE KEY(`physical_network_id`, `tag`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`physical_network_isolation_methods` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', - `isolation_method` varchar(255) NOT NULL COMMENT 'isolation method(VLAN, L3 or GRE)', - PRIMARY KEY (`id`), - CONSTRAINT `fk_physical_network_imethods__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, - UNIQUE KEY(`physical_network_id`, `isolation_method`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`physical_network_traffic_types` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(40), - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', - `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', - `xen_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host', - `kvm_network_label` varchar(255) DEFAULT 'cloudbr0' COMMENT 'The network name label of the physical device dedicated to this traffic on a KVM host', - `vmware_network_label` varchar(255) DEFAULT 'vSwitch0' COMMENT 'The network name label of the physical device dedicated to this traffic on a VMware host', - `simulator_network_label` varchar(255) COMMENT 'The name labels needed for identifying the simulator', - `ovm_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a Ovm host', - `vlan` varchar(255) COMMENT 'The vlan tag to be sent down to a VMware host', - PRIMARY KEY (`id`), - CONSTRAINT `fk_physical_network_traffic_types__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_traffic_types__uuid` UNIQUE (`uuid`), - UNIQUE KEY(`physical_network_id`, `traffic_type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`physical_network_service_providers` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(40), - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', - `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name', - `state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'provider state', - `destination_physical_network_id` bigint unsigned COMMENT 'id of the physical network to bridge to', - `vpn_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is VPN service provided', - `dhcp_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is DHCP service provided', - `dns_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is DNS service provided', - `gateway_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Gateway service provided', - `firewall_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Firewall service provided', - `source_nat_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Source NAT service provided', - `load_balance_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is LB service provided', - `static_nat_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Static NAT service provided', - `port_forwarding_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Port Forwarding service provided', - `user_data_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is UserData service provided', - `security_group_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is SG service provided', - `networkacl_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Network ACL service provided', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_pnetwork_service_providers__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_service_providers__uuid` UNIQUE (`uuid`), - UNIQUE KEY(`physical_network_id`, `provider_name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`external_load_balancer_devices` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(255) UNIQUE, - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which load balancer device is added', - `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this load balancer device', - `device_name` varchar(255) NOT NULL COMMENT 'name of the load balancer device', - `capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the load balancer device', - `device_state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device', - `allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state (Free/Shared/Dedicated/Provider) of the device', - `is_dedicated` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device/appliance is provisioned for dedicated use only', - `is_inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer will be used in in-line configuration with firewall', - `is_managed` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer appliance is provisioned and its life cycle is managed by by cloudstack', - `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external load balancer device', - `parent_host_id` bigint unsigned COMMENT 'if the load balancer appliance is cloudstack managed, then host id on which this appliance is provisioned', - PRIMARY KEY (`id`), - CONSTRAINT `fk_external_lb_devices_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_external_lb_devices_parent_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_external_lb_devices_physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`external_firewall_devices` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(255) UNIQUE, - `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which firewall device is added', - `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this firewall device', - `device_name` varchar(255) NOT NULL COMMENT 'name of the firewall device', - `device_state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device', - `is_dedicated` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device/appliance meant for dedicated use only', - `allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state (Free/Allocated) of the device', - `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external firewall device', - `capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the external firewall device', - PRIMARY KEY (`id`), - CONSTRAINT `fk_external_firewall_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_external_firewall_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`network_external_lb_device_map` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(255) UNIQUE, - `network_id` bigint unsigned NOT NULL COMMENT ' guest network id', - `external_load_balancer_device_id` bigint unsigned NOT NULL COMMENT 'id of external load balancer device assigned for this network', - `created` datetime COMMENT 'Date from when network started using the device', - `removed` datetime COMMENT 'Date till the network stopped using the device ', - PRIMARY KEY (`id`), - CONSTRAINT `fk_network_external_lb_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_network_external_lb_devices_device_id` FOREIGN KEY (`external_load_balancer_device_id`) REFERENCES `external_load_balancer_devices`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`network_external_firewall_device_map` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(255) UNIQUE, - `network_id` bigint unsigned NOT NULL COMMENT ' guest network id', - `external_firewall_device_id` bigint unsigned NOT NULL COMMENT 'id of external firewall device assigned for this device', - `created` datetime COMMENT 'Date from when network started using the device', - `removed` datetime COMMENT 'Date till the network stopped using the device ', - PRIMARY KEY (`id`), - CONSTRAINT `fk_network_external_firewall_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_network_external_firewall_devices_device_id` FOREIGN KEY (`external_firewall_device_id`) REFERENCES `external_firewall_devices`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`virtual_router_providers` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `nsp_id` bigint unsigned NOT NULL COMMENT 'Network Service Provider ID', - `uuid` varchar(40), - `type` varchar(255) NOT NULL COMMENT 'Virtual router, or ElbVM', - `enabled` int(1) NOT NULL COMMENT 'Enabled or disabled', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_virtual_router_providers__nsp_id` FOREIGN KEY (`nsp_id`) REFERENCES `physical_network_service_providers` (`id`) ON DELETE CASCADE, - CONSTRAINT `uc_virtual_router_providers__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`op_user_stats_log` ( - `user_stats_id` bigint unsigned NOT NULL, - `net_bytes_received` bigint unsigned NOT NULL default '0', - `net_bytes_sent` bigint unsigned NOT NULL default '0', - `current_bytes_received` bigint unsigned NOT NULL default '0', - `current_bytes_sent` bigint unsigned NOT NULL default '0', - `agg_bytes_received` bigint unsigned NOT NULL default '0', - `agg_bytes_sent` bigint unsigned NOT NULL default '0', - `updated` datetime COMMENT 'stats update timestamp', - UNIQUE KEY (`user_stats_id`, `updated`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`cluster_vsm_map` ( - `cluster_id` bigint unsigned NOT NULL, - `vsm_id` bigint unsigned NOT NULL, - PRIMARY KEY (`cluster_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`virtual_supervisor_module` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `host_id` bigint NOT NULL, - `vsm_name` varchar(255), - `username` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `ipaddr` varchar(80) NOT NULL, - `management_vlan` int(32), - `control_vlan` int(32), - `packet_vlan` int(32), - `storage_vlan` int(32), - `vsm_domain_id` bigint unsigned, - `config_mode` varchar(20), - `config_state` varchar(20), - `vsm_device_state` varchar(20) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`port_profile` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `port_profile_name` varchar(255), - `port_mode` varchar(10), - `vsm_id` bigint unsigned NOT NULL, - `trunk_low_vlan_id` int, - `trunk_high_vlan_id` int, - `access_vlan_id` int, - `port_type` varchar(20) NOT NULL, - `port_binding` varchar(20), - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`s2s_vpn_gateway` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `addr_id` bigint unsigned NOT NULL, - `vpc_id` bigint unsigned NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_s2s_vpn_gateway__addr_id` FOREIGN KEY (`addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_gateway__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_gateway__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_gateway__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_s2s_vpn_gateway__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`s2s_customer_gateway` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `gateway_ip` char(40) NOT NULL, - `guest_cidr_list` varchar(200) NOT NULL, - `ipsec_psk` varchar(256), - `ike_policy` varchar(30) NOT NULL, - `esp_policy` varchar(30) NOT NULL, - `lifetime` int, - `domain_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_s2s_customer_gateway__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_customer_gateway__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_s2s_customer_gateway__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`s2s_vpn_connection` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `vpn_gateway_id` bigint unsigned NULL, - `customer_gateway_id` bigint unsigned NULL, - `state` varchar(32) NOT NULL, - `domain_id` bigint unsigned NOT NULL, - `account_id` bigint unsigned NOT NULL, - `created` datetime NOT NULL COMMENT 'date created', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_s2s_vpn_connection__vpn_gateway_id` FOREIGN KEY (`vpn_gateway_id`) REFERENCES `s2s_vpn_gateway` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_connection__customer_gateway_id` FOREIGN KEY (`customer_gateway_id`) REFERENCES `s2s_customer_gateway` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_connection__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_s2s_vpn_connection__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_s2s_vpn_connection__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`resource_tags` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `key` varchar(255), - `value` varchar(255), - `resource_id` bigint unsigned NOT NULL, - `resource_uuid` varchar(40), - `resource_type` varchar(255), - `customer` varchar(255), - `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', - `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', - PRIMARY KEY (`id`), - CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), - CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), - UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`), - CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vpc` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40) NOT NULL, - `name` varchar(255) COMMENT 'vpc name', - `display_text` varchar(255) COMMENT 'vpc display text', - `cidr` varchar(18) COMMENT 'vpc cidr', - `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc offering id that this vpc is created from', - `zone_id` bigint unsigned NOT NULL COMMENT 'the id of the zone this Vpc belongs to', - `state` varchar(32) NOT NULL COMMENT 'state of the VP (can be Enabled and Disabled)', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain the vpc belongs to', - `account_id` bigint unsigned NOT NULL COMMENT 'owner of this vpc', - `network_domain` varchar(255) COMMENT 'network domain', - `removed` datetime COMMENT 'date removed if not null', - `created` datetime NOT NULL COMMENT 'date created', - `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the VPC', - PRIMARY KEY (`id`), - INDEX `i_vpc__removed`(`removed`), - CONSTRAINT `fk_vpc__zone_id` FOREIGN KEY `fk_vpc__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), - CONSTRAINT `fk_vpc__account_id` FOREIGN KEY `fk_vpc__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_vpc__domain_id` FOREIGN KEY `fk_vpc__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`vpc_offerings` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40) NOT NULL, - `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the vpc offering', - `name` varchar(255) COMMENT 'vpc name', - `display_text` varchar(255) COMMENT 'display text', - `state` char(32) COMMENT 'state of the vpc offering that has Disabled value by default', - `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if vpc offering is default', - `removed` datetime COMMENT 'date removed if not null', - `created` datetime NOT NULL COMMENT 'date created', - `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', - PRIMARY KEY (`id`), - INDEX `i_vpc__removed`(`removed`), - CONSTRAINT `fk_vpc_offerings__service_offering_id` FOREIGN KEY `fk_vpc_offerings__service_offering_id` (`service_offering_id`) REFERENCES `service_offering`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`vpc_offering_service_map` ( - `id` bigint unsigned NOT NULL auto_increment, - `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc_offering_id', - `service` varchar(255) NOT NULL COMMENT 'service', - `provider` varchar(255) COMMENT 'service provider', - `created` datetime COMMENT 'date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_vpc_offering_service_map__vpc_offering_id` FOREIGN KEY(`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`) ON DELETE CASCADE, - UNIQUE (`vpc_offering_id`, `service`, `provider`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`router_network_ref` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `router_id` bigint unsigned NOT NULL COMMENT 'router id', - `network_id` bigint unsigned NOT NULL COMMENT 'network id', - `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', - PRIMARY KEY (`id`), - CONSTRAINT `fk_router_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, - UNIQUE `i_router_network_ref__router_id__network_id`(`router_id`, `network_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`vpc_gateways` ( - `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', - `uuid` varchar(40), - `ip4_address` char(40) COMMENT 'ip4 address of the gateway', - `netmask` varchar(15) COMMENT 'netmask of the gateway', - `gateway` varchar(15) COMMENT 'gateway', - `vlan_tag` varchar(255), - `type` varchar(32) COMMENT 'type of gateway; can be Public/Private/Vpn', - `network_id` bigint unsigned NOT NULL COMMENT 'network id vpc gateway belongs to', - `vpc_id` bigint unsigned NOT NULL COMMENT 'id of the vpc the gateway belongs to', - `zone_id` bigint unsigned NOT NULL COMMENT 'id of the zone the gateway belongs to', - `created` datetime COMMENT 'date created', - `account_id` bigint unsigned NOT NULL COMMENT 'owner id', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', - `state` varchar(32) NOT NULL COMMENT 'what state the vpc gateway in', - `removed` datetime COMMENT 'date removed if not null', - PRIMARY KEY (`id`), - CONSTRAINT `fk_vpc_gateways__network_id` FOREIGN KEY `fk_vpc_gateways__network_id`(`network_id`) REFERENCES `networks`(`id`), - CONSTRAINT `fk_vpc_gateways__vpc_id` FOREIGN KEY `fk_vpc_gateways__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), - CONSTRAINT `fk_vpc_gateways__zone_id` FOREIGN KEY `fk_vpc_gateways__zone_id`(`zone_id`) REFERENCES `data_center`(`id`), - CONSTRAINT `fk_vpc_gateways__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_vpc_gateways__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_vpc_gateways__uuid` UNIQUE (`uuid`), - INDEX `i_vpc_gateways__removed`(`removed`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`private_ip_address` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', - `ip_address` char(40) NOT NULL COMMENT 'ip address', - `network_id` bigint unsigned NOT NULL COMMENT 'id of the network ip belongs to', - `reservation_id` char(40) COMMENT 'reservation id', - `mac_address` varchar(17) COMMENT 'mac address', - `vpc_id` bigint unsigned COMMENT 'vpc this ip belongs to', - `taken` datetime COMMENT 'Date taken', - PRIMARY KEY (`id`), - CONSTRAINT `fk_private_ip_address__vpc_id` FOREIGN KEY `fk_private_ip_address__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), - CONSTRAINT `fk_private_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`static_routes` ( - `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `uuid` varchar(40), - `vpc_gateway_id` bigint unsigned COMMENT 'id of the corresponding ip address', - `cidr` varchar(18) COMMENT 'cidr for the static route', - `state` char(32) NOT NULL COMMENT 'current state of this rule', - `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', - `account_id` bigint unsigned NOT NULL COMMENT 'owner id', - `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', - `created` datetime COMMENT 'Date created', - PRIMARY KEY (`id`), - CONSTRAINT `fk_static_routes__vpc_gateway_id` FOREIGN KEY(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_static_routes__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_static_routes__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_static_routes__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, - CONSTRAINT `uc_static_routes__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -SET foreign_key_checks = 1; - +# 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 +SET foreign_key_checks = 0; +use cloud; + +DROP VIEW IF EXISTS `cloud`.`port_forwarding_rules_view`; +DROP TABLE IF EXISTS `cloud`.`configuration`; +DROP TABLE IF EXISTS `cloud`.`ip_forwarding`; +DROP TABLE IF EXISTS `cloud`.`management_agent`; +DROP TABLE IF EXISTS `cloud`.`host`; +DROP TABLE IF EXISTS `cloud`.`mshost`; +DROP TABLE IF EXISTS `cloud`.`service_offering`; +DROP TABLE IF EXISTS `cloud`.`user`; +DROP TABLE IF EXISTS `cloud`.`user_ip_address`; +DROP TABLE IF EXISTS `cloud`.`user_statistics`; +DROP TABLE IF EXISTS `cloud`.`vm_template`; +DROP TABLE IF EXISTS `cloud`.`vm_instance`; +DROP TABLE IF EXISTS `cloud`.`domain_router`; +DROP TABLE IF EXISTS `cloud`.`event`; +DROP TABLE IF EXISTS `cloud`.`host_details`; +DROP TABLE IF EXISTS `cloud`.`host_pod_ref`; +DROP TABLE IF EXISTS `cloud`.`host_zone_ref`; +DROP TABLE IF EXISTS `cloud`.`data_ceneter`; +DROP TABLE IF EXISTS `cloud`.`volumes`; +DROP TABLE IF EXISTS `cloud`.`storage`; +DROP TABLE IF EXISTS `cloud`.`data_center`; +DROP TABLE IF EXISTS `cloud`.`pricing`; +DROP TABLE IF EXISTS `cloud`.`sequence`; +DROP TABLE IF EXISTS `cloud`.`user_vm`; +DROP TABLE IF EXISTS `cloud`.`template_host_ref`; +DROP TABLE IF EXISTS `cloud`.`volume_host_ref`; +DROP TABLE IF EXISTS `cloud`.`upload`; +DROP TABLE IF EXISTS `cloud`.`template_zone_ref`; +DROP TABLE IF EXISTS `cloud`.`dc_vnet_alloc`; +DROP TABLE IF EXISTS `cloud`.`dc_ip_address_alloc`; +DROP TABLE IF EXISTS `cloud`.`vlan`; +DROP TABLE IF EXISTS `cloud`.`host_vlan_map`; +DROP TABLE IF EXISTS `cloud`.`pod_vlan_map`; +DROP TABLE IF EXISTS `cloud`.`vm_host`; +DROP TABLE IF EXISTS `cloud`.`op_ha_work`; +DROP TABLE IF EXISTS `cloud`.`op_dc_vnet_alloc`; +DROP TABLE IF EXISTS `cloud`.`op_dc_ip_address_alloc`; +DROP TABLE IF EXISTS `cloud`.`op_vm_host`; +DROP TABLE IF EXISTS `cloud`.`op_host_queue`; +DROP TABLE IF EXISTS `cloud`.`console_proxy`; +DROP TABLE IF EXISTS `cloud`.`secondary_storage_vm`; +DROP TABLE IF EXISTS `cloud`.`domain`; +DROP TABLE IF EXISTS `cloud`.`account`; +DROP TABLE IF EXISTS `cloud`.`limit`; +DROP TABLE IF EXISTS `cloud`.`op_host_capacity`; +DROP TABLE IF EXISTS `cloud`.`alert`; +DROP TABLE IF EXISTS `cloud`.`op_lock`; +DROP TABLE IF EXISTS `cloud`.`op_host_upgrade`; +DROP TABLE IF EXISTS `cloud`.`snapshots`; +DROP TABLE IF EXISTS `cloud`.`scheduled_volume_backups`; +DROP TABLE IF EXISTS `cloud`.`disk_offering`; +DROP TABLE IF EXISTS `cloud`.`security_group`; +DROP TABLE IF EXISTS `cloud`.`network_rule_config`; +DROP TABLE IF EXISTS `cloud`.`host_details`; +DROP TABLE IF EXISTS `cloud`.`launch_permission`; +DROP TABLE IF EXISTS `cloud`.`resource_limit`; +DROP TABLE IF EXISTS `cloud`.`async_job`; +DROP TABLE IF EXISTS `cloud`.`sync_queue`; +DROP TABLE IF EXISTS `cloud`.`sync_queue_item`; +DROP TABLE IF EXISTS `cloud`.`security_group_vm_map`; +DROP TABLE IF EXISTS `cloud`.`load_balancer_vm_map`; +DROP TABLE IF EXISTS `cloud`.`load_balancer_stickiness_policies`; +DROP TABLE IF EXISTS `cloud`.`load_balancer_inline_ip_map`; +DROP TABLE IF EXISTS `cloud`.`storage_pool`; +DROP TABLE IF EXISTS `cloud`.`storage_pool_host_ref`; +DROP TABLE IF EXISTS `cloud`.`template_spool_ref`; +DROP TABLE IF EXISTS `cloud`.`guest_os`; +DROP TABLE IF EXISTS `cloud`.`snapshot_policy`; +DROP TABLE IF EXISTS `cloud`.`snapshot_policy_ref`; +DROP TABLE IF EXISTS `cloud`.`snapshot_schedule`; +DROP TABLE IF EXISTS `cloud`.`op_pod_vlan_alloc`; +DROP TABLE IF EXISTS `cloud`.`storage_pool_details`; +DROP TABLE IF EXISTS `cloud`.`cluster`; +DROP TABLE IF EXISTS `cloud`.`nics`; +DROP TABLE IF EXISTS `cloud`.`networks`; +DROP TABLE IF EXISTS `cloud`.`op_networks`; +DROP TABLE IF EXISTS `cloud`.`network_offerings`; +DROP TABLE IF EXISTS `cloud`.`account_network_ref`; +DROP TABLE IF EXISTS `cloud`.`domain_network_ref`; +DROP TABLE IF EXISTS `cloud`.`instance_group`; +DROP TABLE IF EXISTS `cloud`.`instance_group_vm_map`; +DROP TABLE IF EXISTS `cloud`.`op_it_work`; +DROP TABLE IF EXISTS `cloud`.`load_balancing_ip_map`; +DROP TABLE IF EXISTS `cloud`.`load_balancing_rules`; +DROP TABLE IF EXISTS `cloud`.`port_forwarding_rules`; +DROP TABLE IF EXISTS `cloud`.`firewall_rules`; +DROP TABLE IF EXISTS `cloud`.`firewall_rules_cidrs`; +DROP TABLE IF EXISTS `cloud`.`ssh_keypairs`; +DROP TABLE IF EXISTS `cloud`.`usage_event`; +DROP TABLE IF EXISTS `cloud`.`host_tags`; +DROP TABLE IF EXISTS `cloud`.`version`; +DROP TABLE IF EXISTS `cloud`.`account_vlan_map`; +DROP TABLE IF EXISTS `cloud`.`cluster_details`; +DROP TABLE IF EXISTS `cloud`.`guest_os_category`; +DROP TABLE IF EXISTS `cloud`.`guest_os_hypervisor`; +DROP TABLE IF EXISTS `cloud`.`op_dc_link_local_ip_address_alloc`; +DROP TABLE IF EXISTS `cloud`.`op_host`; +DROP TABLE IF EXISTS `cloud`.`op_nwgrp_work`; +DROP TABLE IF EXISTS `cloud`.`op_vm_ruleset_log`; +DROP TABLE IF EXISTS `cloud`.`ovs_tunnel_network`; +DROP TABLE IF EXISTS `cloud`.`ovs_tunnel_interface`; +DROP TABLE IF EXISTS `cloud`.`remote_access_vpn`; +DROP TABLE IF EXISTS `cloud`.`resource_count`; +DROP TABLE IF EXISTS `cloud`.`security_ingress_rule`; +DROP TABLE IF EXISTS `cloud`.`security_group_rule`; +DROP TABLE IF EXISTS `cloud`.`stack_maid`; +DROP TABLE IF EXISTS `cloud`.`storage_pool_work`; +DROP TABLE IF EXISTS `cloud`.`user_vm_details`; +DROP TABLE IF EXISTS `cloud`.`vpn_users`; +DROP TABLE IF EXISTS `cloud`.`data_center_details`; +DROP TABLE IF EXISTS `cloud`.`network_tags`; +DROP TABLE IF EXISTS `cloud`.`op_host_transfer`; +DROP TABLE IF EXISTS `cloud`.`projects`; +DROP TABLE IF EXISTS `cloud`.`physical_network`; +DROP TABLE IF EXISTS `cloud`.`physical_network_tags`; +DROP TABLE IF EXISTS `cloud`.`physical_network_isolation_methods`; +DROP TABLE IF EXISTS `cloud`.`physical_network_traffic_types`; +DROP TABLE IF EXISTS `cloud`.`physical_network_service_providers`; +DROP TABLE IF EXISTS `cloud`.`virtual_router_elements`; +DROP TABLE IF EXISTS `cloud`.`dc_storage_network_ip_range`; +DROP TABLE IF EXISTS `cloud`.`op_dc_storage_network_ip_address`; +DROP TABLE IF EXISTS `cloud`.`cluster_vsm_map`; +DROP TABLE IF EXISTS `cloud`.`virtual_supervisor_module`; +DROP TABLE IF EXISTS `cloud`.`port_profile`; +DROP TABLE IF EXISTS `cloud`.`s2s_customer_gateway`; +DROP TABLE IF EXISTS `cloud`.`s2s_vpn_gateway`; +DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; +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', + `version` char(40) NOT NULL UNIQUE COMMENT 'version', + `updated` datetime NOT NULL COMMENT 'Date this version table was updated', + `step` char(32) NOT NULL COMMENT 'Step in the upgrade to this version', + PRIMARY KEY (`id`), + INDEX `i_version__version`(`version`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `version` (`version`, `updated`, `step`) VALUES('@VERSION@', now(), 'Complete'); + +CREATE TABLE `cloud`.`op_it_work` ( + `id` char(40) COMMENT 'reservation id', + `mgmt_server_id` bigint unsigned COMMENT 'management server id', + `created_at` bigint unsigned NOT NULL COMMENT 'when was this work detail created', + `thread` varchar(255) NOT NULL COMMENT 'thread name', + `type` char(32) NOT NULL COMMENT 'type of work', + `vm_type` char(32) NOT NULL COMMENT 'type of vm', + `step` char(32) NOT NULL COMMENT 'state', + `updated_at` bigint unsigned NOT NULL COMMENT 'time it was taken over', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', + `resource_type` char(32) COMMENT 'type of resource being worked on', + `resource_id` bigint unsigned COMMENT 'resource id being worked on', + PRIMARY KEY (`id`), + CONSTRAINT `fk_op_it_work__mgmt_server_id` FOREIGN KEY (`mgmt_server_id`) REFERENCES `mshost`(`msid`), + CONSTRAINT `fk_op_it_work__instance_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, + INDEX `i_op_it_work__step`(`step`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_networks`( + `id` bigint unsigned NOT NULL UNIQUE KEY, + `mac_address_seq` bigint unsigned NOT NULL DEFAULT 1 COMMENT 'mac address', + `nics_count` int unsigned NOT NULL DEFAULT 0 COMMENT '# of nics', + `gc` tinyint unsigned NOT NULL DEFAULT 1 COMMENT 'gc this network or not', + `check_for_gc` tinyint unsigned NOT NULL DEFAULT 1 COMMENT 'check this network for gc or not', + PRIMARY KEY(`id`), + CONSTRAINT `fk_op_networks__id` FOREIGN KEY (`id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`networks` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) COMMENT 'name for this network', + `uuid` varchar(40), + `display_text` varchar(255) COMMENT 'display text for this network', + `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', + `broadcast_domain_type` varchar(32) NOT NULL COMMENT 'type of broadcast domain used', + `broadcast_uri` varchar(255) COMMENT 'broadcast domain specifier', + `gateway` varchar(15) COMMENT 'gateway for this network configuration', + `cidr` varchar(18) COMMENT 'network cidr', + `mode` varchar(32) COMMENT 'How to retrieve ip address in this network', + `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id that this configuration is created from', + `physical_network_id` bigint unsigned COMMENT 'physical network id that this configuration is based on', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this configuration is used in', + `guru_name` varchar(255) NOT NULL COMMENT 'who is responsible for this type of network configuration', + `state` varchar(32) NOT NULL COMMENT 'what state is this configuration in', + `related` bigint unsigned NOT NULL COMMENT 'related to what other network configuration', + `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', + `dns1` varchar(255) COMMENT 'comma separated DNS list', + `dns2` varchar(255) COMMENT 'comma separated DNS list', + `guru_data` varchar(1024) COMMENT 'data stored by the network guru that setup this network', + `set_fields` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'which fields are set already', + `acl_type` varchar(15) COMMENT 'ACL access type. Null for system networks, can be Account/Domain for Guest networks', + `network_domain` varchar(255) COMMENT 'domain', + `reservation_id` char(40) COMMENT 'reservation id', + `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', + `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the network', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network provides an ability to define ip ranges', + `vpc_id` bigint unsigned COMMENT 'vpc this network belongs to', + PRIMARY KEY (`id`), + CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), + CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + CONSTRAINT `fk_networks__vpc_id` FOREIGN KEY(`vpc_id`) REFERENCES `vpc`(`id`), + CONSTRAINT `uc_networks__uuid` UNIQUE (`uuid`), + INDEX `i_networks__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`account_network_ref` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `account_id` bigint unsigned NOT NULL COMMENT 'account id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `is_owner` smallint(1) NOT NULL COMMENT 'is the owner of the network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_account_network_ref__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_account_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`nics` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `instance_id` bigint unsigned COMMENT 'vm instance id', + `mac_address` varchar(17) COMMENT 'mac address', + `ip4_address` char(40) COMMENT 'ip4 address', + `netmask` varchar(15) COMMENT 'netmask for ip4 address', + `gateway` varchar(15) COMMENT 'gateway', + `ip_type` varchar(32) COMMENT 'type of ip', + `broadcast_uri` varchar(255) COMMENT 'broadcast uri', + `network_id` bigint unsigned NOT NULL COMMENT 'network configuration id', + `mode` varchar(32) COMMENT 'mode of getting ip address', + `state` varchar(32) NOT NULL COMMENT 'state of the creation', + `strategy` varchar(32) NOT NULL COMMENT 'reservation strategy', + `reserver_name` varchar(255) COMMENT 'Name of the component that reserved the ip address', + `reservation_id` varchar(64) COMMENT 'id for the reservation', + `device_id` int(10) COMMENT 'device id for the network when plugged into the virtual machine', + `update_time` timestamp NOT NULL COMMENT 'time the state was changed', + `isolation_uri` varchar(255) COMMENT 'id for isolation', + `ip6_address` char(40) COMMENT 'ip6 address', + `default_nic` tinyint NOT NULL COMMENT "None", + `vm_type` varchar(32) COMMENT 'type of vm: System or User vm', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_nics__instance_id` FOREIGN KEY `fk_nics__instance_id`(`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_nics__networks_id` FOREIGN KEY `fk_nics__networks_id`(`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `uc_nics__uuid` UNIQUE (`uuid`), + INDEX `i_nics__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_offerings` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `name` varchar(64) COMMENT 'name of the network offering', + `uuid` varchar(40), + `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the network offering', + `display_text` varchar(255) NOT NULL COMMENT 'text to display to users', + `nw_rate` smallint unsigned COMMENT 'network rate throttle mbits/s', + `mc_rate` smallint unsigned COMMENT 'mcast rate throttle mbits/s', + `traffic_type` varchar(32) NOT NULL COMMENT 'traffic type carried on this network', + `tags` varchar(4096) COMMENT 'tags supported by this offering', + `system_only` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network offering for system use only', + `specify_vlan` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Should the user specify vlan', + `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', + `conserve_mode` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is this network offering is IP conserve mode enabled', + `created` datetime NOT NULL COMMENT 'time the entry was created', + `removed` datetime DEFAULT NULL COMMENT 'time the entry was removed', + `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if network offering is default', + `availability` varchar(255) NOT NULL COMMENT 'availability of the network', + `dedicated_lb_service` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'true if the network offering provides a dedicated load balancer for each network', + `shared_source_nat_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides the shared source nat service', + `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', + `redundant_router_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides the redundant router service', + `state` char(32) COMMENT 'state of the network offering that has Disabled value by default', + `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', + `elastic_ip_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic ip service', + `elastic_lb_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic lb service', + `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides an ability to define ip ranges', + PRIMARY KEY (`id`), + INDEX `i_network_offerings__system_only`(`system_only`), + INDEX `i_network_offerings__removed`(`removed`), + CONSTRAINT `uc_network_offerings__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`cluster` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) COMMENT 'name for the cluster', + `uuid` varchar(40) COMMENT 'uuid is different with following guid, while the later one is generated by hypervisor resource', + `guid` varchar(255) UNIQUE DEFAULT NULL COMMENT 'guid for the cluster', + `pod_id` bigint unsigned NOT NULL COMMENT 'pod id', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id', + `hypervisor_type` varchar(32), + `cluster_type` varchar(64) DEFAULT 'CloudManaged', + `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this cluster enabled for allocation for new resources', + `managed_state` varchar(32) NOT NULL DEFAULT 'Managed' COMMENT 'Is this cluster managed by cloudstack', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_cluster__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_cluster__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`), + UNIQUE `i_cluster__pod_id__name`(`pod_id`, `name`), + INDEX `i_cluster__allocation_state`(`allocation_state`), + INDEX `i_cluster__removed`(`removed`), + CONSTRAINT `uc_cluster__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`cluster_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `cluster_id` bigint unsigned NOT NULL COMMENT 'cluster id', + `name` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_cluster_details__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cluster`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_host_upgrade` ( + `host_id` bigint unsigned NOT NULL UNIQUE COMMENT 'host id', + `version` varchar(20) NOT NULL COMMENT 'version', + `state` varchar(20) NOT NULL COMMENT 'state', + PRIMARY KEY (`host_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_lock` ( + `key` varchar(128) NOT NULL UNIQUE COMMENT 'primary key of the table', + `mac` varchar(17) NOT NULL COMMENT 'management server id of the server that holds this lock', + `ip` char(40) NOT NULL COMMENT 'name of the thread that holds this lock', + `thread` varchar(255) NOT NULL COMMENT 'Thread id that acquired this lock', + `acquired_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Time acquired', + `waiters` int NOT NULL DEFAULT 0 COMMENT 'How many have the thread acquired this lock (reentrant)', + PRIMARY KEY (`key`), + INDEX `i_op_lock__mac_ip_thread`(`mac`, `ip`, `thread`) +) ENGINE=Memory DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`configuration` ( + `category` varchar(255) NOT NULL DEFAULT 'Advanced', + `instance` varchar(255) NOT NULL, + `component` varchar(255) NOT NULL DEFAULT 'management-server', + `name` varchar(255) NOT NULL, + `value` varchar(4095), + `description` varchar(1024), + PRIMARY KEY (`name`), + INDEX `i_configuration__instance`(`instance`), + INDEX `i_configuration__name`(`name`), + INDEX `i_configuration__category`(`category`), + INDEX `i_configuration__component`(`component`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_ha_work` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs to be ha.', + `type` varchar(32) NOT NULL COMMENT 'type of work', + `vm_type` varchar(32) NOT NULL COMMENT 'VM type', + `state` varchar(32) NOT NULL COMMENT 'state of the vm instance when this happened.', + `mgmt_server_id` bigint unsigned COMMENT 'management server that has taken up the work of doing ha', + `host_id` bigint unsigned COMMENT 'host that the vm is suppose to be on', + `created` datetime NOT NULL COMMENT 'time the entry was requested', + `tried` int(10) unsigned COMMENT '# of times tried', + `taken` datetime COMMENT 'time it was taken by the management server', + `step` varchar(32) NOT NULL COMMENT 'Step in the work', + `time_to_try` bigint COMMENT 'time to try do this work', + `updated` bigint unsigned NOT NULL COMMENT 'time the VM state was updated when it was stored into work queue', + PRIMARY KEY (`id`), + CONSTRAINT `fk_op_ha_work__instance_id` FOREIGN KEY `fk_op_ha_work__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, + INDEX `i_op_ha_work__instance_id`(`instance_id`), + CONSTRAINT `fk_op_ha_work__host_id` FOREIGN KEY `fk_op_ha_work__host_id` (`host_id`) REFERENCES `host` (`id`), + INDEX `i_op_ha_work__host_id`(`host_id`), + INDEX `i_op_ha_work__step`(`step`), + INDEX `i_op_ha_work__type`(`type`), + CONSTRAINT `fk_op_ha_work__mgmt_server_id` FOREIGN KEY `fk_op_ha_work__mgmt_server_id`(`mgmt_server_id`) REFERENCES `mshost`(`msid`), + INDEX `i_op_ha_work__mgmt_server_id`(`mgmt_server_id`) + +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`sequence` ( + `name` varchar(64) UNIQUE NOT NULL COMMENT 'name of the sequence', + `value` bigint unsigned NOT NULL COMMENT 'sequence value', + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('vm_instance_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('vm_template_seq', 200); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('public_mac_address_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('private_mac_address_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('storage_pool_seq', 200); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('volume_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('networks_seq', 200); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('checkpoint_seq', 1); +INSERT INTO `cloud`.`sequence` (name, value) VALUES ('physical_networks_seq', 200); + +CREATE TABLE `cloud`.`volumes` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', + `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', + `domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to', + `pool_id` bigint unsigned COMMENT 'pool it belongs to. foreign key to storage_pool table', + `last_pool_id` bigint unsigned COMMENT 'last pool it belongs to.', + `instance_id` bigint unsigned NULL COMMENT 'vm instance it belongs to. foreign key to vm_instance table', + `device_id` bigint unsigned NULL COMMENT 'which device inside vm instance it is ', + `name` varchar(255) COMMENT 'A user specified name for the volume', + `uuid` varchar(40), + `size` bigint unsigned NOT NULL COMMENT 'total size', + `folder` varchar(255) COMMENT 'The folder where the volume is saved', + `path` varchar(255) COMMENT 'Path', + `pod_id` bigint unsigned COMMENT 'pod this volume belongs to', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center this volume belongs to', + `iscsi_name` varchar(255) COMMENT 'iscsi target name', + `host_ip` char(40) COMMENT 'host ip address for convenience', + `volume_type` varchar(64) NOT NULL COMMENT 'root, swap or data', + `pool_type` varchar(64) COMMENT 'type of the pool', + `disk_offering_id` bigint unsigned NOT NULL COMMENT 'can be null for system VMs', + `template_id` bigint unsigned COMMENT 'fk to vm_template.id', + `first_snapshot_backup_uuid` varchar (255) COMMENT 'The first snapshot that was ever taken for this volume', + `recreatable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this volume recreatable?', + `created` datetime COMMENT 'Date Created', + `attached` datetime COMMENT 'Date Attached', + `updated` datetime COMMENT 'Date updated for attach/detach', + `removed` datetime COMMENT 'Date removed. not null if removed', + `state` varchar(32) COMMENT 'State machine', + `chain_info` text COMMENT 'save possible disk chain info in primary storage', + `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated', + PRIMARY KEY (`id`), + INDEX `i_volumes__removed`(`removed`), + INDEX `i_volumes__pod_id`(`pod_id`), + INDEX `i_volumes__data_center_id`(`data_center_id`), + CONSTRAINT `fk_volumes__account_id` FOREIGN KEY `fk_volumes__account_id` (`account_id`) REFERENCES `account` (`id`), + INDEX `i_volumes__account_id`(`account_id`), + CONSTRAINT `fk_volumes__pool_id` FOREIGN KEY `fk_volumes__pool_id` (`pool_id`) REFERENCES `storage_pool` (`id`), + INDEX `i_volumes__pool_id`(`pool_id`), + INDEX `i_volumes__last_pool_id`(`last_pool_id`), + CONSTRAINT `fk_volumes__instance_id` FOREIGN KEY `fk_volumes__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, + INDEX `i_volumes__instance_id`(`instance_id`), + INDEX `i_volumes__state`(`state`), + INDEX `i_volumes__update_count`(`update_count`), + CONSTRAINT `uc_volumes__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`snapshots` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', + `data_center_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', + `domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to', + `volume_id` bigint unsigned NOT NULL COMMENT 'volume it belongs to. foreign key to volume table', + `disk_offering_id` bigint unsigned NOT NULL COMMENT 'from original volume', + `status` varchar(32) COMMENT 'snapshot creation status', + `path` varchar(255) COMMENT 'Path', + `name` varchar(255) NOT NULL COMMENT 'snapshot name', + `uuid` varchar(40), + `snapshot_type` int(4) NOT NULL COMMENT 'type of snapshot, e.g. manual, recurring', + `type_description` varchar(25) COMMENT 'description of the type of snapshot, e.g. manual, recurring', + `size` bigint unsigned NOT NULL COMMENT 'original disk size of snapshot', + `created` datetime COMMENT 'Date Created', + `removed` datetime COMMENT 'Date removed. not null if removed', + `backup_snap_id` varchar(255) COMMENT 'Back up uuid of the snapshot', + `swift_id` bigint unsigned COMMENT 'which swift', + `sechost_id` bigint unsigned COMMENT 'secondary storage host id', + `prev_snap_id` bigint unsigned COMMENT 'Id of the most recent snapshot', + `hypervisor_type` varchar(32) NOT NULL COMMENT 'hypervisor that the snapshot was taken under', + `version` varchar(32) COMMENT 'snapshot version', + PRIMARY KEY (`id`), + CONSTRAINT `uc_snapshots__uuid` UNIQUE (`uuid`), + INDEX `i_snapshots__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vlan` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `uuid` varchar(40), + `vlan_id` varchar(255), + `vlan_gateway` varchar(255), + `vlan_netmask` varchar(255), + `description` varchar(255), + `vlan_type` varchar(255), + `data_center_id` bigint unsigned NOT NULL, + `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', + PRIMARY KEY (`id`), + #CONSTRAINT `fk_vlan__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_vlan__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `uc_vlan__uuid` UNIQUE (`uuid`), + CONSTRAINT `fk_vlan__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`pod_vlan_map` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `pod_id` bigint unsigned NOT NULL COMMENT 'pod id. foreign key to pod table', + `vlan_db_id` bigint unsigned NOT NULL COMMENT 'database id of vlan. foreign key to vlan table', + PRIMARY KEY (`id`), + CONSTRAINT `fk_pod_vlan_map__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, + INDEX `i_pod_vlan_map__pod_id`(`pod_id`), + CONSTRAINT `fk_pod_vlan_map__vlan_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan` (`id`) ON DELETE CASCADE, + INDEX `i_pod_vlan_map__vlan_id`(`vlan_db_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`account_vlan_map` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `account_id` bigint unsigned NOT NULL COMMENT 'account id. foreign key to account table', + `vlan_db_id` bigint unsigned NOT NULL COMMENT 'database id of vlan. foreign key to vlan table', + PRIMARY KEY (`id`), + CONSTRAINT `fk_account_vlan_map__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, + INDEX `i_account_vlan_map__account_id`(`account_id`), + CONSTRAINT `fk_account_vlan_map__vlan_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan` (`id`) ON DELETE CASCADE, + INDEX `i_account_vlan_map__vlan_id`(`vlan_db_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`data_center` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `name` varchar(255), + `uuid` varchar(40), + `description` varchar(255), + `dns1` varchar(255) NOT NULL, + `dns2` varchar(255), + `internal_dns1` varchar(255) NOT NULL, + `internal_dns2` varchar(255), + `gateway` varchar(15), + `netmask` varchar(15), + `router_mac_address` varchar(17) NOT NULL DEFAULT '02:00:00:00:00:01' COMMENT 'mac address for the router within the domain', + `mac_address` bigint unsigned NOT NULL DEFAULT '1' COMMENT 'Next available mac address for the ethernet card interacting with public internet', + `guest_network_cidr` varchar(18), + `domain` varchar(100) COMMENT 'Network domain name of the Vms of the zone', + `domain_id` bigint unsigned COMMENT 'domain id for the parent domain to this zone (null signifies public zone)', + `networktype` varchar(255) NOT NULL DEFAULT 'Basic' COMMENT 'Network type of the zone', + `dns_provider` char(64) DEFAULT 'VirtualRouter', + `gateway_provider` char(64) DEFAULT 'VirtualRouter', + `firewall_provider` char(64) DEFAULT 'VirtualRouter', + `dhcp_provider` char(64) DEFAULT 'VirtualRouter', + `lb_provider` char(64) DEFAULT 'VirtualRouter', + `vpn_provider` char(64) DEFAULT 'VirtualRouter', + `userdata_provider` char(64) DEFAULT 'VirtualRouter', + `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this data center enabled for allocation for new resources', + `zone_token` varchar(255), + `is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_data_center__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`), + INDEX `i_data_center__domain_id`(`domain_id`), + INDEX `i_data_center__allocation_state`(`allocation_state`), + INDEX `i_data_center__zone_token`(`zone_token`), + INDEX `i_data_center__removed`(`removed`), + CONSTRAINT `uc_data_center__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_dc_ip_address_alloc` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center it belongs to', + `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', + `nic_id` bigint unsigned NULL COMMENT 'nic id', + `reservation_id` char(40) NULL COMMENT 'reservation id', + `taken` datetime COMMENT 'Date taken', + `mac_address` bigint unsigned NOT NULL COMMENT 'mac address for management ips', + PRIMARY KEY (`id`), + CONSTRAINT `fk_op_dc_ip_address_alloc__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + INDEX `i_op_dc_ip_address_alloc__pod_id__data_center_id__taken` (`pod_id`, `data_center_id`, `taken`, `nic_id`), + UNIQUE `i_op_dc_ip_address_alloc__ip_address__data_center_id`(`ip_address`, `data_center_id`), + CONSTRAINT `fk_op_dc_ip_address_alloc__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, + INDEX `i_op_dc_ip_address_alloc__pod_id`(`pod_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_dc_link_local_ip_address_alloc` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center it belongs to', + `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', + `nic_id` bigint unsigned NULL COMMENT 'instance id', + `reservation_id` char(40) NULL COMMENT 'reservation id used to reserve this network', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + INDEX `i_op_dc_link_local_ip_address_alloc__pod_id`(`pod_id`), + INDEX `i_op_dc_link_local_ip_address_alloc__data_center_id`(`data_center_id`), + INDEX `i_op_dc_link_local_ip_address_alloc__nic_id_reservation_id`(`nic_id`,`reservation_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`dc_storage_network_ip_range` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `uuid` varchar(40), + `start_ip` char(40) NOT NULL COMMENT 'start ip address', + `end_ip` char(40) NOT NULL COMMENT 'end ip address', + `gateway` varchar(15) NOT NULL COMMENT 'gateway ip address', + `vlan` int unsigned DEFAULT NULL COMMENT 'vlan the storage network on', + `netmask` varchar(15) NOT NULL COMMENT 'netmask for storage network', + `data_center_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', + `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', + PRIMARY KEY (`id`), + CONSTRAINT `fk_storage_ip_range__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_storage_ip_range__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `fk_storage_ip_range__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`), + CONSTRAINT `uc_storage_ip_range__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_dc_storage_network_ip_address` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `range_id` bigint unsigned NOT NULL COMMENT 'id of ip range in dc_storage_network_ip_range', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `mac_address` bigint unsigned NOT NULL COMMENT 'mac address for storage ips', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`host_pod_ref` ( + `id` bigint unsigned NOT NULL UNIQUE auto_increment, + `name` varchar(255), + `uuid` varchar(40), + `data_center_id` bigint unsigned NOT NULL, + `gateway` varchar(255) NOT NULL COMMENT 'gateway for the pod', + `cidr_address` varchar(15) NOT NULL COMMENT 'CIDR address for the pod', + `cidr_size` bigint unsigned NOT NULL COMMENT 'CIDR size for the pod', + `description` varchar(255) COMMENT 'store private ip range in startIP-endIP format', + `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this Pod enabled for allocation for new resources', + `external_dhcp` tinyint NOT NULL DEFAULT 0 COMMENT 'Is this Pod using external DHCP', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + UNIQUE KEY (`name`, `data_center_id`), + INDEX `i_host_pod_ref__data_center_id`(`data_center_id`), + INDEX `i_host_pod_ref__allocation_state`(`allocation_state`), + INDEX `i_host_pod_ref__removed`(`removed`), + CONSTRAINT `uc_host_pod_ref__uuid` UNIQUE (`uuid`) + +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_dc_vnet_alloc` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary id', + `vnet` varchar(18) NOT NULL COMMENT 'vnet', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network the vnet belongs to', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center the vnet belongs to', + `reservation_id` char(40) NULL COMMENT 'reservation id', + `account_id` bigint unsigned NULL COMMENT 'account the vnet belongs to right now', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + UNIQUE `i_op_dc_vnet_alloc__vnet__data_center_id__account_id`(`vnet`, `data_center_id`, `account_id`), + INDEX `i_op_dc_vnet_alloc__dc_taken`(`data_center_id`, `taken`), + UNIQUE `i_op_dc_vnet_alloc__vnet__data_center_id`(`vnet`, `data_center_id`), + CONSTRAINT `fk_op_dc_vnet_alloc__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_op_dc_vnet_alloc__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`firewall_rules` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `ip_address_id` bigint unsigned COMMENT 'id of the corresponding ip address', + `start_port` int(10) COMMENT 'starting port of a port range', + `end_port` int(10) COMMENT 'end port of a port range', + `state` char(32) NOT NULL COMMENT 'current state of this rule', + `protocol` char(16) NOT NULL default 'TCP' COMMENT 'protocol to open these ports for', + `purpose` char(32) NOT NULL COMMENT 'why are these ports opened?', + `account_id` bigint unsigned NOT NULL COMMENT 'owner id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `xid` char(40) NOT NULL COMMENT 'external id', + `created` datetime COMMENT 'Date created', + `icmp_code` int(10) COMMENT 'The ICMP code (if protocol=ICMP). A value of -1 means all codes for the given ICMP type.', + `icmp_type` int(10) COMMENT 'The ICMP type (if protocol=ICMP). A value of -1 means all types.', + `related` bigint unsigned COMMENT 'related to what other firewall rule', + `type` varchar(10) NOT NULL DEFAULT 'USER', + `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', + `traffic_type` char(32) COMMENT 'the traffic type of the rule, can be Ingress or Egress', + PRIMARY KEY (`id`), + CONSTRAINT `fk_firewall_rules__ip_address_id` FOREIGN KEY(`ip_address_id`) REFERENCES `user_ip_address`(`id`), + CONSTRAINT `fk_firewall_rules__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__related` FOREIGN KEY(`related`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, + INDEX `i_firewall_rules__purpose`(`purpose`), + CONSTRAINT `uc_firewall_rules__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`firewall_rules_cidrs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `firewall_rule_id` bigint(20) unsigned NOT NULL COMMENT 'firewall rule id', + `source_cidr` varchar(18) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_firewall_cidrs_firewall_rules` (`firewall_rule_id`), + UNIQUE INDEX `unique_rule_cidrs` (`firewall_rule_id`, `source_cidr`), + CONSTRAINT `fk_firewall_cidrs_firewall_rules` FOREIGN KEY (`firewall_rule_id`) REFERENCES `firewall_rules` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`load_balancing_rules` ( + `id` bigint unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `description` varchar(4096) NULL COMMENT 'description', + `default_port_start` int(10) NOT NULL COMMENT 'default private port range start', + `default_port_end` int(10) NOT NULL COMMENT 'default destination port range end', + `algorithm` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_load_balancing_rules__id` FOREIGN KEY(`id`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`load_balancer_vm_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `load_balancer_id` bigint unsigned NOT NULL, + `instance_id` bigint unsigned NOT NULL, + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', + PRIMARY KEY (`id`), + UNIQUE KEY (`load_balancer_id`, `instance_id`), + CONSTRAINT `fk_load_balancer_vm_map__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_load_balancer_vm_map__instance_id` FOREIGN KEY(`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`load_balancer_stickiness_policies` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `load_balancer_id` bigint unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `description` varchar(4096) NULL COMMENT 'description', + `method_name` varchar(255) NOT NULL, + `params` varchar(4096) NOT NULL, + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', + PRIMARY KEY (`id`), + CONSTRAINT `fk_load_balancer_stickiness_policies__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`inline_load_balancer_nic_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `load_balancer_id` bigint unsigned NOT NULL, + `public_ip_address` char(40) NOT NULL, + `nic_id` bigint unsigned NULL COMMENT 'nic id', + PRIMARY KEY (`id`), + UNIQUE KEY (`nic_id`), + CONSTRAINT `fk_inline_load_balancer_nic_map__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_inline_load_balancer_nic_map__nic_id` FOREIGN KEY(`nic_id`) REFERENCES `nics`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`port_forwarding_rules` ( + `id` bigint unsigned NOT NULL COMMENT 'id', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance id', + `dest_ip_address` char(40) NOT NULL COMMENT 'id_address', + `dest_port_start` int(10) NOT NULL COMMENT 'starting port of the port range to map to', + `dest_port_end` int(10) NOT NULL COMMENT 'end port of the the port range to map to', + PRIMARY KEY (`id`), + CONSTRAINT `fk_port_forwarding_rules__id` FOREIGN KEY(`id`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_port_forwarding_rules__instance_id` FOREIGN KEY `fk_port_forwarding_rules__instance_id` (`instance_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`host` ( + `id` bigint unsigned NOT NULL auto_increment, + `name` varchar(255) NOT NULL, + `uuid` varchar(40) COMMENT 'this uuid is different with guid below, the later one is used by hypervisor resource', + `status` varchar(32) NOT NULL, + `type` varchar(32) NOT NULL, + `private_ip_address` char(40) NOT NULL, + `private_netmask` varchar(15), + `private_mac_address` varchar(17), + `storage_ip_address` char(40), + `storage_netmask` varchar(15), + `storage_mac_address` varchar(17), + `storage_ip_address_2` char(40), + `storage_mac_address_2` varchar(17), + `storage_netmask_2` varchar(15), + `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', + `public_ip_address` char(40), + `public_netmask` varchar(15), + `public_mac_address` varchar(17), + `proxy_port` int(10) unsigned, + `data_center_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned, + `cpus` int(10) unsigned, + `speed` int(10) unsigned, + `url` varchar(255) COMMENT 'iqn for the servers', + `fs_type` varchar(32), + `hypervisor_type` varchar(32) COMMENT 'hypervisor type, can be NONE for storage', + `hypervisor_version` varchar(32) COMMENT 'hypervisor version', + `ram` bigint unsigned, + `resource` varchar(255) DEFAULT NULL COMMENT 'If it is a local resource, this is the class name', + `version` varchar(40) NOT NULL, + `parent` varchar(255) COMMENT 'parent path for the storage server', + `total_size` bigint unsigned COMMENT 'TotalSize', + `capabilities` varchar(255) COMMENT 'host capabilities in comma separated list', + `guid` varchar(255) UNIQUE, + `available` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is this host ready for more resources?', + `setup` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this host already setup?', + `dom0_memory` bigint unsigned NOT NULL COMMENT 'memory used by dom0 for computing and routing servers', + `last_ping` int(10) unsigned NOT NULL COMMENT 'time in seconds from the start of machine of the last ping', + `mgmt_server_id` bigint unsigned COMMENT 'ManagementServer this host is connected to.', + `disconnected` datetime COMMENT 'Time this was disconnected', + `created` datetime COMMENT 'date the host first signed on', + `removed` datetime COMMENT 'date removed if not null', + `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'atomic increase count making status update operation atomical', + `resource_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this host enabled for allocation for new resources', + PRIMARY KEY (`id`), + INDEX `i_host__removed`(`removed`), + INDEX `i_host__last_ping`(`last_ping`), + INDEX `i_host__status`(`status`), + INDEX `i_host__data_center_id`(`data_center_id`), + CONSTRAINT `fk_host__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, + INDEX `i_host__pod_id`(`pod_id`), + CONSTRAINT `fk_host__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cloud`.`cluster`(`id`), + CONSTRAINT `uc_host__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_host` ( + `id` bigint unsigned NOT NULL UNIQUE COMMENT 'host id', + `sequence` bigint unsigned DEFAULT 1 NOT NULL COMMENT 'sequence for the host communication', + PRIMARY KEY (`id`), + CONSTRAINT `fk_op_host__id` FOREIGN KEY (`id`) REFERENCES `host`(`id`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`account_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_id` bigint unsigned NOT NULL COMMENT 'account id', + `name` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_account_details__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE +)ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`host_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL COMMENT 'host id', + `name` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`mshost` ( + `id` bigint unsigned NOT NULL auto_increment, + `msid` bigint unsigned NOT NULL UNIQUE COMMENT 'management server id derived from MAC address', + `runid` bigint NOT NULL DEFAULT 0 COMMENT 'run id, combined with msid to form a cluster session', + `name` varchar(255), + `state` varchar(10) NOT NULL DEFAULT 'Down', + `version` varchar(255), + `service_ip` char(40) NOT NULL, + `service_port` integer NOT NULL, + `last_update` DATETIME NULL COMMENT 'Last record update time', + `removed` datetime COMMENT 'date removed if not null', + `alert_count` integer NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + INDEX `i_mshost__removed`(`removed`), + INDEX `i_mshost__last_update`(`last_update`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`mshost_peer` ( + `id` bigint unsigned NOT NULL auto_increment, + `owner_mshost` bigint unsigned NOT NULL, + `peer_mshost` bigint unsigned NOT NULL, + `peer_runid` bigint NOT NULL, + `peer_state` varchar(10) NOT NULL DEFAULT 'Down', + `last_update` DATETIME NULL COMMENT 'Last record update time', + + PRIMARY KEY (`id`), + CONSTRAINT `fk_mshost_peer__owner_mshost` FOREIGN KEY (`owner_mshost`) REFERENCES `mshost`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_mshost_peer__peer_mshost` FOREIGN KEY (`peer_mshost`) REFERENCES `mshost`(`id`), + UNIQUE `i_mshost_peer__owner_peer_runid`(`owner_mshost`, `peer_mshost`, `peer_runid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`host_tags` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL COMMENT 'host id', + `tag` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_host_tags__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`user` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `account_id` bigint unsigned NOT NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `state` varchar(10) NOT NULL default 'enabled', + `api_key` varchar(255) default NULL, + `secret_key` varchar(255) default NULL, + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed', + `timezone` varchar(30) default NULL, + `registration_token` varchar(255) default NULL, + `is_registered` tinyint NOT NULL DEFAULT 0 COMMENT '1: yes, 0: no', + PRIMARY KEY (`id`), + INDEX `i_user__removed`(`removed`), + INDEX `i_user__secret_key_removed`(`secret_key`, `removed`), + UNIQUE `i_user__api_key`(`api_key`), + CONSTRAINT `fk_user__account_id` FOREIGN KEY `fk_user__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, + INDEX `i_user__account_id`(`account_id`), + CONSTRAINT `uc_user__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`event` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `type` varchar(32) NOT NULL, + `state` varchar(32) NOT NULL DEFAULT 'Completed', + `description` varchar(1024) NOT NULL, + `user_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `created` datetime NOT NULL, + `level` varchar(16) NOT NULL, + `start_id` bigint unsigned NOT NULL DEFAULT 0, + `parameters` varchar(1024) NULL, + PRIMARY KEY (`id`), + CONSTRAINT `uc_event__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`user_ip_address` ( + `id` bigint unsigned NOT NULL UNIQUE auto_increment, + `uuid` varchar(40), + `account_id` bigint unsigned NULL, + `domain_id` bigint unsigned NULL, + `public_ip_address` char(40) NOT NULL, + `data_center_id` bigint unsigned NOT NULL COMMENT 'zone that it belongs to', + `source_nat` int(1) unsigned NOT NULL default '0', + `allocated` datetime NULL COMMENT 'Date this ip was allocated to someone', + `vlan_db_id` bigint unsigned NOT NULL, + `one_to_one_nat` int(1) unsigned NOT NULL default '0', + `vm_id` bigint unsigned COMMENT 'vm id the one_to_one nat ip is assigned to', + `state` char(32) NOT NULL default 'Free' COMMENT 'state of the ip address', + `mac_address` bigint unsigned NOT NULL COMMENT 'mac address of this ip', + `source_network_id` bigint unsigned NOT NULL COMMENT 'network id ip belongs to', + `network_id` bigint unsigned COMMENT 'network this public ip address is associated with', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', + `is_system` int(1) unsigned NOT NULL default '0', + `vpc_id` bigint unsigned COMMENT 'vpc the ip address is associated with', + PRIMARY KEY (`id`), + UNIQUE (`public_ip_address`, `source_network_id`), + CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_user_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_user_ip_address__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_user_ip_address__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance`(`id`), + CONSTRAINT `fk_user_ip_address__vlan_db_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user_ip_address__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_user_ip_address__uuid` UNIQUE (`uuid`), + CONSTRAINT `fk_user_ip_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user_ip_address__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, + INDEX `i_user_ip_address__allocated`(`allocated`), + INDEX `i_user_ip_address__source_nat`(`source_nat`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`user_statistics` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT, + `data_center_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `public_ip_address` char(40), + `device_id` bigint unsigned NOT NULL, + `device_type` varchar(32) NOT NULL, + `network_id` bigint unsigned, + `net_bytes_received` bigint unsigned NOT NULL default '0', + `net_bytes_sent` bigint unsigned NOT NULL default '0', + `current_bytes_received` bigint unsigned NOT NULL default '0', + `current_bytes_sent` bigint unsigned NOT NULL default '0', + `agg_bytes_received` bigint unsigned NOT NULL default '0', + `agg_bytes_sent` bigint unsigned NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY (`account_id`, `data_center_id`, `public_ip_address`, `device_id`, `device_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vm_template` ( + `id` bigint unsigned NOT NULL auto_increment, + `unique_name` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + `public` int(1) unsigned NOT NULL, + `featured` int(1) unsigned NOT NULL, + `type` varchar(32) NULL, + `hvm` int(1) unsigned NOT NULL COMMENT 'requires HVM', + `bits` int(6) unsigned NOT NULL COMMENT '32 bit or 64 bit', + `url` varchar(255) NULL COMMENT 'the url where the template exists externally', + `format` varchar(32) NOT NULL COMMENT 'format for the template', + `created` datetime NOT NULL COMMENT 'Date created', + `removed` datetime COMMENT 'Date removed if not null', + `account_id` bigint unsigned NOT NULL COMMENT 'id of the account that created this template', + `checksum` varchar(255) COMMENT 'checksum for the template root disk', + `display_text` varchar(4096) NULL COMMENT 'Description text set by the admin for display purpose only', + `enable_password` int(1) unsigned NOT NULL default 1 COMMENT 'true if this template supports password reset', + `enable_sshkey` int(1) unsigned NOT NULL default 0 COMMENT 'true if this template supports sshkey reset', + `guest_os_id` bigint unsigned NOT NULL COMMENT 'the OS of the template', + `bootable` int(1) unsigned NOT NULL default 1 COMMENT 'true if this template represents a bootable ISO', + `prepopulate` int(1) unsigned NOT NULL default 0 COMMENT 'prepopulate this template to primary storage', + `cross_zones` int(1) unsigned NOT NULL default 0 COMMENT 'Make this template available in all zones', + `extractable` int(1) unsigned NOT NULL default 0 COMMENT 'Is this template extractable', + `hypervisor_type` varchar(32) COMMENT 'hypervisor that the template belongs to', + `source_template_id` bigint unsigned COMMENT 'Id of the original template, if this template is created from snapshot', + `template_tag` varchar(255) COMMENT 'template tag', + `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', + PRIMARY KEY (`id`), + INDEX `i_vm_template__removed`(`removed`), + CONSTRAINT `uc_vm_template__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vm_template_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `template_id` bigint unsigned NOT NULL COMMENT 'template id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_vm_template_details__template_id` FOREIGN KEY `fk_vm_template_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vm_instance` ( + `id` bigint unsigned UNIQUE NOT NULL, + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + `instance_name` varchar(255) NOT NULL COMMENT 'name of the vm instance running on the hosts', + `state` varchar(32) NOT NULL, + `vm_template_id` bigint unsigned, + `guest_os_id` bigint unsigned NOT NULL, + `private_mac_address` varchar(17), + `private_ip_address` char(40), + `pod_id` bigint unsigned, + `data_center_id` bigint unsigned NOT NULL COMMENT 'Data Center the instance belongs to', + `host_id` bigint unsigned, + `last_host_id` bigint unsigned COMMENT 'tentative host for first run or last host that it has been running on', + `proxy_id` bigint unsigned NULL COMMENT 'console proxy allocated in previous session', + `proxy_assign_time` DATETIME NULL COMMENT 'time when console proxy was assigned', + `vnc_password` varchar(255) NOT NULL COMMENT 'vnc password', + `ha_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Should HA be enabled for this VM', + `limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the cpu usage to service offering', + `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated', + `update_time` datetime COMMENT 'date the destroy was requested', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + `type` varchar(32) NOT NULL COMMENT 'type of vm it is', + `vm_type` varchar(32) NOT NULL COMMENT 'vm type', + `account_id` bigint unsigned NOT NULL COMMENT 'user id of owner', + `domain_id` bigint unsigned NOT NULL, + `service_offering_id` bigint unsigned NOT NULL COMMENT 'service offering id', + `reservation_id` char(40) COMMENT 'reservation id', + `hypervisor_type` char(32) COMMENT 'hypervisor type', + PRIMARY KEY (`id`), + INDEX `i_vm_instance__removed`(`removed`), + INDEX `i_vm_instance__type`(`type`), + INDEX `i_vm_instance__pod_id`(`pod_id`), + INDEX `i_vm_instance__update_time`(`update_time`), + INDEX `i_vm_instance__update_count`(`update_count`), + INDEX `i_vm_instance__state`(`state`), + INDEX `i_vm_instance__data_center_id`(`data_center_id`), + CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY `fk_vm_instance__host_id` (`host_id`) REFERENCES `host` (`id`), + CONSTRAINT `fk_vm_instance__last_host_id` FOREIGN KEY `fk_vm_instance__last_host_id` (`last_host_id`) REFERENCES `host`(`id`), + CONSTRAINT `fk_vm_instance__template_id` FOREIGN KEY `fk_vm_instance__template_id` (`vm_template_id`) REFERENCES `vm_template` (`id`), + INDEX `i_vm_instance__template_id`(`vm_template_id`), + CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY `fk_vm_instance__account_id` (`account_id`) REFERENCES `account` (`id`), + CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY `fk_vm_instance__service_offering_id` (`service_offering_id`) REFERENCES `service_offering` (`id`), + CONSTRAINT `uc_vm_instance_uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`user_vm` ( + `id` bigint unsigned UNIQUE NOT NULL, + `iso_id` bigint unsigned, + `display_name` varchar(255), + `user_data` varchar(2048), + `update_parameters` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Defines if the parameters have been updated for the vm', + PRIMARY KEY (`id`), + CONSTRAINT `fk_user_vm__id` FOREIGN KEY `fk_user_vm__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- note, uer_vm_details is now used for all VMs (not just for user vms) +CREATE TABLE `cloud`.`user_vm_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `vm_id` bigint unsigned NOT NULL COMMENT 'vm id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_user_vm_details__vm_id` FOREIGN KEY `fk_user_vm_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`domain_router` ( + `id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key', + `element_id` bigint unsigned NOT NULL COMMENT 'correlated virtual router provider ID', + `public_mac_address` varchar(17) COMMENT 'mac address of the public facing network card', + `public_ip_address` char(40) COMMENT 'public ip address used for source net', + `public_netmask` varchar(15) COMMENT 'netmask used for the domR', + `guest_netmask` varchar(15) COMMENT 'netmask used for the guest network', + `guest_ip_address` char(40) COMMENT ' ip address in the guest network', + `is_redundant_router` int(1) unsigned NOT NULL COMMENT 'if in redundant router mode', + `priority` int(4) unsigned COMMENT 'priority of router in the redundant router mode', + `is_priority_bumpup` int(1) unsigned NOT NULL COMMENT 'if the priority has been bumped up', + `redundant_state` varchar(64) NOT NULL COMMENT 'the state of redundant virtual router', + `stop_pending` int(1) unsigned NOT NULL COMMENT 'if this router would be stopped after we can connect to it', + `role` varchar(64) NOT NULL COMMENT 'type of role played by this router', + `template_version` varchar(100) COMMENT 'template version', + `scripts_version` varchar(100) COMMENT 'scripts version', + `vpc_id` bigint unsigned COMMENT 'correlated virtual router vpc ID', + PRIMARY KEY (`id`), + CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`), + CONSTRAINT `fk_domain_router__vpc_id` FOREIGN KEY `fk_domain_router__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance'; + +CREATE TABLE `cloud`.`upload` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL, + `type_id` bigint unsigned NOT NULL, + `type` varchar(255), + `mode` varchar(255), + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `upload_pct` int(10) unsigned, + `upload_state` varchar(255), + `error_str` varchar(255), + `url` varchar(255), + `install_path` varchar(255), + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`template_host_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL, + `template_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + `download_state` varchar(255), + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `url` varchar(255), + `destroyed` tinyint(1) COMMENT 'indicates whether the template_host entry was destroyed by the user or not', + `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', + PRIMARY KEY (`id`), + CONSTRAINT `fk_template_host_ref__host_id` FOREIGN KEY `fk_template_host_ref__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, + INDEX `i_template_host_ref__host_id`(`host_id`), + CONSTRAINT `fk_template_host_ref__template_id` FOREIGN KEY `fk_template_host_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), + INDEX `i_template_host_ref__template_id`(`template_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`volume_host_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL, + `volume_id` bigint unsigned NOT NULL, + `zone_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + `download_state` varchar(255), + `checksum` varchar(255) COMMENT 'checksum for the data disk', + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `url` varchar(255), + `format` varchar(32) NOT NULL COMMENT 'format for the volume', + `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', + PRIMARY KEY (`id`), + CONSTRAINT `fk_volume_host_ref__host_id` FOREIGN KEY `fk_volume_host_ref__host_id` (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, + INDEX `i_volume_host_ref__host_id`(`host_id`), + CONSTRAINT `fk_volume_host_ref__volume_id` FOREIGN KEY `fk_volume_host_ref__volume_id` (`volume_id`) REFERENCES `volumes` (`id`), + INDEX `i_volume_host_ref__volume_id`(`volume_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`template_swift_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `swift_id` bigint unsigned NOT NULL, + `template_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `path` varchar(255), + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + PRIMARY KEY (`id`), + CONSTRAINT `fk_template_swift_ref__swift_id` FOREIGN KEY `fk_template_swift_ref__swift_id` (`swift_id`) REFERENCES `swift` (`id`) ON DELETE CASCADE, + INDEX `i_template_swift_ref__swift_id`(`swift_id`), + CONSTRAINT `fk_template_swift_ref__template_id` FOREIGN KEY `fk_template_swift_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), + INDEX `i_template_swift_ref__template_id`(`template_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`template_zone_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `zone_id` bigint unsigned NOT NULL, + `template_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_template_zone_ref__zone_id` FOREIGN KEY `fk_template_zone_ref__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, + INDEX `i_template_zone_ref__zone_id`(`zone_id`), + CONSTRAINT `fk_template_zone_ref__template_id` FOREIGN KEY `fk_template_zone_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`) ON DELETE CASCADE, + INDEX `i_template_zone_ref__template_id`(`template_id`), + INDEX `i_template_zone_ref__removed`(`removed`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`console_proxy` ( + `id` bigint unsigned NOT NULL auto_increment, + `public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card', + `public_ip_address` char(40) COMMENT 'public ip address for the console proxy', + `public_netmask` varchar(15) COMMENT 'public netmask used for the console proxy', + `active_session` int(10) NOT NULL DEFAULT 0 COMMENT 'active session number', + `last_update` DATETIME NULL COMMENT 'Last session update time', + `session_details` BLOB NULL COMMENT 'session detail info', + PRIMARY KEY (`id`), + CONSTRAINT `fk_console_proxy__id` FOREIGN KEY `fk_console_proxy__id`(`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`secondary_storage_vm` ( + `id` bigint unsigned NOT NULL auto_increment, + `public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card', + `public_ip_address` char(40) COMMENT 'public ip address for the sec storage vm', + `public_netmask` varchar(15) COMMENT 'public netmask used for the sec storage vm', + `guid` varchar(255) COMMENT 'copied from guid of secondary storage host', + `nfs_share` varchar(255) COMMENT 'server and path exported by the nfs server ', + `last_update` DATETIME NULL COMMENT 'Last session update time', + `role` varchar(64) NOT NULL DEFAULT 'templateProcessor' COMMENT 'work role of secondary storage host(templateProcessor | commandExecutor)', + PRIMARY KEY (`id`), + CONSTRAINT `fk_secondary_storage_vm__id` FOREIGN KEY `fk_secondary_storage_vm__id`(`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`domain` ( + `id` bigint unsigned NOT NULL auto_increment, + `parent` bigint unsigned, + `name` varchar(255), + `uuid` varchar(40), + `owner` bigint unsigned NOT NULL, + `path` varchar(255) NOT NULL, + `level` int(10) NOT NULL DEFAULT 0, + `child_count` int(10) NOT NULL DEFAULT 0, + `next_child_seq` bigint unsigned NOT NULL DEFAULT 1, + `removed` datetime COMMENT 'date removed', + `state` char(32) NOT NULL default 'Active' COMMENT 'state of the domain', + `network_domain` varchar(255), + `type` varchar(255) NOT NULL DEFAULT 'Normal' COMMENT 'type of the domain - can be Normal or Project', + PRIMARY KEY (`id`), + UNIQUE (parent, name, removed), + INDEX `i_domain__path`(`path`), + INDEX `i_domain__removed`(`removed`), + CONSTRAINT `uc_domain__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`account` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_name` varchar(100) COMMENT 'an account name set by the creator of the account, defaults to username for single accounts', + `uuid` varchar(40), + `type` int(1) unsigned NOT NULL, + `domain_id` bigint unsigned, + `state` varchar(10) NOT NULL default 'enabled', + `removed` datetime COMMENT 'date removed', + `cleanup_needed` tinyint(1) NOT NULL default '0', + `network_domain` varchar(255), + `default_zone_id` bigint unsigned, + PRIMARY KEY (`id`), + INDEX i_account__removed(`removed`), + CONSTRAINT `fk_account__default_zone_id` FOREIGN KEY `fk_account__default_zone_id`(`default_zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_account__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`resource_limit` ( + `id` bigint unsigned NOT NULL auto_increment, + `domain_id` bigint unsigned, + `account_id` bigint unsigned, + `type` varchar(255), + `max` bigint NOT NULL default '-1', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`resource_count` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_id` bigint unsigned, + `domain_id` bigint unsigned, + `type` varchar(255), + `count` bigint NOT NULL default '0', + PRIMARY KEY (`id`), + CONSTRAINT `fk_resource_count__account_id` FOREIGN KEY `fk_resource_count__account_id`(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_resource_count__domain_id` FOREIGN KEY `fk_resource_count__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + INDEX `i_resource_count__type`(`type`), + UNIQUE `i_resource_count__type_accountId`(`type`, `account_id`), + UNIQUE `i_resource_count__type_domaintId`(`type`, `domain_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_host_capacity` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned, + `data_center_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned, + `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', + `used_capacity` bigint signed NOT NULL, + `reserved_capacity` bigint signed NOT NULL, + `total_capacity` bigint signed NOT NULL, + `capacity_type` int(1) unsigned NOT NULL, + `capacity_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this capacity enabled for allocation for new resources', + `update_time` datetime COMMENT 'time the capacity was last updated', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + INDEX `i_op_host_capacity__host_type`(`host_id`, `capacity_type`), + INDEX `i_op_host_capacity__pod_id`(`pod_id`), + INDEX `i_op_host_capacity__data_center_id`(`data_center_id`), + INDEX `i_op_host_capacity__cluster_id`(`cluster_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`alert` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `type` int(1) unsigned NOT NULL, + `cluster_id` bigint unsigned, + `pod_id` bigint unsigned, + `data_center_id` bigint unsigned NOT NULL, + `subject` varchar(999) COMMENT 'according to SMTP spec, max subject length is 1000 including the CRLF character, so allow enough space to fit long pod/zone/host names', + `sent_count` int(3) unsigned NOT NULL, + `created` DATETIME NULL COMMENT 'when this alert type was created', + `last_sent` DATETIME NULL COMMENT 'Last time the alert was sent', + `resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)', + PRIMARY KEY (`id`), + CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`async_job` ( + `id` bigint unsigned NOT NULL auto_increment, + `user_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `session_key` varchar(64) COMMENT 'all async-job manage to apply session based security enforcement', + `instance_type` varchar(64) COMMENT 'instance_type and instance_id work together to allow attaching an instance object to a job', + `instance_id` bigint unsigned, + `job_cmd` varchar(64) NOT NULL COMMENT 'command name', + `job_cmd_originator` varchar(64) COMMENT 'command originator', + `job_cmd_info` text COMMENT 'command parameter info', + `job_cmd_ver` int(1) COMMENT 'command version', + `callback_type` int(1) COMMENT 'call back type, 0 : polling, 1 : email', + `callback_address` varchar(128) COMMENT 'call back address by callback_type', + `job_status` int(1) COMMENT 'general job execution status', + `job_process_status` int(1) COMMENT 'job specific process status for asynchronize progress update', + `job_result_code` int(1) COMMENT 'job result code, specify error code corresponding to result message', + `job_result` text COMMENT 'job result info', + `job_init_msid` bigint COMMENT 'the initiating msid', + `job_complete_msid` bigint COMMENT 'completing msid', + `created` datetime COMMENT 'date created', + `last_updated` datetime COMMENT 'date created', + `last_polled` datetime COMMENT 'date polled', + `removed` datetime COMMENT 'date removed', + `uuid` varchar(40), + PRIMARY KEY (`id`), + INDEX `i_async_job__removed`(`removed`), + INDEX `i_async__user_id`(`user_id`), + INDEX `i_async__account_id`(`account_id`), + INDEX `i_async__instance_type_id`(`instance_type`,`instance_id`), + INDEX `i_async__job_cmd`(`job_cmd`), + INDEX `i_async__created`(`created`), + INDEX `i_async__last_updated`(`last_updated`), + INDEX `i_async__last_poll`(`last_polled`), + CONSTRAINT `uc_async__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`sync_queue` ( + `id` bigint unsigned NOT NULL auto_increment, + `sync_objtype` varchar(64) NOT NULL, + `sync_objid` bigint unsigned NOT NULL, + `queue_proc_msid` bigint, + `queue_proc_number` bigint COMMENT 'process number, increase 1 for each iteration', + `queue_proc_time` datetime COMMENT 'last time to process the queue', + `created` datetime COMMENT 'date created', + `last_updated` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + UNIQUE `i_sync_queue__objtype__objid`(`sync_objtype`, `sync_objid`), + INDEX `i_sync_queue__created`(`created`), + INDEX `i_sync_queue__last_updated`(`last_updated`), + INDEX `i_sync_queue__queue_proc_time`(`queue_proc_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`stack_maid` ( + `id` bigint unsigned NOT NULL auto_increment, + `msid` bigint unsigned NOT NULL, + `thread_id` bigint unsigned NOT NULL, + `seq` int unsigned NOT NULL, + `cleanup_delegate` varchar(128), + `cleanup_context` text, + `created` datetime, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`sync_queue_item` ( + `id` bigint unsigned NOT NULL auto_increment, + `queue_id` bigint unsigned NOT NULL, + `content_type` varchar(64), + `content_id` bigint, + `queue_proc_msid` bigint COMMENT 'owner msid when the queue item is being processed', + `queue_proc_number` bigint COMMENT 'used to distinguish raw items and items being in process', + `created` datetime COMMENT 'time created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_sync_queue_item__queue_id` FOREIGN KEY `fk_sync_queue_item__queue_id` (`queue_id`) REFERENCES `sync_queue` (`id`) ON DELETE CASCADE, + INDEX `i_sync_queue_item__queue_id`(`queue_id`), + INDEX `i_sync_queue_item__created`(`created`), + INDEX `i_sync_queue_item__queue_proc_number`(`queue_proc_number`), + INDEX `i_sync_queue_item__queue_proc_msid`(`queue_proc_msid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`disk_offering` ( + `id` bigint unsigned NOT NULL auto_increment, + `domain_id` bigint unsigned, + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + `display_text` varchar(4096) NULL COMMENT 'Descrianaption text set by the admin for display purpose only', + `disk_size` bigint unsigned NOT NULL COMMENT 'disk space in byte', + `type` varchar(32) COMMENT 'inheritted by who?', + `tags` varchar(4096) COMMENT 'comma separated tags about the disk_offering', + `recreatable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'The root disk is always recreatable', + `use_local_storage` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Indicates whether local storage pools should be used', + `unique_name` varchar(32) UNIQUE COMMENT 'unique name', + `system_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'is this offering for system used only', + `customized` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0 implies not customized by default', + `removed` datetime COMMENT 'date removed', + `created` datetime COMMENT 'date the disk offering was created', + `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', + PRIMARY KEY (`id`), + INDEX `i_disk_offering__removed`(`removed`), + CONSTRAINT `uc_disk_offering__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`service_offering` ( + `id` bigint unsigned NOT NULL, + `cpu` int(10) unsigned NOT NULL COMMENT '# of cores', + `speed` int(10) unsigned NOT NULL COMMENT 'speed per core in mhz', + `ram_size` bigint unsigned NOT NULL, + `nw_rate` smallint unsigned default 200 COMMENT 'network rate throttle mbits/s', + `mc_rate` smallint unsigned default 10 COMMENT 'mcast rate throttle mbits/s', + `ha_enabled` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Enable HA', + `limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the CPU usage to service offering', + `host_tag` varchar(255) COMMENT 'host tag specified by the service_offering', + `default_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'is this offering a default system offering', + `vm_type` varchar(32) COMMENT 'type of offering specified for system offerings', + `sort_key` int(32) NOT NULL default 0 COMMENT 'sort key used for customising sort method', + PRIMARY KEY (`id`), + CONSTRAINT `fk_service_offering__id` FOREIGN KEY `fk_service_offering__id`(`id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_rule_config` ( + `id` bigint unsigned NOT NULL auto_increment, + `security_group_id` bigint unsigned NOT NULL, + `public_port` varchar(10) default NULL, + `private_port` varchar(10) default NULL, + `protocol` varchar(16) NOT NULL default 'TCP', + `create_status` varchar(32) COMMENT 'rule creation status', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`remote_access_vpn` ( + `vpn_server_addr_id` bigint unsigned UNIQUE NOT NULL, + `account_id` bigint unsigned NOT NULL, + `network_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `local_ip` char(40) NOT NULL, + `ip_range` varchar(32) NOT NULL, + `ipsec_psk` varchar(256) NOT NULL, + `state` char(32) NOT NULL, + PRIMARY KEY (`vpn_server_addr_id`), + CONSTRAINT `fk_remote_access_vpn__account_id` FOREIGN KEY `fk_remote_access_vpn__account_id`(`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_remote_access_vpn__domain_id` FOREIGN KEY `fk_remote_access_vpn__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_remote_access_vpn__network_id` FOREIGN KEY `fk_remote_access_vpn__network_id` (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_remote_access_vpn__vpn_server_addr_id` FOREIGN KEY `fk_remote_access_vpn__vpn_server_addr_id` (`vpn_server_addr_id`) REFERENCES `user_ip_address` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpn_users` ( + `id` bigint unsigned NOT NULL UNIQUE auto_increment, + `uuid` varchar(40), + `owner_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `state` char(32) NOT NULL COMMENT 'What state is this vpn user in', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpn_users__owner_id` FOREIGN KEY (`owner_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpn_users__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + INDEX `i_vpn_users_username`(`username`), + UNIQUE `i_vpn_users__account_id__username`(`owner_id`, `username`), + CONSTRAINT `uc_vpn_users__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`storage_pool` ( + `id` bigint unsigned UNIQUE NOT NULL, + `name` varchar(255) COMMENT 'should be NOT NULL', + `uuid` varchar(255) UNIQUE, + `pool_type` varchar(32) NOT NULL, + `port` int unsigned NOT NULL, + `data_center_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned, + `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', + `available_bytes` bigint unsigned, + `capacity_bytes` bigint unsigned, + `host_address` varchar(255) NOT NULL COMMENT 'FQDN or IP of storage server', + `path` varchar(255) NOT NULL COMMENT 'Filesystem path that is shared', + `created` datetime COMMENT 'date the pool created', + `removed` datetime COMMENT 'date removed if not null', + `update_time` DATETIME, + `status` varchar(32), + PRIMARY KEY (`id`), + CONSTRAINT `fk_storage_pool__pod_id` FOREIGN KEY `fk_storage_pool__pod_id` (`pod_id`) REFERENCES `host_pod_ref` (`id`) ON DELETE CASCADE, + INDEX `i_storage_pool__pod_id`(`pod_id`), + CONSTRAINT `fk_storage_pool__cluster_id` FOREIGN KEY `fk_storage_pool__cluster_id`(`cluster_id`) REFERENCES `cloud`.`cluster`(`id`), + INDEX `i_storage_pool__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`storage_pool_details` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `pool_id` bigint unsigned NOT NULL COMMENT 'pool the detail is related to', + `name` varchar(255) NOT NULL COMMENT 'name of the detail', + `value` varchar(255) NOT NULL COMMENT 'value of the detail', + PRIMARY KEY (`id`), + CONSTRAINT `fk_storage_pool_details__pool_id` FOREIGN KEY `fk_storage_pool_details__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE, + INDEX `i_storage_pool_details__name__value`(`name`(128), `value`(128)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`storage_pool_host_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `host_id` bigint unsigned NOT NULL, + `pool_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `local_path` varchar(255), + PRIMARY KEY (`id`), + CONSTRAINT `fk_storage_pool_host_ref__host_id` FOREIGN KEY `fk_storage_pool_host_ref__host_id`(`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_storage_pool_host_ref__pool_id` FOREIGN KEY `fk_storage_pool_host_ref__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`template_spool_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `pool_id` bigint unsigned NOT NULL, + `template_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `download_state` varchar(255), + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `template_size` bigint unsigned NOT NULL COMMENT 'the size of the template on the pool', + `marked_for_gc` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'if true, the garbage collector will evict the template from this pool.', + PRIMARY KEY (`id`), + UNIQUE `i_template_spool_ref__template_id__pool_id`(`template_id`, `pool_id`), + CONSTRAINT `fk_template_spool_ref__template_id` FOREIGN KEY (`template_id`) REFERENCES `vm_template`(`id`), + CONSTRAINT `fk_template_spool_ref__pool_id` FOREIGN KEY (`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`guest_os` ( + `id` bigint unsigned NOT NULL auto_increment, + `category_id` bigint unsigned NOT NULL, + `name` varchar(255), + `uuid` varchar(40), + `display_name` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `uc_guest_os__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`guest_os_hypervisor` ( + `id` bigint unsigned NOT NULL auto_increment, + `hypervisor_type` varchar(32) NOT NULL, + `guest_os_name` varchar(255) NOT NULL, + `guest_os_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`guest_os_category` ( + `id` bigint unsigned NOT NULL auto_increment, + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + PRIMARY KEY (`id`), + CONSTRAINT `uc_guest_os_category__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`hypervisor_capabilities` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `hypervisor_type` varchar(32) NOT NULL, + `hypervisor_version` varchar(32), + `max_guests_limit` bigint unsigned DEFAULT 50, + `security_group_enabled` int(1) unsigned DEFAULT 1 COMMENT 'Is security group supported', + PRIMARY KEY (`id`), + CONSTRAINT `uc_hypervisor_capabilities__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', 'default', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', 'XCP 1.0', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6 FP1', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '5.6 SP2', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '6.0', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('XenServer', '6.0.2', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', 'default', 128, 0); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.0', 128, 0); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '4.1', 128, 0); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('VMware', '5.0', 128, 0); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('KVM', 'default', 50, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', 'default', 25, 1); +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm', '2.3', 25, 1); + +CREATE TABLE `cloud`.`launch_permission` ( + `id` bigint unsigned NOT NULL auto_increment, + `template_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`snapshot_policy` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `volume_id` bigint unsigned NOT NULL, + `schedule` varchar(100) NOT NULL COMMENT 'schedule time of execution', + `timezone` varchar(100) NOT NULL COMMENT 'the timezone in which the schedule time is specified', + `interval` int(4) NOT NULL default 4 COMMENT 'backup schedule, e.g. hourly, daily, etc.', + `max_snaps` int(8) NOT NULL default 0 COMMENT 'maximum number of snapshots to maintain', + `active` tinyint(1) unsigned NOT NULL COMMENT 'Is the policy active', + PRIMARY KEY (`id`), + CONSTRAINT `uc_snapshot_policy__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`snapshot_schedule` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `volume_id` bigint unsigned NOT NULL COMMENT 'The volume for which this snapshot is being taken', + `policy_id` bigint unsigned NOT NULL COMMENT 'One of the policyIds for which this snapshot was taken', + `scheduled_timestamp` datetime NOT NULL COMMENT 'Time at which the snapshot was scheduled for execution', + `async_job_id` bigint unsigned COMMENT 'If this schedule is being executed, it is the id of the create aysnc_job. Before that it is null', + `snapshot_id` bigint unsigned COMMENT 'If this schedule is being executed, then the corresponding snapshot has this id. Before that it is null', + UNIQUE (volume_id, policy_id), + CONSTRAINT `uc_snapshot_schedule__uuid` UNIQUE (`uuid`), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_pod_vlan_alloc` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary id', + `vlan` varchar(18) NOT NULL COMMENT 'vlan id', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center the pod belongs to', + `pod_id` bigint unsigned NOT NULL COMMENT 'pod the vlan belongs to', + `account_id` bigint unsigned NULL COMMENT 'account the vlan belongs to right now', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`security_group` ( + `id` bigint unsigned NOT NULL auto_increment, + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + `description` varchar(4096) NULL, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + UNIQUE (`name`, `account_id`), + PRIMARY KEY (`id`), + CONSTRAINT `uc_security_group__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`security_group_rule` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `security_group_id` bigint unsigned NOT NULL, + `type` varchar(10) default 'ingress', + `start_port` varchar(10) default NULL, + `end_port` varchar(10) default NULL, + `protocol` varchar(16) NOT NULL default 'TCP', + `allowed_network_id` bigint unsigned, + `allowed_ip_cidr` varchar(44), + `create_status` varchar(32) COMMENT 'rule creation status', + PRIMARY KEY (`id`), + CONSTRAINT `uc_security_group_rule__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`security_group_vm_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `security_group_id` bigint unsigned NOT NULL, + `instance_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_nwgrp_work` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs rules to be synced.', + `mgmt_server_id` bigint unsigned COMMENT 'management server that has taken up the work of doing rule sync', + `created` datetime NOT NULL COMMENT 'time the entry was requested', + `taken` datetime COMMENT 'time it was taken by the management server', + `step` varchar(32) NOT NULL COMMENT 'Step in the work', + `seq_no` bigint unsigned COMMENT 'seq number to be sent to agent, uniquely identifies ruleset update', + PRIMARY KEY (`id`), + INDEX `i_op_nwgrp_work__instance_id`(`instance_id`), + INDEX `i_op_nwgrp_work__mgmt_server_id`(`mgmt_server_id`), + INDEX `i_op_nwgrp_work__taken`(`taken`), + INDEX `i_op_nwgrp_work__step`(`step`), + INDEX `i_op_nwgrp_work__seq_no`(`seq_no`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_vm_ruleset_log` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance that needs rules to be synced.', + `created` datetime NOT NULL COMMENT 'time the entry was requested', + `logsequence` bigint unsigned COMMENT 'seq number to be sent to agent, uniquely identifies ruleset update', + PRIMARY KEY (`id`), + UNIQUE `u_op_vm_ruleset_log__instance_id`(`instance_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`instance_group` ( + `id` bigint unsigned NOT NULL UNIQUE auto_increment, + `account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table', + `name` varchar(255) NOT NULL, + `uuid` varchar(40), + `removed` datetime COMMENT 'date the group was removed', + `created` datetime COMMENT 'date the group was created', + PRIMARY KEY (`id`), + INDEX `i_instance_group__removed`(`removed`), + CONSTRAINT `uc_instance_group__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`instance_group_vm_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `group_id` bigint unsigned NOT NULL, + `instance_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`ssh_keypairs` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `account_id` bigint unsigned NOT NULL COMMENT 'owner, foreign key to account table', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain, foreign key to domain table', + `keypair_name` varchar(256) NOT NULL COMMENT 'name of the key pair', + `fingerprint` varchar(128) NOT NULL COMMENT 'fingerprint for the ssh public key', + `public_key` varchar(5120) NOT NULL COMMENT 'public key of the ssh key pair', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`usage_event` ( + `id` bigint unsigned NOT NULL auto_increment, + `type` varchar(32) NOT NULL, + `account_id` bigint unsigned NOT NULL, + `created` datetime NOT NULL, + `zone_id` bigint unsigned NOT NULL, + `resource_id` bigint unsigned, + `resource_name` varchar(255), + `offering_id` bigint unsigned, + `template_id` bigint unsigned, + `size` bigint unsigned, + `resource_type` varchar(32), + `processed` tinyint NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`ovs_tunnel_interface` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `ip` varchar(16) DEFAULT NULL, + `netmask` varchar(16) DEFAULT NULL, + `mac` varchar(18) DEFAULT NULL, + `host_id` bigint DEFAULT NULL, + `label` varchar(45) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`ovs_tunnel_interface` (`ip`, `netmask`, `mac`, `host_id`, `label`) VALUES ('0', '0', '0', 0, 'lock'); + +CREATE TABLE `cloud`.`ovs_tunnel_network`( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `from` bigint unsigned COMMENT 'from host id', + `to` bigint unsigned COMMENT 'to host id', + `network_id` bigint unsigned COMMENT 'network identifier', + `key` int unsigned COMMENT 'gre key', + `port_name` varchar(32) COMMENT 'in port on open vswitch', + `state` varchar(16) default 'FAILED' COMMENT 'result of tunnel creatation', + PRIMARY KEY(`from`, `to`, `network_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `cloud`.`ovs_tunnel_network` (`from`, `to`, `network_id`, `key`, `port_name`, `state`) VALUES (0, 0, 0, 0, 'lock', 'SUCCESS'); + +CREATE TABLE `cloud`.`storage_pool_work` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `pool_id` bigint unsigned NOT NULL COMMENT 'storage pool associated with the vm', + `vm_id` bigint unsigned NOT NULL COMMENT 'vm identifier', + `stopped_for_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was stopped during maintenance', + `started_after_maintenance` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'this flag denoted whether the vm was started after maintenance', + `mgmt_server_id` bigint unsigned NOT NULL COMMENT 'management server id', + PRIMARY KEY (`id`), + UNIQUE (pool_id,vm_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`data_center_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `dc_id` bigint unsigned NOT NULL COMMENT 'dc id', + `name` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_dc_details__dc_id` FOREIGN KEY (`dc_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`domain_network_ref` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `subdomain_access` int(1) unsigned COMMENT '1 if network can be accessible from the subdomain', + PRIMARY KEY (`id`), + CONSTRAINT `fk_domain_network_ref__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_domain_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`cmd_exec_log` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `host_id` bigint unsigned NOT NULL COMMENT 'host id of the system VM agent that command is sent to', + `instance_id` bigint unsigned NOT NULL COMMENT 'instance id of the system VM that command is executed on', + `command_name` varchar(255) NOT NULL COMMENT 'command name', + `weight` integer NOT NULL DEFAULT 1 COMMENT 'command weight in consideration of the load factor added to host that is executing the command', + `created` datetime NOT NULL COMMENT 'date created', + PRIMARY KEY (`id`), + INDEX `i_cmd_exec_log__host_id`(`host_id`), + INDEX `i_cmd_exec_log__instance_id`(`instance_id`), + CONSTRAINT `fk_cmd_exec_log_ref__inst_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`keystore` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(64) NOT NULL COMMENT 'unique name for the certifiation', + `certificate` text NOT NULL COMMENT 'the actual certificate being stored in the db', + `key` text COMMENT 'private key associated wih the certificate', + `domain_suffix` varchar(256) NOT NULL COMMENT 'DNS domain suffix associated with the certificate', + `seq` int, + PRIMARY KEY (`id`), + UNIQUE(name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`swift` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(40), + `url` varchar(255) NOT NULL, + `account` varchar(255) NOT NULL COMMENT ' account in swift', + `username` varchar(255) NOT NULL COMMENT ' username in swift', + `key` varchar(255) NOT NULL COMMENT 'token for this user', + `created` datetime COMMENT 'date the swift first signed on', + PRIMARY KEY (`id`), + CONSTRAINT `uc_swift__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`op_host_transfer` ( + `id` bigint unsigned UNIQUE NOT NULL COMMENT 'Id of the host', + `initial_mgmt_server_id` bigint unsigned COMMENT 'management server the host is transfered from', + `future_mgmt_server_id` bigint unsigned COMMENT 'management server the host is transfered to', + `state` varchar(32) NOT NULL COMMENT 'the transfer state of the host', + `created` datetime NOT NULL COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_op_host_transfer__id` FOREIGN KEY `fk_op_host_transfer__id` (`id`) REFERENCES `host` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_op_host_transfer__initial_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__initial_mgmt_server_id`(`initial_mgmt_server_id`) REFERENCES `mshost`(`msid`), + CONSTRAINT `fk_op_host_transfer__future_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__future_mgmt_server_id`(`future_mgmt_server_id`) REFERENCES `mshost`(`msid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`projects` ( + `id` bigint unsigned NOT NULL auto_increment, + `name` varchar(255) COMMENT 'project name', + `uuid` varchar(40), + `display_text` varchar(255) COMMENT 'project name', + `project_account_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `created` datetime COMMENT 'date created', + `removed` datetime COMMENT 'date removed', + `state` varchar(255) NOT NULL COMMENT 'state of the project (Active/Inactive/Suspended)', + PRIMARY KEY (`id`), + CONSTRAINT `fk_projects__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_projects__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + INDEX `i_projects__removed`(`removed`), + CONSTRAINT `uc_projects__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`project_account` ( + `id` bigint unsigned NOT NULL auto_increment, + `account_id` bigint unsigned NOT NULL COMMENT'account id', + `account_role` varchar(255) NOT NULL DEFAULT 'Regular' COMMENT 'Account role in the project (Owner or Regular)', + `project_id` bigint unsigned NOT NULL COMMENT 'project id', + `project_account_id` bigint unsigned NOT NULL, + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_project_account__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_account__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_account__project_account_id` FOREIGN KEY(`project_account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + UNIQUE (`account_id`, `project_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`project_invitations` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `project_id` bigint unsigned NOT NULL COMMENT 'project id', + `account_id` bigint unsigned COMMENT 'account id', + `domain_id` bigint unsigned COMMENT 'domain id', + `email` varchar(255) COMMENT 'email', + `token` varchar(255) COMMENT 'token', + `state` varchar(255) NOT NULL DEFAULT 'Pending' COMMENT 'the state of the invitation', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_project_invitations__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_invitations__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_project_invitations__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE, + UNIQUE (`project_id`, `account_id`), + UNIQUE (`project_id`, `email`), + UNIQUE (`project_id`, `token`), + CONSTRAINT `uc_project_invitations__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`elastic_lb_vm_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `ip_addr_id` bigint unsigned NOT NULL, + `elb_vm_id` bigint unsigned NOT NULL, + `lb_id` bigint unsigned, + PRIMARY KEY (`id`), + CONSTRAINT `fk_elastic_lb_vm_map__ip_id` FOREIGN KEY `fk_elastic_lb_vm_map__ip_id` (`ip_addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_elastic_lb_vm_map__elb_vm_id` FOREIGN KEY `fk_elastic_lb_vm_map__elb_vm_id` (`elb_vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_elastic_lb_vm_map__lb_id` FOREIGN KEY `fk_elastic_lb_vm_map__lb_id` (`lb_id`) REFERENCES `load_balancing_rules` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `ntwk_offering_service_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `network_offering_id` bigint unsigned NOT NULL COMMENT 'network_offering_id', + `service` varchar(255) NOT NULL COMMENT 'service', + `provider` varchar(255) COMMENT 'service provider', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_ntwk_offering_service_map__network_offering_id` FOREIGN KEY(`network_offering_id`) REFERENCES `network_offerings`(`id`) ON DELETE CASCADE, + UNIQUE (`network_offering_id`, `service`, `provider`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `ntwk_service_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `network_id` bigint unsigned NOT NULL COMMENT 'network_id', + `service` varchar(255) NOT NULL COMMENT 'service', + `provider` varchar(255) COMMENT 'service provider', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_ntwk_service_map__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + UNIQUE (`network_id`, `service`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`physical_network` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `name` varchar(255) NOT NULL, + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this physical network belongs to', + `vnet` varchar(255), + `speed` varchar(32), + `domain_id` bigint unsigned COMMENT 'foreign key to domain id', + `broadcast_domain_range` varchar(32) NOT NULL DEFAULT 'POD' COMMENT 'range of broadcast domain : POD/ZONE', + `state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'what state is this configuration in', + `created` datetime COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_physical_network__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_physical_network__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + CONSTRAINT `uc_physical_networks__uuid` UNIQUE (`uuid`), + INDEX `i_physical_network__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`physical_network_tags` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', + `tag` varchar(255) NOT NULL COMMENT 'tag', + PRIMARY KEY (`id`), + CONSTRAINT `fk_physical_network_tags__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + UNIQUE KEY(`physical_network_id`, `tag`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`physical_network_isolation_methods` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', + `isolation_method` varchar(255) NOT NULL COMMENT 'isolation method(VLAN, L3 or GRE)', + PRIMARY KEY (`id`), + CONSTRAINT `fk_physical_network_imethods__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + UNIQUE KEY(`physical_network_id`, `isolation_method`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`physical_network_traffic_types` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', + `traffic_type` varchar(32) NOT NULL COMMENT 'type of traffic going through this network', + `xen_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host', + `kvm_network_label` varchar(255) DEFAULT 'cloudbr0' COMMENT 'The network name label of the physical device dedicated to this traffic on a KVM host', + `vmware_network_label` varchar(255) DEFAULT 'vSwitch0' COMMENT 'The network name label of the physical device dedicated to this traffic on a VMware host', + `simulator_network_label` varchar(255) COMMENT 'The name labels needed for identifying the simulator', + `ovm_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a Ovm host', + `vlan` varchar(255) COMMENT 'The vlan tag to be sent down to a VMware host', + PRIMARY KEY (`id`), + CONSTRAINT `fk_physical_network_traffic_types__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_traffic_types__uuid` UNIQUE (`uuid`), + UNIQUE KEY(`physical_network_id`, `traffic_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`physical_network_service_providers` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network', + `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name', + `state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'provider state', + `destination_physical_network_id` bigint unsigned COMMENT 'id of the physical network to bridge to', + `vpn_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is VPN service provided', + `dhcp_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is DHCP service provided', + `dns_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is DNS service provided', + `gateway_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Gateway service provided', + `firewall_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Firewall service provided', + `source_nat_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Source NAT service provided', + `load_balance_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is LB service provided', + `static_nat_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Static NAT service provided', + `port_forwarding_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Port Forwarding service provided', + `user_data_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is UserData service provided', + `security_group_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is SG service provided', + `networkacl_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Network ACL service provided', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_pnetwork_service_providers__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_service_providers__uuid` UNIQUE (`uuid`), + UNIQUE KEY(`physical_network_id`, `provider_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`external_load_balancer_devices` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which load balancer device is added', + `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this load balancer device', + `device_name` varchar(255) NOT NULL COMMENT 'name of the load balancer device', + `capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the load balancer device', + `device_state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device', + `allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state (Free/Shared/Dedicated/Provider) of the device', + `is_dedicated` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device/appliance is provisioned for dedicated use only', + `is_inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer will be used in in-line configuration with firewall', + `is_managed` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer appliance is provisioned and its life cycle is managed by by cloudstack', + `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external load balancer device', + `parent_host_id` bigint unsigned COMMENT 'if the load balancer appliance is cloudstack managed, then host id on which this appliance is provisioned', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_lb_devices_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_lb_devices_parent_host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_lb_devices_physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`external_firewall_devices` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which firewall device is added', + `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this firewall device', + `device_name` varchar(255) NOT NULL COMMENT 'name of the firewall device', + `device_state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device', + `is_dedicated` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device/appliance meant for dedicated use only', + `allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state (Free/Allocated) of the device', + `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external firewall device', + `capacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Capacity of the external firewall device', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_firewall_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_firewall_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_external_lb_device_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `network_id` bigint unsigned NOT NULL COMMENT ' guest network id', + `external_load_balancer_device_id` bigint unsigned NOT NULL COMMENT 'id of external load balancer device assigned for this network', + `created` datetime COMMENT 'Date from when network started using the device', + `removed` datetime COMMENT 'Date till the network stopped using the device ', + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_external_lb_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_network_external_lb_devices_device_id` FOREIGN KEY (`external_load_balancer_device_id`) REFERENCES `external_load_balancer_devices`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`network_external_firewall_device_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `network_id` bigint unsigned NOT NULL COMMENT ' guest network id', + `external_firewall_device_id` bigint unsigned NOT NULL COMMENT 'id of external firewall device assigned for this device', + `created` datetime COMMENT 'Date from when network started using the device', + `removed` datetime COMMENT 'Date till the network stopped using the device ', + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_external_firewall_devices_network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_network_external_firewall_devices_device_id` FOREIGN KEY (`external_firewall_device_id`) REFERENCES `external_firewall_devices`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`virtual_router_providers` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `nsp_id` bigint unsigned NOT NULL COMMENT 'Network Service Provider ID', + `uuid` varchar(40), + `type` varchar(255) NOT NULL COMMENT 'Virtual router, or ElbVM', + `enabled` int(1) NOT NULL COMMENT 'Enabled or disabled', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_virtual_router_providers__nsp_id` FOREIGN KEY (`nsp_id`) REFERENCES `physical_network_service_providers` (`id`) ON DELETE CASCADE, + CONSTRAINT `uc_virtual_router_providers__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`op_user_stats_log` ( + `user_stats_id` bigint unsigned NOT NULL, + `net_bytes_received` bigint unsigned NOT NULL default '0', + `net_bytes_sent` bigint unsigned NOT NULL default '0', + `current_bytes_received` bigint unsigned NOT NULL default '0', + `current_bytes_sent` bigint unsigned NOT NULL default '0', + `agg_bytes_received` bigint unsigned NOT NULL default '0', + `agg_bytes_sent` bigint unsigned NOT NULL default '0', + `updated` datetime COMMENT 'stats update timestamp', + UNIQUE KEY (`user_stats_id`, `updated`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`cluster_vsm_map` ( + `cluster_id` bigint unsigned NOT NULL, + `vsm_id` bigint unsigned NOT NULL, + PRIMARY KEY (`cluster_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`virtual_supervisor_module` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `host_id` bigint NOT NULL, + `vsm_name` varchar(255), + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `ipaddr` varchar(80) NOT NULL, + `management_vlan` int(32), + `control_vlan` int(32), + `packet_vlan` int(32), + `storage_vlan` int(32), + `vsm_domain_id` bigint unsigned, + `config_mode` varchar(20), + `config_state` varchar(20), + `vsm_device_state` varchar(20) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`port_profile` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `port_profile_name` varchar(255), + `port_mode` varchar(10), + `vsm_id` bigint unsigned NOT NULL, + `trunk_low_vlan_id` int, + `trunk_high_vlan_id` int, + `access_vlan_id` int, + `port_type` varchar(20) NOT NULL, + `port_binding` varchar(20), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`s2s_vpn_gateway` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `addr_id` bigint unsigned NOT NULL, + `vpc_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_s2s_vpn_gateway__addr_id` FOREIGN KEY (`addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_gateway__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_gateway__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_gateway__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_s2s_vpn_gateway__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`s2s_customer_gateway` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `gateway_ip` char(40) NOT NULL, + `guest_cidr_list` varchar(200) NOT NULL, + `ipsec_psk` varchar(256), + `ike_policy` varchar(30) NOT NULL, + `esp_policy` varchar(30) NOT NULL, + `lifetime` int, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_s2s_customer_gateway__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_customer_gateway__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_s2s_customer_gateway__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`s2s_vpn_connection` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `vpn_gateway_id` bigint unsigned NULL, + `customer_gateway_id` bigint unsigned NULL, + `state` varchar(32) NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_s2s_vpn_connection__vpn_gateway_id` FOREIGN KEY (`vpn_gateway_id`) REFERENCES `s2s_vpn_gateway` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_connection__customer_gateway_id` FOREIGN KEY (`customer_gateway_id`) REFERENCES `s2s_customer_gateway` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_connection__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_connection__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_s2s_vpn_connection__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`resource_tags` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `key` varchar(255), + `value` varchar(255), + `resource_id` bigint unsigned NOT NULL, + `resource_uuid` varchar(40), + `resource_type` varchar(255), + `customer` varchar(255), + `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`), + CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpc` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'vpc display text', + `cidr` varchar(18) COMMENT 'vpc cidr', + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc offering id that this vpc is created from', + `zone_id` bigint unsigned NOT NULL COMMENT 'the id of the zone this Vpc belongs to', + `state` varchar(32) NOT NULL COMMENT 'state of the VP (can be Enabled and Disabled)', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain the vpc belongs to', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this vpc', + `network_domain` varchar(255) COMMENT 'network domain', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the VPC', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc__zone_id` FOREIGN KEY `fk_vpc__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), + CONSTRAINT `fk_vpc__account_id` FOREIGN KEY `fk_vpc__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__domain_id` FOREIGN KEY `fk_vpc__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_offerings` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the vpc offering', + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'display text', + `state` char(32) COMMENT 'state of the vpc offering that has Disabled value by default', + `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if vpc offering is default', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc_offerings__service_offering_id` FOREIGN KEY `fk_vpc_offerings__service_offering_id` (`service_offering_id`) REFERENCES `service_offering`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpc_offering_service_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc_offering_id', + `service` varchar(255) NOT NULL COMMENT 'service', + `provider` varchar(255) COMMENT 'service provider', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_offering_service_map__vpc_offering_id` FOREIGN KEY(`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`) ON DELETE CASCADE, + UNIQUE (`vpc_offering_id`, `service`, `provider`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`router_network_ref` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `router_id` bigint unsigned NOT NULL COMMENT 'router id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', + PRIMARY KEY (`id`), + CONSTRAINT `fk_router_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + UNIQUE `i_router_network_ref__router_id__network_id`(`router_id`, `network_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_gateways` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `ip4_address` char(40) COMMENT 'ip4 address of the gateway', + `netmask` varchar(15) COMMENT 'netmask of the gateway', + `gateway` varchar(15) COMMENT 'gateway', + `vlan_tag` varchar(255), + `type` varchar(32) COMMENT 'type of gateway; can be Public/Private/Vpn', + `network_id` bigint unsigned NOT NULL COMMENT 'network id vpc gateway belongs to', + `vpc_id` bigint unsigned NOT NULL COMMENT 'id of the vpc the gateway belongs to', + `zone_id` bigint unsigned NOT NULL COMMENT 'id of the zone the gateway belongs to', + `created` datetime COMMENT 'date created', + `account_id` bigint unsigned NOT NULL COMMENT 'owner id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `state` varchar(32) NOT NULL COMMENT 'what state the vpc gateway in', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_gateways__network_id` FOREIGN KEY `fk_vpc_gateways__network_id`(`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_vpc_gateways__vpc_id` FOREIGN KEY `fk_vpc_gateways__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), + CONSTRAINT `fk_vpc_gateways__zone_id` FOREIGN KEY `fk_vpc_gateways__zone_id`(`zone_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `fk_vpc_gateways__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc_gateways__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_vpc_gateways__uuid` UNIQUE (`uuid`), + INDEX `i_vpc_gateways__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`private_ip_address` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `network_id` bigint unsigned NOT NULL COMMENT 'id of the network ip belongs to', + `reservation_id` char(40) COMMENT 'reservation id', + `mac_address` varchar(17) COMMENT 'mac address', + `vpc_id` bigint unsigned COMMENT 'vpc this ip belongs to', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + CONSTRAINT `fk_private_ip_address__vpc_id` FOREIGN KEY `fk_private_ip_address__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), + CONSTRAINT `fk_private_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`static_routes` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `vpc_gateway_id` bigint unsigned COMMENT 'id of the corresponding ip address', + `cidr` varchar(18) COMMENT 'cidr for the static route', + `state` char(32) NOT NULL COMMENT 'current state of this rule', + `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', + `account_id` bigint unsigned NOT NULL COMMENT 'owner id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `created` datetime COMMENT 'Date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_static_routes__vpc_gateway_id` FOREIGN KEY(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_static_routes__uuid` UNIQUE (`uuid`) +) 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, + `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', + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when a condition needs to be disassociated with a policy', + `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, + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when a condition needs to be disassociated with a policy', + 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, + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when a policy needs to be disassociated with a vmgroup', + 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 ac301726da5..8e35822fbd7 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -1,1138 +1,1150 @@ -// 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.utils.net; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.lang.reflect.Array; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Formatter; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.log4j.Logger; -import org.apache.log4j.xml.DOMConfigurator; - -import com.cloud.utils.IteratorUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.script.Script; - -public class NetUtils { - protected final static Logger s_logger = Logger.getLogger(NetUtils.class); - public final static String HTTP_PORT = "80"; - public final static int VPN_PORT = 500; - public final static int VPN_NATT_PORT = 4500; - public final static int VPN_L2TP_PORT = 1701; - - public final static String UDP_PROTO = "udp"; - public final static String TCP_PROTO = "tcp"; - public final static String ANY_PROTO = "any"; - public final static String ICMP_PROTO = "icmp"; - public final static String ALL_PROTO = "all"; - - public final static String ALL_CIDRS = "0.0.0.0/0"; - - private final static Random _rand = new Random(System.currentTimeMillis()); - - public static long createSequenceBasedMacAddress(long macAddress) { - return macAddress | 0x060000000000l | (((long) _rand.nextInt(32768) << 25) & 0x00fffe000000l); - } - - public static String getHostName() { - try { - InetAddress localAddr = InetAddress.getLocalHost(); - if (localAddr != null) { - return localAddr.getHostName(); - } - } catch (UnknownHostException e) { - s_logger.warn("UnknownHostException when trying to get host name. ", e); - } - return "localhost"; - } - - public static InetAddress getLocalInetAddress() { - try { - return InetAddress.getLocalHost(); - } catch (UnknownHostException e) { - s_logger.warn("UnknownHostException in getLocalInetAddress().", e); - return null; - } - } - - public static String resolveToIp(String host) { - try { - InetAddress addr = InetAddress.getByName(host); - return ipFromInetAddress(addr); - } catch (UnknownHostException e) { - s_logger.warn("Unable to resolve " + host + " to IP due to UnknownHostException"); - return null; - } - } - - public static InetAddress[] getAllLocalInetAddresses() { - List addrList = new ArrayList(); - try { - for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual()) { - for (InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { - addrList.add(addr); - } - } - } - } catch (SocketException e) { - s_logger.warn("SocketException in getAllLocalInetAddresses().", e); - } - - InetAddress[] addrs = new InetAddress[addrList.size()]; - if (addrList.size() > 0) { - System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); - } - return addrs; - } - - public static String[] getLocalCidrs() { - String defaultHostIp = getDefaultHostIp(); - - List cidrList = new ArrayList(); - try { - for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual() && !ifc.isLoopback()) { - for (InterfaceAddress address : ifc.getInterfaceAddresses()) { - InetAddress addr = address.getAddress(); - int prefixLength = address.getNetworkPrefixLength(); - if (prefixLength < 32 && prefixLength > 0) { - String ip = ipFromInetAddress(addr); - if(ip.equalsIgnoreCase(defaultHostIp)) - cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength))); - } - } - } - } - } catch (SocketException e) { - s_logger.warn("UnknownHostException in getLocalCidrs().", e); - } - - return cidrList.toArray(new String[0]); - } - - private static boolean isWindows() { - String os = System.getProperty("os.name"); - if(os != null && os.startsWith("Windows")) - return true; - - return false; - } - - public static String getDefaultHostIp() { - if(isWindows()) { - Pattern pattern = Pattern.compile("\\s*0.0.0.0\\s*0.0.0.0\\s*(\\S*)\\s*(\\S*)\\s*"); - try { - Process result = Runtime.getRuntime().exec("route print -4"); - BufferedReader output = new BufferedReader - (new InputStreamReader(result.getInputStream())); - - String line = output.readLine(); - while(line != null){ - Matcher matcher = pattern.matcher(line); - if (matcher.find()) { - return matcher.group(2); - } - line = output.readLine(); - } - } catch( Exception e ) { - } - return null; - } else { - NetworkInterface nic = null; - String pubNic = getDefaultEthDevice(); - - if (pubNic == null) { - return null; - } - - try { - nic = NetworkInterface.getByName(pubNic); - } catch (final SocketException e) { - return null; - } - - String[] info = NetUtils.getNetworkParams(nic); - return info[0]; - } - } - - public static String getDefaultEthDevice() { - String defaultRoute = Script.runSimpleBashScript("/sbin/route | grep default"); - - if (defaultRoute == null) { - return null; - } - - String[] defaultRouteList = defaultRoute.split("\\s+"); - - if (defaultRouteList.length != 8) { - return null; - } - - return defaultRouteList[7]; - } - - public static InetAddress getFirstNonLoopbackLocalInetAddress() { - InetAddress[] addrs = getAllLocalInetAddresses(); - if (addrs != null) { - for (InetAddress addr : addrs) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Check local InetAddress : " + addr.toString() + ", total count :" + addrs.length); - } - - if (!addr.isLoopbackAddress()) { - return addr; - } - } - } - - s_logger.warn("Unable to determine a non-loopback address, local inet address count :" + addrs.length); - return null; - } - - public static InetAddress[] getInterfaceInetAddresses(String ifName) { - List addrList = new ArrayList(); - try { - for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual() && ifc.getName().equals(ifName)) { - for (InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { - addrList.add(addr); - } - } - } - } catch (SocketException e) { - s_logger.warn("SocketException in getAllLocalInetAddresses().", e); - } - - InetAddress[] addrs = new InetAddress[addrList.size()]; - if (addrList.size() > 0) { - System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); - } - return addrs; - } - - public static String getLocalIPString() { - InetAddress addr = getLocalInetAddress(); - if (addr != null) { - return ipFromInetAddress(addr); - } - - return new String("127.0.0.1"); - } - - public static String ipFromInetAddress(InetAddress addr) { - assert (addr != null); - - byte[] ipBytes = addr.getAddress(); - StringBuffer sb = new StringBuffer(); - sb.append(ipBytes[0] & 0xff).append("."); - sb.append(ipBytes[1] & 0xff).append("."); - sb.append(ipBytes[2] & 0xff).append("."); - sb.append(ipBytes[3] & 0xff); - - return sb.toString(); - } - - public static boolean isLocalAddress(InetAddress addr) { - InetAddress[] addrs = getAllLocalInetAddresses(); - - if (addrs != null) { - for (InetAddress self : addrs) { - if (self.equals(addr)) { - return true; - } - } - } - return false; - } - - public static boolean isLocalAddress(String strAddress) { - - InetAddress addr; - try { - addr = InetAddress.getByName(strAddress); - return isLocalAddress(addr); - } catch (UnknownHostException e) { - } - return false; - } - - public static String getMacAddress(InetAddress address) { - StringBuffer sb = new StringBuffer(); - Formatter formatter = new Formatter(sb); - try { - NetworkInterface ni = NetworkInterface.getByInetAddress(address); - byte[] mac = ni.getHardwareAddress(); - - for (int i = 0; i < mac.length; i++) { - formatter.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""); - } - } catch (SocketException e) { - s_logger.error("SocketException when trying to retrieve MAC address", e); - } - return sb.toString(); - } - - public static long getMacAddressAsLong(InetAddress address) { - long macAddressAsLong = 0; - try { - NetworkInterface ni = NetworkInterface.getByInetAddress(address); - byte[] mac = ni.getHardwareAddress(); - - for (int i = 0; i < mac.length; i++) { - macAddressAsLong |= ((long) (mac[i] & 0xff) << (mac.length - i - 1) * 8); - } - - } catch (SocketException e) { - s_logger.error("SocketException when trying to retrieve MAC address", e); - } - - return macAddressAsLong; - } - - public static boolean ipRangesOverlap(String startIp1, String endIp1, String startIp2, String endIp2) { - long startIp1Long = ip2Long(startIp1); - long endIp1Long = startIp1Long; - if (endIp1 != null) { - endIp1Long = ip2Long(endIp1); - } - long startIp2Long = ip2Long(startIp2); - long endIp2Long = startIp2Long; - if (endIp2 != null) { - endIp2Long = ip2Long(endIp2); - } - - if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) { - return true; - } else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) { - return true; - } else if (endIp1Long > startIp2Long && endIp1Long < endIp2Long) { - return true; - } else if (startIp2Long > startIp1Long && startIp2Long < endIp1Long) { - return true; - } else if (endIp2Long > startIp1Long && endIp2Long < endIp1Long) { - return true; - } else { - return false; - } - } - - public static long ip2Long(String ip) { - String[] tokens = ip.split("[.]"); - assert (tokens.length == 4); - long result = 0; - for (int i = 0; i < tokens.length; i++) { - try { - result = (result << 8) | Integer.parseInt(tokens[i]); - } catch (NumberFormatException e) { - throw new RuntimeException("Incorrect number", e); - } - } - - return result; - } - - public static String long2Ip(long ip) { - StringBuilder result = new StringBuilder(15); - result.append((ip >> 24 & 0xff)).append("."); - result.append((ip >> 16 & 0xff)).append("."); - result.append((ip >> 8 & 0xff)).append("."); - result.append(ip & 0xff); - - return result.toString(); - } - - public static long mac2Long(String macAddress) { - String[] tokens = macAddress.split(":"); - assert (tokens.length == 6); - long result = 0; - for (int i = 0; i < tokens.length; i++) { - result = result << 8; - result |= Integer.parseInt(tokens[i], 16); - } - return result; - } - - public static String[] getNicParams(String nicName) { - try { - NetworkInterface nic = NetworkInterface.getByName(nicName); - return getNetworkParams(nic); - } catch (SocketException e) { - return null; - } - } - - public static String[] getNetworkParams(NetworkInterface nic) { - List addrs = nic.getInterfaceAddresses(); - if (addrs == null || addrs.size() == 0) { - return null; - } - InterfaceAddress addr = null; - for (InterfaceAddress iaddr : addrs) { - InetAddress inet = iaddr.getAddress(); - if (!inet.isLinkLocalAddress() && !inet.isLoopbackAddress() && !inet.isMulticastAddress() && inet.getAddress().length == 4) { - addr = iaddr; - break; - } - } - if (addr == null) { - return null; - } - String[] result = new String[3]; - result[0] = addr.getAddress().getHostAddress(); - try { - byte[] mac = nic.getHardwareAddress(); - result[1] = byte2Mac(mac); - } catch (Exception e) { - } - - result[2] = prefix2Netmask(addr.getNetworkPrefixLength()); - return result; - } - - public static String prefix2Netmask(short prefix) { - long addr = 0; - for (int i = 0; i < prefix; i++) { - addr = addr | (1 << (31 - i)); - } - - return long2Ip(addr); - } - - public static String byte2Mac(byte[] m) { - StringBuilder result = new StringBuilder(17); - Formatter formatter = new Formatter(result); - formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", m[0], m[1], m[2], m[3], m[4], m[5]); - return result.toString(); - } - - public static String long2Mac(long macAddress) { - StringBuilder result = new StringBuilder(17); - Formatter formatter = new Formatter(result); - formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", (macAddress >> 40) & 0xff, (macAddress >> 32) & 0xff, (macAddress >> 24) & 0xff, (macAddress >> 16) & 0xff, (macAddress >> 8) & 0xff, - (macAddress & 0xff)); - - return result.toString(); - } - - public static boolean isValidPrivateIp(String ipAddress, String guestIPAddress) { - - InetAddress privIp = parseIpAddress(ipAddress); - if (privIp == null) { - return false; - } - if (!privIp.isSiteLocalAddress()) { - return false; - } - - String firstGuestOctet = "10"; - if (guestIPAddress != null && !guestIPAddress.isEmpty()) { - String[] guestIPList = guestIPAddress.split("\\."); - firstGuestOctet = guestIPList[0]; - } - - String[] ipList = ipAddress.split("\\."); - if (!ipList[0].equals(firstGuestOctet)) { - return false; - } - - return true; - } - - public static boolean isSiteLocalAddress(String ipAddress) { - if (ipAddress == null) { - return false; - } else { - InetAddress ip = parseIpAddress(ipAddress); - return ip.isSiteLocalAddress(); - } - } - - public static boolean validIpRange(String startIP, String endIP) { - if (endIP == null || endIP.isEmpty()) { - return true; - } - - long startIPLong = NetUtils.ip2Long(startIP); - long endIPLong = NetUtils.ip2Long(endIP); - return (startIPLong <= endIPLong); - } - - public static boolean isValidIp(final String ip) { - final String[] ipAsList = ip.split("\\."); - - // The IP address must have four octets - if (Array.getLength(ipAsList) != 4) { - return false; - } - - for (int i = 0; i < 4; i++) { - // Each octet must be an integer - final String octetString = ipAsList[i]; - int octet; - try { - octet = Integer.parseInt(octetString); - } catch (final Exception e) { - return false; - } - // Each octet must be between 0 and 255, inclusive - if (octet < 0 || octet > 255) { - return false; - } - - // Each octetString must have between 1 and 3 characters - if (octetString.length() < 1 || octetString.length() > 3) { - return false; - } - } - - // IP is good, return true - return true; - } - - public static boolean isValidCIDR(final String cidr) { - if (cidr == null || cidr.isEmpty()) { - return false; - } - String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return false; - } - String cidrAddress = cidrPair[0]; - String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return false; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (Exception e) { - return false; - } - - if (cidrSizeNum < 0 || cidrSizeNum > 32) { - return false; - } - - return true; - } - - public static boolean isValidNetmask(String netmask) { - if (!isValidIp(netmask)) { - return false; - } - - long ip = ip2Long(netmask); - int count = 0; - boolean finished = false; - for (int i = 31; i >= 0; i--) { - if (((ip >> i) & 0x1) == 0) { - finished = true; - } else { - if (finished) { - return false; - } - count += 1; - } - } - - if (count == 0) { - return false; - } - - return true; - } - - private static InetAddress parseIpAddress(String address) { - StringTokenizer st = new StringTokenizer(address, "."); - byte[] bytes = new byte[4]; - - if (st.countTokens() == 4) { - try { - for (int i = 0; i < 4; i++) { - bytes[i] = (byte) Integer.parseInt(st.nextToken()); - } - return InetAddress.getByAddress(address, bytes); - } catch (NumberFormatException nfe) { - return null; - } catch (UnknownHostException uhe) { - return null; - } - } - return null; - } - - public static String getCidrFromGatewayAndNetmask(String gatewayStr, String netmaskStr) { - long netmask = ip2Long(netmaskStr); - long gateway = ip2Long(gatewayStr); - long firstPart = gateway & netmask; - long size = getCidrSize(netmaskStr); - return long2Ip(firstPart) + "/" + size; - } - - public static String[] getIpRangeFromCidr(String cidr, long size) { - assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - String[] result = new String[2]; - long ip = ip2Long(cidr); - long startNetMask = ip2Long(getCidrNetmask(size)); - long start = (ip & startNetMask) + 1; - long end = start; - - end = end >> (32 - size); - - end++; - end = (end << (32 - size)) - 2; - - result[0] = long2Ip(start); - result[1] = long2Ip(end); - - return result; - } - - public static Set getAllIpsFromCidr(String cidr, long size) { - assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - Set result = new TreeSet(); - long ip = ip2Long(cidr); - long startNetMask = ip2Long(getCidrNetmask(size)); - long start = (ip & startNetMask) + 2; - long end = start; - - end = end >> (32 - size); - - end++; - end = (end << (32 - size)) - 2; - while (start <= end) { - result.add(start); - start++; - } - - return result; - } - - /** - * Given a cidr, this method returns an ip address within the range but - * is not in the avoid list. - * - * @param startIp ip that the cidr starts with - * @param size size of the cidr - * @param avoid set of ips to avoid - * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. - */ - public static long getRandomIpFromCidr(String startIp, int size, Set avoid) { - return getRandomIpFromCidr(ip2Long(startIp), size, avoid); - - } - - /** - * Given a cidr, this method returns an ip address within the range but - * is not in the avoid list. - * - * @param startIp ip that the cidr starts with - * @param size size of the cidr - * @param avoid set of ips to avoid - * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. - */ - public static long getRandomIpFromCidr(long cidr, int size, Set avoid) { - assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; - - long startNetMask = ip2Long(getCidrNetmask(size)); - long startIp = (cidr & startNetMask) + 2; - int range = 1 << (32 - size); - - if (avoid.size() > range) { - return -1; - } - - for (int i = 0; i < range; i++) { - int next = _rand.nextInt(range); - if (!avoid.contains(startIp + next)) { - return startIp + next; - } - } - - return -1; - } - - public static String getIpRangeStartIpFromCidr(String cidr, long size) { - long ip = ip2Long(cidr); - long startNetMask = ip2Long(getCidrNetmask(size)); - long start = (ip & startNetMask) + 1; - return long2Ip(start); - } - - public static String getIpRangeEndIpFromCidr(String cidr, long size) { - long ip = ip2Long(cidr); - long startNetMask = ip2Long(getCidrNetmask(size)); - long start = (ip & startNetMask) + 1; - long end = start; - end = end >> (32 - size); - - end++; - end = (end << (32 - size)) - 2; - return long2Ip(end); - } - - public static boolean sameSubnet(final String ip1, final String ip2, final String netmask) { - if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { - return true; - } - String subnet1 = NetUtils.getSubNet(ip1, netmask); - String subnet2 = NetUtils.getSubNet(ip2, netmask); - - return (subnet1.equals(subnet2)); - } - - public static boolean sameSubnetCIDR(final String ip1, final String ip2, final long cidrSize) { - if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { - return true; - } - String subnet1 = NetUtils.getCidrSubNet(ip1, cidrSize); - String subnet2 = NetUtils.getCidrSubNet(ip2, cidrSize); - - return (subnet1.equals(subnet2)); - } - - public static String getSubNet(String ip, String netmask) { - long ipAddr = ip2Long(ip); - long subnet = ip2Long(netmask); - long result = ipAddr & subnet; - return long2Ip(result); - } - - public static String getBroadcastIp(String ip, String netmask) { - long ipAddr = ip2Long(ip); - long subnet = ip2Long(netmask); - long result = ipAddr | (~subnet); - return long2Ip(result); - } - - public static String getCidrSubNet(String ip, long cidrSize) { - long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize); - String netmask = NetUtils.long2Ip(numericNetmask); - return getSubNet(ip, netmask); - } - - public static String ipAndNetMaskToCidr(String ip, String netmask) { - long ipAddr = ip2Long(ip); - long subnet = ip2Long(netmask); - long result = ipAddr & subnet; - int bits = (subnet == 0) ? 0 : 1; - long subnet2 = subnet; - while ((subnet2 = (subnet2 >> 1) & subnet) != 0) { - bits++; - } - - return long2Ip(result) + "/" + Integer.toString(bits); - } - - public static String[] ipAndNetMaskToRange(String ip, String netmask) { - long ipAddr = ip2Long(ip); - long subnet = ip2Long(netmask); - long start = (ipAddr & subnet) + 1; - long end = start; - int bits = (subnet == 0) ? 0 : 1; - while ((subnet = (subnet >> 1) & subnet) != 0) { - bits++; - } - end = end >> (32 - bits); - - end++; - end = (end << (32 - bits)) - 2; - - return new String[] { long2Ip(start), long2Ip(end) }; - - } - - public static Pair getCidr(String cidr) { - String[] tokens = cidr.split("/"); - return new Pair(tokens[0], Integer.parseInt(tokens[1])); - } - - public static boolean isNetworkAWithinNetworkB(String cidrA, String cidrB) { - Long[] cidrALong = cidrToLong(cidrA); - Long[] cidrBLong = cidrToLong(cidrB); - if (cidrALong == null || cidrBLong == null) { - return false; - } - long shift = 32 - cidrBLong[1]; - return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift)); - } - - public static boolean isNetworksOverlap(String cidrA, String cidrB) { - Long[] cidrALong = cidrToLong(cidrA); - Long[] cidrBLong = cidrToLong(cidrB); - if (cidrALong == null || cidrBLong == null) { - return false; - } - long shift = 32 - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]); - return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift)); - } - - public static Long[] cidrToLong(String cidr) { - if (cidr == null || cidr.isEmpty()) { - return null; - } - String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return null; - } - String cidrAddress = cidrPair[0]; - String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return null; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (Exception e) { - return null; - } - long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); - long ipAddr = ip2Long(cidrAddress); - Long[] cidrlong = { ipAddr & numericNetmask, (long) cidrSizeNum }; - return cidrlong; - - } - - public static String getCidrSubNet(String cidr) { - if (cidr == null || cidr.isEmpty()) { - return null; - } - String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return null; - } - String cidrAddress = cidrPair[0]; - String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return null; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (Exception e) { - return null; - } - long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); - String netmask = NetUtils.long2Ip(numericNetmask); - return getSubNet(cidrAddress, netmask); - } - - public static String getCidrBroadcastIp(String cidr) { - if (cidr == null || cidr.isEmpty()) { - return null; - } - String[] cidrPair = cidr.split("\\/"); - if (cidrPair.length != 2) { - return null; - } - String cidrAddress = cidrPair[0]; - String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { - return null; - } - int cidrSizeNum = -1; - - try { - cidrSizeNum = Integer.parseInt(cidrSize); - } catch (Exception e) { - return null; - } - long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); - String netmask = NetUtils.long2Ip(numericNetmask); - return getBroadcastIp(cidrAddress, netmask); - } - - public static String getCidrNetmask(long cidrSize) { - long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize); - return long2Ip(numericNetmask); - } - - public static String getCidrNetmask(String cidr) { - String[] cidrPair = cidr.split("\\/"); - long guestCidrSize = Long.parseLong(cidrPair[1]); - return getCidrNetmask(guestCidrSize); - } - - public static String cidr2Netmask(String cidr) { - String[] tokens = cidr.split("\\/"); - return getCidrNetmask(Integer.parseInt(tokens[1])); - } - - public static long getCidrSize(String netmask) { - long ip = ip2Long(netmask); - int count = 0; - for (int i = 0; i < 32; i++) { - if (((ip >> i) & 0x1) == 0) { - count++; - } else { - break; - } - } - - return 32 - count; - } - - public static boolean isValidPort(String p) { - try { - int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isValidPort(int p) { - return !(p > 65535 || p < 1); - } - - public static boolean isValidLBPort(String p) { - try { - int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isValidProto(String p) { - String proto = p.toLowerCase(); - return (proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO)); - } - - public static boolean isValidSecurityGroupProto(String p) { - String proto = p.toLowerCase(); - return (proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO) || proto.equals(ALL_PROTO)); - } - - public static boolean isValidAlgorithm(String p) { - String algo = p.toLowerCase(); - return (algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source")); - } - - public static String getLinkLocalNetMask() { - return "255.255.0.0"; - } - - public static String getLinkLocalGateway() { - return "169.254.0.1"; - } - - public static String getLinkLocalCIDR() { - return "169.254.0.0/16"; - } - - public static String[] getLinkLocalIPRange(int size) { - if (size > 16 || size <= 0) { - return null; - } - /* reserve gateway */ - String[] range = getIpRangeFromCidr(getLinkLocalGateway(), 32 - size); - - if (range[0].equalsIgnoreCase(getLinkLocalGateway())) { - /* remove the gateway */ - long ip = ip2Long(range[0]); - ip += 1; - range[0] = long2Ip(ip); - } - return range; - } - - public static String getLinkLocalIpEnd() { - String[] cidrPair = getLinkLocalCIDR().split("\\/"); - String cidr = cidrPair[0]; - - return getIpRangeEndIpFromCidr(cidr, 32 - Long.parseLong(cidrPair[1])); - } - - public static String portRangeToString(int portRange[]) { - return Integer.toString(portRange[0]) + ":" + Integer.toString(portRange[1]); - } - - // test only - private static void configLog4j() { - URL configUrl = System.class.getResource("/conf/log4j-cloud.xml"); - if (configUrl != null) { - System.out.println("Configure log4j using log4j-cloud.xml"); - - try { - File file = new File(configUrl.toURI()); - - System.out.println("Log4j configuration from : " + file.getAbsolutePath()); - DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); - } catch (URISyntaxException e) { - System.out.println("Unable to convert log4j configuration Url to URI"); - } - // DOMConfigurator.configure(configUrl); - } else { - System.out.println("Configure log4j with default properties"); - } - } - - - public static boolean verifyDomainNameLabel(String hostName, boolean isHostName) { - // must be between 1 and 63 characters long and may contain only the ASCII letters 'a' through 'z' (in a - // case-insensitive manner), - // the digits '0' through '9', and the hyphen ('-'). - // Can not start with a hyphen and digit, and must not end with a hyphen - // If it's a host name, don't allow to start with digit - - if (hostName.length() > 63 || hostName.length() < 1) { - s_logger.warn("Domain name label must be between 1 and 63 characters long"); - return false; - } else if (!hostName.toLowerCase().matches("[a-z0-9-]*")) { - s_logger.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)"); - return false; - } else if (hostName.startsWith("-") || hostName.endsWith("-")) { - s_logger.warn("Domain name label can not start with a hyphen and digit, and must not end with a hyphen"); - return false; - } else if (isHostName && hostName.matches("^[0-9-].*")) { - s_logger.warn("Host name can't start with digit"); - return false; - } - - return true; - } - - public static boolean verifyDomainName(String domainName) { - // don't allow domain name length to exceed 190 chars (190 + 63 (max host name length) = 253 = max domainName length - if (domainName.length() < 1 || domainName.length() > 190) { - s_logger.trace("Domain name must be between 1 and 190 characters long"); - return false; - } - - if (domainName.startsWith(".") || domainName.endsWith(".")) { - s_logger.trace("Domain name can't start or end with ."); - return false; - } - - String[] domainNameLabels = domainName.split("\\."); - - for (int i = 0; i < domainNameLabels.length; i++) { - if (!verifyDomainNameLabel(domainNameLabels[i], false)) { - s_logger.warn("Domain name label " + domainNameLabels[i] + " is incorrect"); - return false; - } - } - - return true; - } - - public static String getDhcpRange(String cidr) { - String[] splitResult = cidr.split("\\/"); - long size = Long.valueOf(splitResult[1]); - return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size); - } - - public static boolean validateGuestCidr(String cidr) { - // RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the - // following three blocks of the IP address space for private internets: - // 10.0.0.0 - 10.255.255.255 (10/8 prefix) - // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) - // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) - - String cidr1 = "10.0.0.0/8"; - String cidr2 = "172.16.0.0/12"; - String cidr3 = "192.168.0.0/16"; - - if (!isValidCIDR(cidr)) { - s_logger.warn("Cidr " + cidr + " is not valid"); - return false; - } - - if (isNetworkAWithinNetworkB(cidr, cidr1) || isNetworkAWithinNetworkB(cidr, cidr2) || isNetworkAWithinNetworkB(cidr, cidr3)) { - return true; - } else { - s_logger.warn("cidr " + cidr + " is not RFC 1918 compliant"); - return false; - } - } - - public static boolean verifyInstanceName(String instanceName) { - //instance name for cloudstack vms shouldn't contain - and spaces - if (instanceName.contains("-") || instanceName.contains(" ") || instanceName.contains("+")) { - s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char"); - return false; - } - - return true; - } - - public static boolean isValidS2SVpnPolicy(String policys) { - if (policys == null || policys.isEmpty()) { - return false; - } - for (String policy : policys.split(",")) { - if (policy.isEmpty()) { - return false; - } - //String cipherHash = policy.split(";")[0]; - String cipherHash = policy; - if (cipherHash.isEmpty()) { - return false; - } - String[] list = cipherHash.split("-"); - if (list.length != 2) { - return false; - } - String cipher = list[0]; - String hash = list[1]; - if (!cipher.matches("3des|aes|aes128|aes256")) { - return false; - } - if (!hash.matches("md5|sha1")) { - return false; - } - /* Disable pfsGroup support, see CS-15511 - String pfsGroup = null; - if (!policy.equals(cipherHash)) { - pfsGroup = policy.split(";")[1]; - } - if (pfsGroup != null && !pfsGroup.matches("modp1024|modp1536")) { - return false; - } - */ - } - return true; - } - - public static boolean validateGuestCidrList(String guestCidrList) { - for (String guestCidr : guestCidrList.split(";")) { - if (!validateGuestCidr(guestCidr)) { - return false; - } - } - return true; - } -} +// 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.utils.net; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.lang.reflect.Array; +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; +import org.apache.log4j.xml.DOMConfigurator; + +import com.cloud.utils.IteratorUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.script.Script; + +public class NetUtils { + protected final static Logger s_logger = Logger.getLogger(NetUtils.class); + public final static String HTTP_PORT = "80"; + public final static int VPN_PORT = 500; + public final static int VPN_NATT_PORT = 4500; + public final static int VPN_L2TP_PORT = 1701; + + public final static String UDP_PROTO = "udp"; + public final static String TCP_PROTO = "tcp"; + public final static String ANY_PROTO = "any"; + public final static String ICMP_PROTO = "icmp"; + public final static String ALL_PROTO = "all"; + + 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) { + return macAddress | 0x060000000000l | (((long) _rand.nextInt(32768) << 25) & 0x00fffe000000l); + } + + public static String getHostName() { + try { + InetAddress localAddr = InetAddress.getLocalHost(); + if (localAddr != null) { + return localAddr.getHostName(); + } + } catch (UnknownHostException e) { + s_logger.warn("UnknownHostException when trying to get host name. ", e); + } + return "localhost"; + } + + public static InetAddress getLocalInetAddress() { + try { + return InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + s_logger.warn("UnknownHostException in getLocalInetAddress().", e); + return null; + } + } + + public static String resolveToIp(String host) { + try { + InetAddress addr = InetAddress.getByName(host); + return ipFromInetAddress(addr); + } catch (UnknownHostException e) { + s_logger.warn("Unable to resolve " + host + " to IP due to UnknownHostException"); + return null; + } + } + + public static InetAddress[] getAllLocalInetAddresses() { + List addrList = new ArrayList(); + try { + for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { + if (ifc.isUp() && !ifc.isVirtual()) { + for (InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { + addrList.add(addr); + } + } + } + } catch (SocketException e) { + s_logger.warn("SocketException in getAllLocalInetAddresses().", e); + } + + InetAddress[] addrs = new InetAddress[addrList.size()]; + if (addrList.size() > 0) { + System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); + } + return addrs; + } + + public static String[] getLocalCidrs() { + String defaultHostIp = getDefaultHostIp(); + + List cidrList = new ArrayList(); + try { + for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { + if (ifc.isUp() && !ifc.isVirtual() && !ifc.isLoopback()) { + for (InterfaceAddress address : ifc.getInterfaceAddresses()) { + InetAddress addr = address.getAddress(); + int prefixLength = address.getNetworkPrefixLength(); + if (prefixLength < 32 && prefixLength > 0) { + String ip = ipFromInetAddress(addr); + if(ip.equalsIgnoreCase(defaultHostIp)) + cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength))); + } + } + } + } + } catch (SocketException e) { + s_logger.warn("UnknownHostException in getLocalCidrs().", e); + } + + return cidrList.toArray(new String[0]); + } + + private static boolean isWindows() { + String os = System.getProperty("os.name"); + if(os != null && os.startsWith("Windows")) + return true; + + return false; + } + + public static String getDefaultHostIp() { + if(isWindows()) { + Pattern pattern = Pattern.compile("\\s*0.0.0.0\\s*0.0.0.0\\s*(\\S*)\\s*(\\S*)\\s*"); + try { + Process result = Runtime.getRuntime().exec("route print -4"); + BufferedReader output = new BufferedReader + (new InputStreamReader(result.getInputStream())); + + String line = output.readLine(); + while(line != null){ + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + return matcher.group(2); + } + line = output.readLine(); + } + } catch( Exception e ) { + } + return null; + } else { + NetworkInterface nic = null; + String pubNic = getDefaultEthDevice(); + + if (pubNic == null) { + return null; + } + + try { + nic = NetworkInterface.getByName(pubNic); + } catch (final SocketException e) { + return null; + } + + String[] info = NetUtils.getNetworkParams(nic); + return info[0]; + } + } + + public static String getDefaultEthDevice() { + String defaultRoute = Script.runSimpleBashScript("/sbin/route | grep default"); + + if (defaultRoute == null) { + return null; + } + + String[] defaultRouteList = defaultRoute.split("\\s+"); + + if (defaultRouteList.length != 8) { + return null; + } + + return defaultRouteList[7]; + } + + public static InetAddress getFirstNonLoopbackLocalInetAddress() { + InetAddress[] addrs = getAllLocalInetAddresses(); + if (addrs != null) { + for (InetAddress addr : addrs) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Check local InetAddress : " + addr.toString() + ", total count :" + addrs.length); + } + + if (!addr.isLoopbackAddress()) { + return addr; + } + } + } + + s_logger.warn("Unable to determine a non-loopback address, local inet address count :" + addrs.length); + return null; + } + + public static InetAddress[] getInterfaceInetAddresses(String ifName) { + List addrList = new ArrayList(); + try { + for (NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { + if (ifc.isUp() && !ifc.isVirtual() && ifc.getName().equals(ifName)) { + for (InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { + addrList.add(addr); + } + } + } + } catch (SocketException e) { + s_logger.warn("SocketException in getAllLocalInetAddresses().", e); + } + + InetAddress[] addrs = new InetAddress[addrList.size()]; + if (addrList.size() > 0) { + System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); + } + return addrs; + } + + public static String getLocalIPString() { + InetAddress addr = getLocalInetAddress(); + if (addr != null) { + return ipFromInetAddress(addr); + } + + return new String("127.0.0.1"); + } + + public static String ipFromInetAddress(InetAddress addr) { + assert (addr != null); + + byte[] ipBytes = addr.getAddress(); + StringBuffer sb = new StringBuffer(); + sb.append(ipBytes[0] & 0xff).append("."); + sb.append(ipBytes[1] & 0xff).append("."); + sb.append(ipBytes[2] & 0xff).append("."); + sb.append(ipBytes[3] & 0xff); + + return sb.toString(); + } + + public static boolean isLocalAddress(InetAddress addr) { + InetAddress[] addrs = getAllLocalInetAddresses(); + + if (addrs != null) { + for (InetAddress self : addrs) { + if (self.equals(addr)) { + return true; + } + } + } + return false; + } + + public static boolean isLocalAddress(String strAddress) { + + InetAddress addr; + try { + addr = InetAddress.getByName(strAddress); + return isLocalAddress(addr); + } catch (UnknownHostException e) { + } + return false; + } + + public static String getMacAddress(InetAddress address) { + StringBuffer sb = new StringBuffer(); + Formatter formatter = new Formatter(sb); + try { + NetworkInterface ni = NetworkInterface.getByInetAddress(address); + byte[] mac = ni.getHardwareAddress(); + + for (int i = 0; i < mac.length; i++) { + formatter.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""); + } + } catch (SocketException e) { + s_logger.error("SocketException when trying to retrieve MAC address", e); + } + return sb.toString(); + } + + public static long getMacAddressAsLong(InetAddress address) { + long macAddressAsLong = 0; + try { + NetworkInterface ni = NetworkInterface.getByInetAddress(address); + byte[] mac = ni.getHardwareAddress(); + + for (int i = 0; i < mac.length; i++) { + macAddressAsLong |= ((long) (mac[i] & 0xff) << (mac.length - i - 1) * 8); + } + + } catch (SocketException e) { + s_logger.error("SocketException when trying to retrieve MAC address", e); + } + + return macAddressAsLong; + } + + public static boolean ipRangesOverlap(String startIp1, String endIp1, String startIp2, String endIp2) { + long startIp1Long = ip2Long(startIp1); + long endIp1Long = startIp1Long; + if (endIp1 != null) { + endIp1Long = ip2Long(endIp1); + } + long startIp2Long = ip2Long(startIp2); + long endIp2Long = startIp2Long; + if (endIp2 != null) { + endIp2Long = ip2Long(endIp2); + } + + if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) { + return true; + } else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) { + return true; + } else if (endIp1Long > startIp2Long && endIp1Long < endIp2Long) { + return true; + } else if (startIp2Long > startIp1Long && startIp2Long < endIp1Long) { + return true; + } else if (endIp2Long > startIp1Long && endIp2Long < endIp1Long) { + return true; + } else { + return false; + } + } + + public static long ip2Long(String ip) { + String[] tokens = ip.split("[.]"); + assert (tokens.length == 4); + long result = 0; + for (int i = 0; i < tokens.length; i++) { + try { + result = (result << 8) | Integer.parseInt(tokens[i]); + } catch (NumberFormatException e) { + throw new RuntimeException("Incorrect number", e); + } + } + + return result; + } + + public static String long2Ip(long ip) { + StringBuilder result = new StringBuilder(15); + result.append((ip >> 24 & 0xff)).append("."); + result.append((ip >> 16 & 0xff)).append("."); + result.append((ip >> 8 & 0xff)).append("."); + result.append(ip & 0xff); + + return result.toString(); + } + + public static long mac2Long(String macAddress) { + String[] tokens = macAddress.split(":"); + assert (tokens.length == 6); + long result = 0; + for (int i = 0; i < tokens.length; i++) { + result = result << 8; + result |= Integer.parseInt(tokens[i], 16); + } + return result; + } + + public static String[] getNicParams(String nicName) { + try { + NetworkInterface nic = NetworkInterface.getByName(nicName); + return getNetworkParams(nic); + } catch (SocketException e) { + return null; + } + } + + public static String[] getNetworkParams(NetworkInterface nic) { + List addrs = nic.getInterfaceAddresses(); + if (addrs == null || addrs.size() == 0) { + return null; + } + InterfaceAddress addr = null; + for (InterfaceAddress iaddr : addrs) { + InetAddress inet = iaddr.getAddress(); + if (!inet.isLinkLocalAddress() && !inet.isLoopbackAddress() && !inet.isMulticastAddress() && inet.getAddress().length == 4) { + addr = iaddr; + break; + } + } + if (addr == null) { + return null; + } + String[] result = new String[3]; + result[0] = addr.getAddress().getHostAddress(); + try { + byte[] mac = nic.getHardwareAddress(); + result[1] = byte2Mac(mac); + } catch (Exception e) { + } + + result[2] = prefix2Netmask(addr.getNetworkPrefixLength()); + return result; + } + + public static String prefix2Netmask(short prefix) { + long addr = 0; + for (int i = 0; i < prefix; i++) { + addr = addr | (1 << (31 - i)); + } + + return long2Ip(addr); + } + + public static String byte2Mac(byte[] m) { + StringBuilder result = new StringBuilder(17); + Formatter formatter = new Formatter(result); + formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", m[0], m[1], m[2], m[3], m[4], m[5]); + return result.toString(); + } + + public static String long2Mac(long macAddress) { + StringBuilder result = new StringBuilder(17); + Formatter formatter = new Formatter(result); + formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", (macAddress >> 40) & 0xff, (macAddress >> 32) & 0xff, (macAddress >> 24) & 0xff, (macAddress >> 16) & 0xff, (macAddress >> 8) & 0xff, + (macAddress & 0xff)); + + return result.toString(); + } + + public static boolean isValidPrivateIp(String ipAddress, String guestIPAddress) { + + InetAddress privIp = parseIpAddress(ipAddress); + if (privIp == null) { + return false; + } + if (!privIp.isSiteLocalAddress()) { + return false; + } + + String firstGuestOctet = "10"; + if (guestIPAddress != null && !guestIPAddress.isEmpty()) { + String[] guestIPList = guestIPAddress.split("\\."); + firstGuestOctet = guestIPList[0]; + } + + String[] ipList = ipAddress.split("\\."); + if (!ipList[0].equals(firstGuestOctet)) { + return false; + } + + return true; + } + + public static boolean isSiteLocalAddress(String ipAddress) { + if (ipAddress == null) { + return false; + } else { + InetAddress ip = parseIpAddress(ipAddress); + return ip.isSiteLocalAddress(); + } + } + + public static boolean validIpRange(String startIP, String endIP) { + if (endIP == null || endIP.isEmpty()) { + return true; + } + + long startIPLong = NetUtils.ip2Long(startIP); + long endIPLong = NetUtils.ip2Long(endIP); + return (startIPLong <= endIPLong); + } + + public static boolean isValidIp(final String ip) { + final String[] ipAsList = ip.split("\\."); + + // The IP address must have four octets + if (Array.getLength(ipAsList) != 4) { + return false; + } + + for (int i = 0; i < 4; i++) { + // Each octet must be an integer + final String octetString = ipAsList[i]; + int octet; + try { + octet = Integer.parseInt(octetString); + } catch (final Exception e) { + return false; + } + // Each octet must be between 0 and 255, inclusive + if (octet < 0 || octet > 255) { + return false; + } + + // Each octetString must have between 1 and 3 characters + if (octetString.length() < 1 || octetString.length() > 3) { + return false; + } + } + + // IP is good, return true + return true; + } + + public static boolean isValidCIDR(final String cidr) { + if (cidr == null || cidr.isEmpty()) { + return false; + } + String[] cidrPair = cidr.split("\\/"); + if (cidrPair.length != 2) { + return false; + } + String cidrAddress = cidrPair[0]; + String cidrSize = cidrPair[1]; + if (!isValidIp(cidrAddress)) { + return false; + } + int cidrSizeNum = -1; + + try { + cidrSizeNum = Integer.parseInt(cidrSize); + } catch (Exception e) { + return false; + } + + if (cidrSizeNum < 0 || cidrSizeNum > 32) { + return false; + } + + return true; + } + + public static boolean isValidNetmask(String netmask) { + if (!isValidIp(netmask)) { + return false; + } + + long ip = ip2Long(netmask); + int count = 0; + boolean finished = false; + for (int i = 31; i >= 0; i--) { + if (((ip >> i) & 0x1) == 0) { + finished = true; + } else { + if (finished) { + return false; + } + count += 1; + } + } + + if (count == 0) { + return false; + } + + return true; + } + + private static InetAddress parseIpAddress(String address) { + StringTokenizer st = new StringTokenizer(address, "."); + byte[] bytes = new byte[4]; + + if (st.countTokens() == 4) { + try { + for (int i = 0; i < 4; i++) { + bytes[i] = (byte) Integer.parseInt(st.nextToken()); + } + return InetAddress.getByAddress(address, bytes); + } catch (NumberFormatException nfe) { + return null; + } catch (UnknownHostException uhe) { + return null; + } + } + return null; + } + + public static String getCidrFromGatewayAndNetmask(String gatewayStr, String netmaskStr) { + long netmask = ip2Long(netmaskStr); + long gateway = ip2Long(gatewayStr); + long firstPart = gateway & netmask; + long size = getCidrSize(netmaskStr); + return long2Ip(firstPart) + "/" + size; + } + + public static String[] getIpRangeFromCidr(String cidr, long size) { + assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; + String[] result = new String[2]; + long ip = ip2Long(cidr); + long startNetMask = ip2Long(getCidrNetmask(size)); + long start = (ip & startNetMask) + 1; + long end = start; + + end = end >> (32 - size); + + end++; + end = (end << (32 - size)) - 2; + + result[0] = long2Ip(start); + result[1] = long2Ip(end); + + return result; + } + + public static Set getAllIpsFromCidr(String cidr, long size) { + assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; + Set result = new TreeSet(); + long ip = ip2Long(cidr); + long startNetMask = ip2Long(getCidrNetmask(size)); + long start = (ip & startNetMask) + 2; + long end = start; + + end = end >> (32 - size); + + end++; + end = (end << (32 - size)) - 2; + while (start <= end) { + result.add(start); + start++; + } + + return result; + } + + /** + * Given a cidr, this method returns an ip address within the range but + * is not in the avoid list. + * + * @param startIp ip that the cidr starts with + * @param size size of the cidr + * @param avoid set of ips to avoid + * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. + */ + public static long getRandomIpFromCidr(String startIp, int size, Set avoid) { + return getRandomIpFromCidr(ip2Long(startIp), size, avoid); + + } + + /** + * Given a cidr, this method returns an ip address within the range but + * is not in the avoid list. + * + * @param startIp ip that the cidr starts with + * @param size size of the cidr + * @param avoid set of ips to avoid + * @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one. + */ + public static long getRandomIpFromCidr(long cidr, int size, Set avoid) { + assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; + + long startNetMask = ip2Long(getCidrNetmask(size)); + long startIp = (cidr & startNetMask) + 2; + int range = 1 << (32 - size); + + if (avoid.size() > range) { + return -1; + } + + for (int i = 0; i < range; i++) { + int next = _rand.nextInt(range); + if (!avoid.contains(startIp + next)) { + return startIp + next; + } + } + + return -1; + } + + public static String getIpRangeStartIpFromCidr(String cidr, long size) { + long ip = ip2Long(cidr); + long startNetMask = ip2Long(getCidrNetmask(size)); + long start = (ip & startNetMask) + 1; + return long2Ip(start); + } + + public static String getIpRangeEndIpFromCidr(String cidr, long size) { + long ip = ip2Long(cidr); + long startNetMask = ip2Long(getCidrNetmask(size)); + long start = (ip & startNetMask) + 1; + long end = start; + end = end >> (32 - size); + + end++; + end = (end << (32 - size)) - 2; + return long2Ip(end); + } + + public static boolean sameSubnet(final String ip1, final String ip2, final String netmask) { + if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { + return true; + } + String subnet1 = NetUtils.getSubNet(ip1, netmask); + String subnet2 = NetUtils.getSubNet(ip2, netmask); + + return (subnet1.equals(subnet2)); + } + + public static boolean sameSubnetCIDR(final String ip1, final String ip2, final long cidrSize) { + if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) { + return true; + } + String subnet1 = NetUtils.getCidrSubNet(ip1, cidrSize); + String subnet2 = NetUtils.getCidrSubNet(ip2, cidrSize); + + return (subnet1.equals(subnet2)); + } + + public static String getSubNet(String ip, String netmask) { + long ipAddr = ip2Long(ip); + long subnet = ip2Long(netmask); + long result = ipAddr & subnet; + return long2Ip(result); + } + + public static String getBroadcastIp(String ip, String netmask) { + long ipAddr = ip2Long(ip); + long subnet = ip2Long(netmask); + long result = ipAddr | (~subnet); + return long2Ip(result); + } + + public static String getCidrSubNet(String ip, long cidrSize) { + long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize); + String netmask = NetUtils.long2Ip(numericNetmask); + return getSubNet(ip, netmask); + } + + public static String ipAndNetMaskToCidr(String ip, String netmask) { + long ipAddr = ip2Long(ip); + long subnet = ip2Long(netmask); + long result = ipAddr & subnet; + int bits = (subnet == 0) ? 0 : 1; + long subnet2 = subnet; + while ((subnet2 = (subnet2 >> 1) & subnet) != 0) { + bits++; + } + + return long2Ip(result) + "/" + Integer.toString(bits); + } + + public static String[] ipAndNetMaskToRange(String ip, String netmask) { + long ipAddr = ip2Long(ip); + long subnet = ip2Long(netmask); + long start = (ipAddr & subnet) + 1; + long end = start; + int bits = (subnet == 0) ? 0 : 1; + while ((subnet = (subnet >> 1) & subnet) != 0) { + bits++; + } + end = end >> (32 - bits); + + end++; + end = (end << (32 - bits)) - 2; + + return new String[] { long2Ip(start), long2Ip(end) }; + + } + + public static Pair getCidr(String cidr) { + String[] tokens = cidr.split("/"); + return new Pair(tokens[0], Integer.parseInt(tokens[1])); + } + + public static boolean isNetworkAWithinNetworkB(String cidrA, String cidrB) { + Long[] cidrALong = cidrToLong(cidrA); + Long[] cidrBLong = cidrToLong(cidrB); + if (cidrALong == null || cidrBLong == null) { + return false; + } + long shift = 32 - cidrBLong[1]; + return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift)); + } + + public static boolean isNetworksOverlap(String cidrA, String cidrB) { + Long[] cidrALong = cidrToLong(cidrA); + Long[] cidrBLong = cidrToLong(cidrB); + if (cidrALong == null || cidrBLong == null) { + return false; + } + long shift = 32 - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]); + return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift)); + } + + public static Long[] cidrToLong(String cidr) { + if (cidr == null || cidr.isEmpty()) { + return null; + } + String[] cidrPair = cidr.split("\\/"); + if (cidrPair.length != 2) { + return null; + } + String cidrAddress = cidrPair[0]; + String cidrSize = cidrPair[1]; + if (!isValidIp(cidrAddress)) { + return null; + } + int cidrSizeNum = -1; + + try { + cidrSizeNum = Integer.parseInt(cidrSize); + } catch (Exception e) { + return null; + } + long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); + long ipAddr = ip2Long(cidrAddress); + Long[] cidrlong = { ipAddr & numericNetmask, (long) cidrSizeNum }; + return cidrlong; + + } + + public static String getCidrSubNet(String cidr) { + if (cidr == null || cidr.isEmpty()) { + return null; + } + String[] cidrPair = cidr.split("\\/"); + if (cidrPair.length != 2) { + return null; + } + String cidrAddress = cidrPair[0]; + String cidrSize = cidrPair[1]; + if (!isValidIp(cidrAddress)) { + return null; + } + int cidrSizeNum = -1; + + try { + cidrSizeNum = Integer.parseInt(cidrSize); + } catch (Exception e) { + return null; + } + long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); + String netmask = NetUtils.long2Ip(numericNetmask); + return getSubNet(cidrAddress, netmask); + } + + public static String getCidrBroadcastIp(String cidr) { + if (cidr == null || cidr.isEmpty()) { + return null; + } + String[] cidrPair = cidr.split("\\/"); + if (cidrPair.length != 2) { + return null; + } + String cidrAddress = cidrPair[0]; + String cidrSize = cidrPair[1]; + if (!isValidIp(cidrAddress)) { + return null; + } + int cidrSizeNum = -1; + + try { + cidrSizeNum = Integer.parseInt(cidrSize); + } catch (Exception e) { + return null; + } + long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum); + String netmask = NetUtils.long2Ip(numericNetmask); + return getBroadcastIp(cidrAddress, netmask); + } + + public static String getCidrNetmask(long cidrSize) { + long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize); + return long2Ip(numericNetmask); + } + + public static String getCidrNetmask(String cidr) { + String[] cidrPair = cidr.split("\\/"); + long guestCidrSize = Long.parseLong(cidrPair[1]); + return getCidrNetmask(guestCidrSize); + } + + public static String cidr2Netmask(String cidr) { + String[] tokens = cidr.split("\\/"); + return getCidrNetmask(Integer.parseInt(tokens[1])); + } + + public static long getCidrSize(String netmask) { + long ip = ip2Long(netmask); + int count = 0; + for (int i = 0; i < 32; i++) { + if (((ip >> i) & 0x1) == 0) { + count++; + } else { + break; + } + } + + return 32 - count; + } + + public static boolean isValidPort(String p) { + try { + int port = Integer.parseInt(p); + return !(port > 65535 || port < 1); + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isValidPort(int p) { + return !(p > 65535 || p < 1); + } + + public static boolean isValidLBPort(String p) { + try { + int port = Integer.parseInt(p); + return !(port > 65535 || port < 1); + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isValidProto(String p) { + String proto = p.toLowerCase(); + return (proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO)); + } + + public static boolean isValidSecurityGroupProto(String p) { + String proto = p.toLowerCase(); + return (proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO) || proto.equals(ALL_PROTO)); + } + + public static boolean isValidAlgorithm(String p) { + String algo = p.toLowerCase(); + 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"; + } + + public static String getLinkLocalGateway() { + return "169.254.0.1"; + } + + public static String getLinkLocalCIDR() { + return "169.254.0.0/16"; + } + + public static String[] getLinkLocalIPRange(int size) { + if (size > 16 || size <= 0) { + return null; + } + /* reserve gateway */ + String[] range = getIpRangeFromCidr(getLinkLocalGateway(), 32 - size); + + if (range[0].equalsIgnoreCase(getLinkLocalGateway())) { + /* remove the gateway */ + long ip = ip2Long(range[0]); + ip += 1; + range[0] = long2Ip(ip); + } + return range; + } + + public static String getLinkLocalIpEnd() { + String[] cidrPair = getLinkLocalCIDR().split("\\/"); + String cidr = cidrPair[0]; + + return getIpRangeEndIpFromCidr(cidr, 32 - Long.parseLong(cidrPair[1])); + } + + public static String portRangeToString(int portRange[]) { + return Integer.toString(portRange[0]) + ":" + Integer.toString(portRange[1]); + } + + // test only + private static void configLog4j() { + URL configUrl = System.class.getResource("/conf/log4j-cloud.xml"); + if (configUrl != null) { + System.out.println("Configure log4j using log4j-cloud.xml"); + + try { + File file = new File(configUrl.toURI()); + + System.out.println("Log4j configuration from : " + file.getAbsolutePath()); + DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); + } catch (URISyntaxException e) { + System.out.println("Unable to convert log4j configuration Url to URI"); + } + // DOMConfigurator.configure(configUrl); + } else { + System.out.println("Configure log4j with default properties"); + } + } + + + public static boolean verifyDomainNameLabel(String hostName, boolean isHostName) { + // must be between 1 and 63 characters long and may contain only the ASCII letters 'a' through 'z' (in a + // case-insensitive manner), + // the digits '0' through '9', and the hyphen ('-'). + // Can not start with a hyphen and digit, and must not end with a hyphen + // If it's a host name, don't allow to start with digit + + if (hostName.length() > 63 || hostName.length() < 1) { + s_logger.warn("Domain name label must be between 1 and 63 characters long"); + return false; + } else if (!hostName.toLowerCase().matches("[a-z0-9-]*")) { + s_logger.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)"); + return false; + } else if (hostName.startsWith("-") || hostName.endsWith("-")) { + s_logger.warn("Domain name label can not start with a hyphen and digit, and must not end with a hyphen"); + return false; + } else if (isHostName && hostName.matches("^[0-9-].*")) { + s_logger.warn("Host name can't start with digit"); + return false; + } + + return true; + } + + public static boolean verifyDomainName(String domainName) { + // don't allow domain name length to exceed 190 chars (190 + 63 (max host name length) = 253 = max domainName length + if (domainName.length() < 1 || domainName.length() > 190) { + s_logger.trace("Domain name must be between 1 and 190 characters long"); + return false; + } + + if (domainName.startsWith(".") || domainName.endsWith(".")) { + s_logger.trace("Domain name can't start or end with ."); + return false; + } + + String[] domainNameLabels = domainName.split("\\."); + + for (int i = 0; i < domainNameLabels.length; i++) { + if (!verifyDomainNameLabel(domainNameLabels[i], false)) { + s_logger.warn("Domain name label " + domainNameLabels[i] + " is incorrect"); + return false; + } + } + + return true; + } + + public static String getDhcpRange(String cidr) { + String[] splitResult = cidr.split("\\/"); + long size = Long.valueOf(splitResult[1]); + return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size); + } + + public static boolean validateGuestCidr(String cidr) { + // RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the + // following three blocks of the IP address space for private internets: + // 10.0.0.0 - 10.255.255.255 (10/8 prefix) + // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) + // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) + + String cidr1 = "10.0.0.0/8"; + String cidr2 = "172.16.0.0/12"; + String cidr3 = "192.168.0.0/16"; + + if (!isValidCIDR(cidr)) { + s_logger.warn("Cidr " + cidr + " is not valid"); + return false; + } + + if (isNetworkAWithinNetworkB(cidr, cidr1) || isNetworkAWithinNetworkB(cidr, cidr2) || isNetworkAWithinNetworkB(cidr, cidr3)) { + return true; + } else { + s_logger.warn("cidr " + cidr + " is not RFC 1918 compliant"); + return false; + } + } + + public static boolean verifyInstanceName(String instanceName) { + //instance name for cloudstack vms shouldn't contain - and spaces + if (instanceName.contains("-") || instanceName.contains(" ") || instanceName.contains("+")) { + s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char"); + return false; + } + + return true; + } + + public static boolean isValidS2SVpnPolicy(String policys) { + if (policys == null || policys.isEmpty()) { + return false; + } + for (String policy : policys.split(",")) { + if (policy.isEmpty()) { + return false; + } + //String cipherHash = policy.split(";")[0]; + String cipherHash = policy; + if (cipherHash.isEmpty()) { + return false; + } + String[] list = cipherHash.split("-"); + if (list.length != 2) { + return false; + } + String cipher = list[0]; + String hash = list[1]; + if (!cipher.matches("3des|aes|aes128|aes256")) { + return false; + } + if (!hash.matches("md5|sha1")) { + return false; + } + /* Disable pfsGroup support, see CS-15511 + String pfsGroup = null; + if (!policy.equals(cipherHash)) { + pfsGroup = policy.split(";")[1]; + } + if (pfsGroup != null && !pfsGroup.matches("modp1024|modp1536")) { + return false; + } + */ + } + return true; + } + + public static boolean validateGuestCidrList(String guestCidrList) { + for (String guestCidr : guestCidrList.split(";")) { + if (!validateGuestCidr(guestCidr)) { + return false; + } + } + return true; + } +}