diff --git a/.gitignore b/.gitignore index b2a905641ba..15f7f91c864 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ tools/cli/build/ *.iso *.tar.gz *.tgz +target-eclipse awsapi/modules/* !.gitignore .classpath diff --git a/LICENSE b/LICENSE index 5e29e2b12bc..00afdb41fd6 100644 --- a/LICENSE +++ b/LICENSE @@ -370,7 +370,7 @@ Within the scripts/vm/hypervisor/xenserver directory from OpenStack, LLC http://www.openstack.org swift -Within the tools/appliance/definitions/systemvmtemplate directory +Within the tools/appliance/definitions/systemvmtemplate and tools/appliance/definitions/systemvmtemplate64 directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) Copyright (c) 2010-2012 Patrick Debois diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java index 9cb3c3db3ff..2af08e9bf21 100644 --- a/agent/src/com/cloud/agent/AgentShell.java +++ b/agent/src/com/cloud/agent/AgentShell.java @@ -38,10 +38,13 @@ import java.util.UUID; import javax.naming.ConfigurationException; +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.xml.DOMConfigurator; import com.cloud.agent.Agent.ExitStatus; import com.cloud.agent.dao.StorageComponent; @@ -377,6 +380,18 @@ public class AgentShell implements IAgentShell { public void init(String[] args) throws ConfigurationException { + // PropertiesUtil is used both in management server and agent packages, + // it searches path under class path and common J2EE containers + // For KVM agent, do it specially here + + File file = new File("/etc/cloudstack/agent/log4j-cloud.xml"); + if(file == null || !file.exists()) { + file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); + } + DOMConfigurator.configureAndWatch(file.getAbsolutePath()); + + s_logger.info("Agent started"); + final Class c = this.getClass(); _version = c.getPackage().getImplementationVersion(); if (_version == null) { diff --git a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java index a0ac8d7ad71..cac686dc0ce 100644 --- a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java +++ b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java @@ -35,6 +35,7 @@ public class BackupSnapshotCommand extends SnapshotCommand { private SwiftTO swift; private S3TO s3; StorageFilerTO pool; + private Long secHostId; protected BackupSnapshotCommand() { @@ -49,12 +50,14 @@ public class BackupSnapshotCommand extends SnapshotCommand { * @param firstBackupUuid This is the backup of the first ever snapshot taken by the volume. * @param isFirstSnapshotOfRootVolume true if this is the first snapshot of a root volume. Set the parent of the backup to null. * @param isVolumeInactive True if the volume belongs to a VM that is not running or is detached. + * @param secHostId This is the Id of the secondary storage. */ public BackupSnapshotCommand(String secondaryStoragePoolURL, Long dcId, Long accountId, Long volumeId, Long snapshotId, + Long secHostId, String volumePath, StoragePool pool, String snapshotUuid, @@ -71,6 +74,7 @@ public class BackupSnapshotCommand extends SnapshotCommand { this.prevBackupUuid = prevBackupUuid; this.isVolumeInactive = isVolumeInactive; this.vmName = vmName; + this.secHostId = secHostId; setVolumePath(volumePath); setWait(wait); } @@ -111,4 +115,7 @@ public class BackupSnapshotCommand extends SnapshotCommand { return snapshotId; } + public Long getSecHostId() { + return secHostId; + } } diff --git a/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java index affad1f9b9d..4336b4c32b4 100644 --- a/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java +++ b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java @@ -18,6 +18,7 @@ package com.cloud.agent.api; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.List; import java.util.zip.DeflaterOutputStream; import org.apache.commons.codec.binary.Base64; @@ -80,6 +81,7 @@ public class SecurityGroupRulesCmd extends Command { Long msId; IpPortAndProto [] ingressRuleSet; IpPortAndProto [] egressRuleSet; + private List secIps; public SecurityGroupRulesCmd() { super(); @@ -103,6 +105,23 @@ public class SecurityGroupRulesCmd extends Command { } + public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet, IpPortAndProto[] egressRuleSet, List secIps) { + super(); + this.guestIp = guestIp; + this.vmName = vmName; + this.ingressRuleSet = ingressRuleSet; + this.egressRuleSet = egressRuleSet; + this.guestMac = guestMac; + this.signature = signature; + this.seqNum = seqNum; + this.vmId = vmId; + if (signature == null) { + String stringified = stringifyRules(); + this.signature = DigestUtils.md5Hex(stringified); + } + this.secIps = secIps; + } + @Override public boolean executeInSequence() { return true; @@ -131,6 +150,10 @@ public class SecurityGroupRulesCmd extends Command { return guestIp; } + public List getSecIps() { + return secIps; + } + public String getVmName() { return vmName; @@ -165,6 +188,20 @@ public class SecurityGroupRulesCmd extends Command { } + public String getSecIpsString() { + StringBuilder sb = new StringBuilder(); + List ips = getSecIps(); + if (ips == null) { + return "0:"; + } else { + for (String ip : ips) { + sb.append(ip).append(":"); + } + } + return sb.toString(); + } + + public String stringifyCompressedRules() { StringBuilder ruleBuilder = new StringBuilder(); for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) { diff --git a/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java b/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java new file mode 100644 index 00000000000..dfca4ab5908 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java @@ -0,0 +1,42 @@ +// 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.agent.api.routing; + +import java.util.List; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; + +/** + * LoadBalancerConfigCommand sends the load balancer configuration + */ +public class HealthCheckLBConfigAnswer extends Answer { + List loadBalancers; + + protected HealthCheckLBConfigAnswer() { + } + + public HealthCheckLBConfigAnswer(List loadBalancers) { + this.loadBalancers = loadBalancers; + } + + public List getLoadBalancers() { + return loadBalancers; + } + +} diff --git a/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java b/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java new file mode 100644 index 00000000000..f705f6c9707 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java @@ -0,0 +1,39 @@ +// 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.agent.api.routing; + +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; + +/** + * LoadBalancerConfigCommand sends the load balancer configuration + */ +public class HealthCheckLBConfigCommand extends NetworkElementCommand { + LoadBalancerTO[] loadBalancers; + + protected HealthCheckLBConfigCommand() { + } + + public HealthCheckLBConfigCommand(LoadBalancerTO[] loadBalancers) { + this.loadBalancers = loadBalancers; + } + + public LoadBalancerTO[] getLoadBalancers() { + return loadBalancers; + } + +} diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index 2d166ea1e1e..df2f8a87490 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -31,6 +31,7 @@ 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.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.utils.Pair; @@ -46,8 +47,10 @@ public class LoadBalancerTO { boolean inline; DestinationTO[] destinations; private StickinessPolicyTO[] stickinessPolicies; + private HealthCheckPolicyTO[] healthCheckPolicies; private AutoScaleVmGroupTO autoScaleVmGroupTO; final static int MAX_STICKINESS_POLICIES = 1; + final static int MAX_HEALTHCHECK_POLICIES = 1; public LoadBalancerTO(String uuid, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline, List destinations) { if (destinations == null) { // for autoscaleconfig destinations will be null; @@ -69,23 +72,52 @@ public class LoadBalancerTO { } } - public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline, List arg_destinations, List stickinessPolicies) { + public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, + boolean alreadyAdded, boolean inline, List arg_destinations, + List stickinessPolicies) { + + this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, arg_destinations, + stickinessPolicies, null); + } + + public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, + boolean alreadyAdded, boolean inline, List arg_destinations, + List stickinessPolicies, List healthCheckPolicies) { this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, arg_destinations); this.stickinessPolicies = null; + this.healthCheckPolicies = 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()); + this.stickinessPolicies[index] = new StickinessPolicyTO(stickinesspolicy.getMethodName(), + stickinesspolicy.getParams()); index++; - if (index == MAX_STICKINESS_POLICIES) break; - } + if (index == MAX_STICKINESS_POLICIES) + break; } - if (index == 0) this.stickinessPolicies = null; } + if (index == 0) + this.stickinessPolicies = null; + } + + if (healthCheckPolicies != null && healthCheckPolicies.size() > 0) { + this.healthCheckPolicies = new HealthCheckPolicyTO[MAX_HEALTHCHECK_POLICIES]; + int index = 0; + for (LbHealthCheckPolicy hcp : healthCheckPolicies) { + this.healthCheckPolicies[0] = new HealthCheckPolicyTO(hcp.getpingpath(), hcp.getDescription(), + hcp.getResponseTime(), hcp.getHealthcheckInterval(), hcp.getHealthcheckThresshold(), + hcp.getUnhealthThresshold(), hcp.isRevoked()); + index++; + if (index == MAX_HEALTHCHECK_POLICIES) + break; } + if (index == 0) + this.healthCheckPolicies = null; + } + } protected LoadBalancerTO() { } @@ -126,6 +158,10 @@ public class LoadBalancerTO { return stickinessPolicies; } + public HealthCheckPolicyTO[] getHealthCheckPolicies() { + return healthCheckPolicies; + } + public DestinationTO[] getDestinations() { return destinations; } @@ -158,6 +194,65 @@ public class LoadBalancerTO { this._methodName = methodName; this._paramsList = paramsList; } + } + + public static class HealthCheckPolicyTO { + private String pingPath; + private String description; + private int responseTime; + private int healthcheckInterval; + private int healthcheckThresshold; + private int unhealthThresshold; + private boolean revoke = false; + + public HealthCheckPolicyTO(String pingPath, String description, int responseTime, int healthcheckInterval, + int healthcheckThresshold, int unhealthThresshold, boolean revoke) { + + this.description = description; + this.pingPath = pingPath; + this.responseTime = responseTime; + this.healthcheckInterval = healthcheckInterval; + this.healthcheckThresshold = healthcheckThresshold; + this.unhealthThresshold = unhealthThresshold; + this.revoke = revoke; + } + + public HealthCheckPolicyTO() { + + } + + public String getpingPath() { + return pingPath; + } + + public String getDescription() { + return description; + } + + public int getResponseTime() { + return responseTime; + } + + public int getHealthcheckInterval() { + return healthcheckInterval; + } + + public int getHealthcheckThresshold() { + return healthcheckThresshold; + } + + public int getUnhealthThresshold() { + return unhealthThresshold; + } + + public void setRevoke(boolean revoke) { + this.revoke = revoke; + } + + public boolean isRevoked() { + return revoke; + } + } public static class DestinationTO { @@ -165,6 +260,7 @@ public class LoadBalancerTO { int destPort; boolean revoked; boolean alreadyAdded; + String monitorState; public DestinationTO(String destIp, int destPort, boolean revoked, boolean alreadyAdded) { this.destIp = destIp; this.destPort = destPort; @@ -190,6 +286,14 @@ public class LoadBalancerTO { public boolean isAlreadyAdded() { return alreadyAdded; } + + public void setMonitorState(String state) { + this.monitorState = state; + } + + public String getMonitorState() { + return monitorState; + } } public static class CounterTO implements Serializable { private final String name; diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java index aa2aa19cc19..ccebe115f97 100644 --- a/api/src/com/cloud/agent/api/to/NicTO.java +++ b/api/src/com/cloud/agent/api/to/NicTO.java @@ -16,12 +16,15 @@ // under the License. package com.cloud.agent.api.to; +import java.util.List; + public class NicTO extends NetworkTO { int deviceId; Integer networkRateMbps; Integer networkRateMulticastMbps; boolean defaultNic; String uuid; + List nicSecIps; public NicTO() { super(); @@ -69,4 +72,12 @@ public class NicTO extends NetworkTO { public String toString() { return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString(); } + + public void setNicSecIps(List secIps) { + this.nicSecIps = secIps; + } + + public List getNicSecIps() { + return nicSecIps; + } } diff --git a/api/src/com/cloud/domain/Domain.java b/api/src/com/cloud/domain/Domain.java index f8277c2cd28..befed073072 100644 --- a/api/src/com/cloud/domain/Domain.java +++ b/api/src/com/cloud/domain/Domain.java @@ -62,5 +62,4 @@ public interface Domain extends OwnedBy, Identity, InternalIdentity { public String getUuid(); - int getRegionId(); } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 8f7c92580a0..6fdd28cf165 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -110,6 +110,8 @@ public class EventTypes { 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_LB_HEALTHCHECKPOLICY_CREATE = "LB.HEALTHCHECKPOLICY.CREATE"; + public static final String EVENT_LB_HEALTHCHECKPOLICY_DELETE = "LB.HEALTHCHECKPOLICY.DELETE"; public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE"; // Global Load Balancer rules diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index efed5cd4f8b..89dac686d0f 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -188,6 +188,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Capability InlineMode = new Capability("InlineMode"); public static final Capability SupportedTrafficDirection = new Capability("SupportedTrafficDirection"); public static final Capability SupportedEgressProtocols = new Capability("SupportedEgressProtocols"); + public static final Capability HealthCheckPolicy = new Capability("HealthCheckPolicy"); private String name; diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 9731a61667d..60e1f7fd164 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -257,4 +257,6 @@ public interface NetworkModel { void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException; void checkRequestedIpAddresses(long networkId, String ip4, String ip6) throws InvalidParameterValueException; + + String getStartIpv6Address(long id); } \ No newline at end of file diff --git a/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java b/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java index 879ea0ed663..cb3155f9c05 100644 --- a/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java +++ b/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java @@ -18,6 +18,7 @@ package com.cloud.network.element; import java.util.List; +import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule; @@ -25,6 +26,7 @@ import com.cloud.network.lb.LoadBalancingRule; public interface LoadBalancingServiceProvider extends NetworkElement, IpDeployingRequester { /** * Apply rules + * * @param network * @param rules * @return @@ -34,10 +36,14 @@ public interface LoadBalancingServiceProvider extends NetworkElement, IpDeployin /** * Validate rules + * * @param network * @param rule - * @return true/false. true should be return if there are no validations. false should be return if any oneof the validation fails. + * @return true/false. true should be return if there are no validations. + *false should be return if any oneof the validation fails. * @throws */ boolean validateLBRule(Network network, LoadBalancingRule rule); + + List updateHealthChecks(Network network, List lbrules); } diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java index fb1d988a4de..84526c5ea45 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRule.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -32,11 +32,14 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { private List destinations; private List stickinessPolicies; private LbAutoScaleVmGroup autoScaleVmGroup; + private List healthCheckPolicies; - public LoadBalancingRule(LoadBalancer lb, List destinations, List stickinessPolicies) { + public LoadBalancingRule(LoadBalancer lb, List destinations, + List stickinessPolicies, List healthCheckPolicies) { this.lb = lb; this.destinations = destinations; this.stickinessPolicies = stickinessPolicies; + this.healthCheckPolicies = healthCheckPolicies; } @Override @@ -136,11 +139,17 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { return stickinessPolicies; } + public List getHealthCheckPolicies() { + return healthCheckPolicies; + } public interface Destination { String getIpAddress(); + int getDestinationPortStart(); + int getDestinationPortEnd(); + boolean isRevoked(); } @@ -174,6 +183,64 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { } } + public static class LbHealthCheckPolicy { + private String pingpath; + private String description; + private int responseTime; + private int healthcheckInterval; + private int healthcheckThresshold; + private int unhealthThresshold; + private boolean _revoke; + + public LbHealthCheckPolicy(String pingpath, String description, int responseTime, int healthcheckInterval, + int healthcheckThresshold, int unhealthThresshold) { + this(pingpath, description, responseTime, healthcheckInterval, healthcheckThresshold, unhealthThresshold, false); + } + + public LbHealthCheckPolicy(String pingpath, String description, int responseTime, int healthcheckInterval, + int healthcheckThresshold, int unhealthThresshold, boolean revoke) { + this.pingpath = pingpath; + this.description = description; + this.responseTime = responseTime; + this.healthcheckInterval = healthcheckInterval; + this.healthcheckThresshold = healthcheckThresshold; + this.unhealthThresshold = unhealthThresshold; + this._revoke = revoke; + } + + public LbHealthCheckPolicy() { + } + + public String getpingpath() { + return pingpath; + } + + public String getDescription() { + return description; + } + + public int getResponseTime() { + return responseTime; + } + + public int getHealthcheckInterval() { + return healthcheckInterval; + } + + public int getHealthcheckThresshold() { + return healthcheckThresshold; + } + + public int getUnhealthThresshold() { + return unhealthThresshold; + } + + public boolean isRevoked() { + return _revoke; + } + + } + public static class LbDestination implements Destination { private int portStart; private int portEnd; @@ -191,10 +258,12 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { public String getIpAddress() { return ip; } + @Override public int getDestinationPortStart() { return portStart; } + @Override public int getDestinationPortEnd() { return portEnd; @@ -230,15 +299,16 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { return null; } - @Override public TrafficType getTrafficType() { return null; } + @Override public FirewallRuleType getType() { return FirewallRuleType.User; } + public LbAutoScaleVmGroup getAutoScaleVmGroup() { return autoScaleVmGroup; } @@ -274,8 +344,7 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { private final AutoScalePolicy policy; private boolean revoked; - public LbAutoScalePolicy(AutoScalePolicy policy, List conditions) - { + public LbAutoScalePolicy(AutoScalePolicy policy, List conditions) { this.policy = policy; this.conditions = conditions; } @@ -309,7 +378,9 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { private final String networkId; private final String vmName; - public LbAutoScaleVmProfile(AutoScaleVmProfile profile, String autoScaleUserApiKey, String autoScaleUserSecretKey, String csUrl, String zoneId, String domainId, String serviceOfferingId, String templateId, String vmName, String networkId) { + public LbAutoScaleVmProfile(AutoScaleVmProfile profile, String autoScaleUserApiKey, + String autoScaleUserSecretKey, String csUrl, String zoneId, String domainId, String serviceOfferingId, + String templateId, String vmName, String networkId) { this.profile = profile; this.autoScaleUserApiKey = autoScaleUserApiKey; this.autoScaleUserSecretKey = autoScaleUserSecretKey; @@ -369,7 +440,8 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { private final LbAutoScaleVmProfile profile; private final String currentState; - public LbAutoScaleVmGroup(AutoScaleVmGroup vmGroup, List policies, LbAutoScaleVmProfile profile, String currentState) { + public LbAutoScaleVmGroup(AutoScaleVmGroup vmGroup, List policies, + LbAutoScaleVmProfile profile, String currentState) { this.vmGroup = vmGroup; this.policies = policies; this.profile = profile; diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index 3743aae4bf8..ed39bedaa6f 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -18,8 +18,10 @@ package com.cloud.network.lb; import java.util.List; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; @@ -28,6 +30,8 @@ import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRul import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.StickinessPolicy; import com.cloud.uservm.UserVm; @@ -66,6 +70,22 @@ public interface LoadBalancingRulesService { public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws ResourceUnavailableException; boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply); + + /** + * Create a healthcheck policy to a load balancer from the given healthcheck + * 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 HealthCheckPolicy createLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd); + public boolean applyLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) throws ResourceUnavailableException; + boolean deleteLBHealthCheckPolicy(long healthCheckPolicyId, boolean apply); + /** * Assign a virtual machine, or list of virtual machines, to a load balancer. */ @@ -104,8 +124,18 @@ public interface LoadBalancingRulesService { */ List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd); + /** + * List healthcheck policies based on the given criteria + * + * @param cmd + * the command specifies the load balancing rule id. + * @return list of healthcheck policies that match the criteria. + */ + + List searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd cmd); + List listByNetworkId(long networkId); LoadBalancer findById(long LoadBalancer); - + public void updateLBHealthChecks() throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/rules/HealthCheckPolicy.java b/api/src/com/cloud/network/rules/HealthCheckPolicy.java new file mode 100644 index 00000000000..96bb28204a2 --- /dev/null +++ b/api/src/com/cloud/network/rules/HealthCheckPolicy.java @@ -0,0 +1,45 @@ +// 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.rules; + +import java.util.List; + +import com.cloud.utils.Pair; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +/** + */ +public interface HealthCheckPolicy extends InternalIdentity, Identity { + + public long getLoadBalancerId(); + + public String getpingpath(); + + public String getDescription(); + + public int getResponseTime(); + + public int getHealthcheckInterval(); + + public int getHealthcheckThresshold(); + + public int getUnhealthThresshold(); + + public boolean isRevoke(); + +} diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/com/cloud/network/security/SecurityGroupService.java index c6480323780..397de1ccb46 100644 --- a/api/src/com/cloud/network/security/SecurityGroupService.java +++ b/api/src/com/cloud/network/security/SecurityGroupService.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupC import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd; import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd; +import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -45,5 +46,6 @@ public interface SecurityGroupService { public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd); public List authorizeSecurityGroupEgress(AuthorizeSecurityGroupEgressCmd cmd); - + public boolean securityGroupRulesForVmSecIp(Long nicId, Long networkId, + String secondaryIp, boolean ruleAction); } diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java index cdfe8d38dc5..cedc793c197 100755 --- a/api/src/com/cloud/template/VirtualMachineTemplate.java +++ b/api/src/com/cloud/template/VirtualMachineTemplate.java @@ -37,6 +37,7 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte featured, // returns templates that have been marked as featured and public self, // returns templates that have been registered or created by the calling user selfexecutable, // same as self, but only returns templates that are ready to be deployed with + shared, // including templates that have been granted to the calling user by another user sharedexecutable, // ready templates that have been granted to the calling user by another user executable, // templates that are owned by the calling user, or public templates, that can be used to deploy a community, // returns templates that have been marked as public but not featured diff --git a/api/src/com/cloud/user/Account.java b/api/src/com/cloud/user/Account.java index e65e017c266..5d32fb23253 100755 --- a/api/src/com/cloud/user/Account.java +++ b/api/src/com/cloud/user/Account.java @@ -63,7 +63,5 @@ public interface Account extends ControlledEntity, InternalIdentity, Identity { public Long getDefaultZoneId(); - public int getRegionId(); - public String getUuid(); } diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index f9c6ddb38ef..903eebc5bf8 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -62,7 +62,7 @@ public interface AccountService { * @return the user if created successfully, null otherwise */ UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, String networkDomain, - Map details); + Map details, String accountUUID, String userUUID); /** * Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses @@ -77,7 +77,7 @@ public interface AccountService { User getSystemUser(); - User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId); + User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID); boolean isAdmin(short accountType); diff --git a/api/src/com/cloud/user/DomainService.java b/api/src/com/cloud/user/DomainService.java index 1f030196420..7c302e377fd 100644 --- a/api/src/com/cloud/user/DomainService.java +++ b/api/src/com/cloud/user/DomainService.java @@ -27,7 +27,7 @@ import com.cloud.utils.Pair; public interface DomainService { - Domain createDomain(String name, Long parentId, String networkDomain); + Domain createDomain(String name, Long parentId, String networkDomain, String domainUUID); Domain getDomain(long id); diff --git a/api/src/com/cloud/user/User.java b/api/src/com/cloud/user/User.java index 7d80c435e3d..3742c7bf3e2 100644 --- a/api/src/com/cloud/user/User.java +++ b/api/src/com/cloud/user/User.java @@ -73,5 +73,4 @@ public interface User extends OwnedBy, InternalIdentity { boolean isRegistered(); - public int getRegionId(); } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index ea89eda89d2..9d6b221ca21 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -356,8 +356,9 @@ public interface UserVmService { * @param cmd * - the command specifying vmId and new serviceOfferingId * @return the vm + * @throws ResourceAllocationException */ - UserVm upgradeVirtualMachine(UpgradeVMCmd cmd); + UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException; UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 0436906bac4..c518830c92c 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -468,6 +468,11 @@ public class ApiConstants { public static final String UCS_BLADE_ID = "bladeid"; public static final String VM_GUEST_IP = "vmguestip"; public static final String OLDER_THAN = "olderthan"; + public static final String HEALTHCHECK_RESPONSE_TIMEOUT = "responsetimeout"; + public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime"; + public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold"; + public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold"; + public static final String HEALTHCHECK_PINGPATH = "pingpath"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java.orig b/api/src/org/apache/cloudstack/api/ApiConstants.java.orig deleted file mode 100644 index 3801506ffaa..00000000000 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java.orig +++ /dev/null @@ -1,468 +0,0 @@ -// 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 org.apache.cloudstack.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 IP6_CIDR = "ip6cidr"; - 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_IPV6 = "endipv6"; - 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 IP6_GATEWAY = "ip6gateway"; - 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 IP6_ADDRESS = "ip6address"; - public static final String IP_ADDRESS_ID = "ipaddressid"; - public static final String IS_ASYNC = "isasync"; - 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_PERSISTENT = "ispersistent"; - 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 LENGTH = "length"; - 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 PARAMS = "params"; - 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 POD_IDS = "podids"; - 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 RESPONSE = "response"; - 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 SINCE = "since"; - 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_IPV6 = "startipv6"; - 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 ISO_ID = "isoid"; - 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 NIC_ID = "nicid"; - 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 LOCAL_STORAGE_ENABLED = "localstorageenabled"; - 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 ASSOCIATED_NETWORK_NAME = "associatednetworkname"; - 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 REQUIRED = "required"; - 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 ADD_VSM_FLAG = "addvsmflag"; - public static final String END_POINT = "endpoint"; - public static final String REGION_ID = "regionid"; - public static final String IS_PROPAGATE = "ispropagate"; - 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 GATEWAY_ID = "gatewayid"; - public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy"; - public static final String RESOURCE_IDS = "resourceids"; - public static final String RESOURCE_ID = "resourceid"; - public static final String CUSTOMER = "customer"; - 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 IKE_LIFETIME = "ikelifetime"; - public static final String ESP_LIFETIME = "esplifetime"; - public static final String DPD = "dpd"; - public static final String FOR_VPC = "forvpc"; - public static final String SHRINK_OK = "shrinkok"; - public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid"; - public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid"; - public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename"; - public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid"; - public static final String S3_ACCESS_KEY = "accesskey"; - public static final String S3_SECRET_KEY = "secretkey"; - public static final String S3_END_POINT = "endpoint"; - public static final String S3_BUCKET_NAME = "bucket"; - public static final String S3_HTTPS_FLAG = "usehttps"; - public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout"; - public static final String S3_MAX_ERROR_RETRY = "maxerrorretry"; - public static final String S3_SOCKET_TIMEOUT = "sockettimeout"; - public static final String INCL_ZONES = "includezones"; - public static final String EXCL_ZONES = "excludezones"; - 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 OTHER_DEPLOY_PARAMS = "otherdeployparams"; - public static final String MIN_MEMBERS = "minmembers"; - public static final String MAX_MEMBERS = "maxmembers"; - public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod"; - public static final String VMPROFILE_ID = "vmprofileid"; - public static final String VMGROUP_ID = "vmgroupid"; - public static final String CS_URL = "csurl"; - public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids"; - public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids"; - public static final String SCALEUP_POLICIES = "scaleuppolicies"; - public static final String SCALEDOWN_POLICIES = "scaledownpolicies"; - public static final String INTERVAL = "interval"; - public static final String QUIETTIME = "quiettime"; - public static final String ACTION = "action"; - public static final String CONDITION_ID = "conditionid"; - public static final String CONDITION_IDS = "conditionids"; - public static final String COUNTERPARAM_LIST = "counterparam"; - public static final String AUTOSCALE_USER_ID = "autoscaleuserid"; - public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername"; -<<<<<<< HEAD - public static final String UCS_DN = "ucsdn"; -======= - public static final String VM_SNAPSHOT_DESCRIPTION = "description"; - public static final String VM_SNAPSHOT_DISPLAYNAME = "name"; - public static final String VM_SNAPSHOT_ID = "vmsnapshotid"; - public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids"; - public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory"; ->>>>>>> CLOUDSTACK-684 Support VM Snapshot - - 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/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 0b73fd47888..d1e13023117 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -47,6 +47,7 @@ import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.IpForwardingRuleResponse; +import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; import org.apache.cloudstack.api.response.LDAPConfigResponse; import org.apache.cloudstack.api.response.LoadBalancerResponse; @@ -118,7 +119,12 @@ import com.cloud.network.*; import com.cloud.network.Network.Service; import com.cloud.network.as.*; import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.*; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.HealthCheckPolicy; +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.SecurityRule; import com.cloud.network.vpc.PrivateGateway; @@ -202,6 +208,11 @@ public interface ResponseGenerator { LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb); + LBHealthCheckResponse createLBHealthCheckPolicyResponse(List healthcheckPolicies, + LoadBalancer lb); + + LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb); + PodResponse createPodResponse(Pod pod, Boolean showCapacities); ZoneResponse createZoneResponse(DataCenter dataCenter, Boolean showCapacities); diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java index 4121651d499..89673ea6123 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java @@ -78,6 +78,11 @@ public class CreateAccountCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters") private Map details; + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.STRING, description="Account UUID, required for adding account from external provisioning system") + private String accountUUID; + + @Parameter(name=ApiConstants.USER_ID, type=CommandType.STRING, description="User UUID, required for adding account from external provisioning system") + private String userUUID; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -133,6 +138,14 @@ public class CreateAccountCmd extends BaseCmd { return params; } + public String getAccountUUID() { + return accountUUID; + } + + public String getUserUUID() { + return userUUID; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -151,7 +164,7 @@ public class CreateAccountCmd extends BaseCmd { public void execute(){ UserContext.current().setEventDetails("Account Name: "+getAccountName()+", Domain Id:"+getDomainId()); UserAccount userAccount = _accountService.createUserAccount(getUsername(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimeZone(), getAccountName(), getAccountType(), - getDomainId(), getNetworkDomain(), getDetails()); + getDomainId(), getNetworkDomain(), getDetails(), getAccountUUID(), getUserUUID()); if (userAccount != null) { AccountResponse response = _responseGenerator.createUserAccountResponse(userAccount); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java b/api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java index 5eae4865732..91d61ccf582 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java @@ -49,6 +49,9 @@ public class CreateDomainCmd extends BaseCmd { @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="Network domain for networks in the domain") private String networkDomain; + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.STRING, description="Domain UUID, required for adding domain from another Region") + private String domainUUID; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +68,10 @@ public class CreateDomainCmd extends BaseCmd { return networkDomain; } + public String getDomainUUID() { + return domainUUID; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -82,7 +89,7 @@ public class CreateDomainCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("Domain Name: "+getDomainName()+((getParentDomainId()!=null)?", Parent DomainId :"+getParentDomainId():"")); - Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain()); + Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain(), getDomainUUID()); if (domain != null) { DomainResponse response = _responseGenerator.createDomainResponse(domain); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java index 20366702dd1..dce1e8b8028 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java @@ -49,12 +49,6 @@ public class AddRegionCmd extends BaseCmd { @Parameter(name=ApiConstants.END_POINT, type=CommandType.STRING, required=true, description="Region service endpoint") private String endPoint; - @Parameter(name=ApiConstants.API_KEY, type=CommandType.STRING, description="API key of Admin user") - private String apiKey; - - @Parameter(name=ApiConstants.SECRET_KEY, type=CommandType.STRING, description="Secret Key of Admin user") - private String secretKey; - @Inject public RegionService _regionService; ///////////////////////////////////////////////////// @@ -73,14 +67,6 @@ public class AddRegionCmd extends BaseCmd { return endPoint; } - public String getApiKey() { - return apiKey; - } - - public String getSecretKey() { - return secretKey; - } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -97,7 +83,7 @@ public class AddRegionCmd extends BaseCmd { @Override public void execute(){ - Region region = _regionService.addRegion(getId(), getRegionName(), getEndPoint(), getApiKey(), getSecretKey()); + Region region = _regionService.addRegion(getId(), getRegionName(), getEndPoint()); if (region != null) { RegionResponse response = _responseGenerator.createRegionResponse(region); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java index 16693b64650..79890d00eca 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java @@ -49,12 +49,6 @@ public class UpdateRegionCmd extends BaseCmd { @Parameter(name=ApiConstants.END_POINT, type=CommandType.STRING, description="updates region with this end point") private String endPoint; - @Parameter(name=ApiConstants.API_KEY, type=CommandType.STRING, description="new API key for the Region") - private String apiKey; - - @Parameter(name=ApiConstants.SECRET_KEY, type=CommandType.STRING, description="new Secret Key for the Region") - private String secretKey; - @Inject RegionService _regionService; ///////////////////////////////////////////////////// @@ -73,13 +67,6 @@ public class UpdateRegionCmd extends BaseCmd { return endPoint; } - public String getApiKey() { - return apiKey; - } - - public String getSecretKey() { - return secretKey; - } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -96,7 +83,7 @@ public class UpdateRegionCmd extends BaseCmd { @Override public void execute(){ - Region region = _regionService.updateRegion(getId(), getRegionName(), getEndPoint(), getApiKey(), getSecretKey()); + Region region = _regionService.updateRegion(getId(), getRegionName(), getEndPoint()); if (region != null) { RegionResponse response = _responseGenerator.createRegionResponse(region); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java index 6ea8d9b20cb..fb29e1a2629 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java @@ -65,6 +65,9 @@ public class CreateUserCmd extends BaseCmd { @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required=true, description="Unique username.") private String username; + @Parameter(name=ApiConstants.USER_ID, type=CommandType.STRING, description="User UUID, required for adding account from external provisioning system") + private String userUUID; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -101,6 +104,10 @@ public class CreateUserCmd extends BaseCmd { return username; } + public String getUserUUID() { + return userUUID; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -132,7 +139,7 @@ public class CreateUserCmd extends BaseCmd { @Override public void execute(){ UserContext.current().setEventDetails("UserName: "+getUserName()+", FirstName :"+getFirstName()+", LastName: "+getLastName()); - User user = _accountService.createUser(getUserName(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimezone(), getAccountName(), getDomainId()); + User user = _accountService.createUser(getUserName(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimezone(), getAccountName(), getDomainId(), getUserUUID()); if (user != null) { UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index bb37d085c8e..5683d58ab30 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -33,7 +33,7 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.UserContext; -@APICommand(name = "deleteUser", description="Creates a user for an account", responseObject=UserResponse.class) +@APICommand(name = "deleteUser", description="Deletes a user for an account", responseObject=SuccessResponse.class) public class DeleteUserCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteUserCmd.class.getName()); @@ -42,7 +42,7 @@ public class DeleteUserCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, required=true, description="Deletes a user") + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserResponse.class, required=true, description="id of the user to be deleted") private Long id; @Inject RegionService _regionService; diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java index 8a75c66531c..152dd4e14c2 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java @@ -35,7 +35,7 @@ import org.apache.log4j.Logger; import com.cloud.user.Account; import com.cloud.uservm.UserVm; -@APICommand(name = "assignVirtualMachine", description="Move a user VM to another user under same domain.", responseObject=UserVmResponse.class, since="3.0.0") +@APICommand(name = "assignVirtualMachine", description="Assign a VM from one account to another under the same domain. This API is available for Basic zones with security groups and Advance zones with guest networks. The VM is restricted to move between accounts under same domain.", responseObject=UserVmResponse.class, since="3.0.0") public class AssignVMCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AssignVMCmd.class.getName()); @@ -46,7 +46,7 @@ public class AssignVMCmd extends BaseCmd { ///////////////////////////////////////////////////// @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class, - required=true, description="the vm ID of the user VM to be moved") + required=true, description="id of the VM to be moved") private Long virtualMachineId; @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, required=true, description="account name of the new VM owner.") @@ -58,11 +58,11 @@ public class AssignVMCmd extends BaseCmd { //Network information @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=NetworkResponse.class, - description="list of network ids that will be part of VM network after move in advanced network setting.") + description="list of new network ids in which the moved VM will participate. In case no network ids are provided the VM will be part of the default network for that zone. In case there is no network yet created for the new account the default network will be created.") private List networkIds; @Parameter(name=ApiConstants.SECURITY_GROUP_IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=SecurityGroupResponse.class, - description="comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is moved in a zone with Basic Network support.") + description="list of security group ids to be applied on the virtual machine. In case no security groups are provided the VM is part of the default security group.") private List securityGroupIdList; ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 1824612ebb0..3219601156e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -52,7 +52,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { private String hypervisor; @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class, - description="list all isos by id") + description="list ISO by id") private Long id; @Parameter(name=ApiConstants.IS_PUBLIC, type=CommandType.BOOLEAN, description="true if the ISO is publicly available to all users, false otherwise.") @@ -61,11 +61,14 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.IS_READY, type=CommandType.BOOLEAN, description="true if this ISO is ready to be deployed") private Boolean ready; - @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"self-executable\",\"executable\", and \"community\". " + - "* featured-ISOs that are featured and are publicself-ISOs that have been registered/created by the owner. " + - "* selfexecutable-ISOs that have been registered/created by the owner that can be used to deploy a new VM. " + - "* executable-all ISOs that can be used to deploy a new VM " + - "* community-ISOs that are public.") + @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + + "* featured : templates that have been marked as featured and public. " + + "* self : templates that have been registered or created by the calling user. " + + "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " + + "* sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. " + + "* executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. " + + "* community : templates that have been marked as public but not featured. " + + "* all : all templates (only usable by admins).") private String isoFilter = TemplateFilter.selfexecutable.toString(); @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list all isos by name") diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java new file mode 100644 index 00000000000..ac0ec3a9dab --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java @@ -0,0 +1,168 @@ +// 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 org.apache.cloudstack.api.command.user.loadbalancer; + + +import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.HealthCheckPolicy; +import org.apache.cloudstack.api.response.LBHealthCheckResponse; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + + +@APICommand(name = "createLBHealthCheckPolicy", description = "Creates a Load Balancer healthcheck policy ", responseObject = LBHealthCheckResponse.class, since="4.2.0") +@SuppressWarnings("rawtypes") +public class CreateLBHealthCheckPolicyCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger + .getLogger(CreateLBHealthCheckPolicyCmd.class.getName()); + + private static final String s_name = "createlbhealthcheckpolicyresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = true, description = "the ID of the load balancer rule") + private Long lbRuleId; + + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "the description of the load balancer HealthCheck policy") + private String description; + + @Parameter(name = ApiConstants.HEALTHCHECK_PINGPATH, type = CommandType.STRING, required = false, description = "HTTP Ping Path") + private String pingPath; + + @Parameter(name = ApiConstants.HEALTHCHECK_RESPONSE_TIMEOUT, type = CommandType.INTEGER, required = false, description = "Time to wait when receiving a response from the health check (2sec - 60 sec)") + private int responsTimeOut; + + @Parameter(name = ApiConstants.HEALTHCHECK_INTERVAL_TIME, type = CommandType.INTEGER, required = false, description = "Amount of time between health checks (1 sec - 20940 sec)") + private int healthCheckInterval; + + @Parameter(name = ApiConstants.HEALTHCHECK_HEALTHY_THRESHOLD, type = CommandType.INTEGER, required = false, description = "Number of consecutive health check success before declaring an instance healthy") + private int healthyThreshold; + + @Parameter(name = ApiConstants.HEALTHCHECK_UNHEALTHY_THRESHOLD, type = CommandType.INTEGER, required = false, description = "Number of consecutive health check failures before declaring an instance unhealthy") + private int unhealthyThreshold; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getLbRuleId() { + return lbRuleId; + } + + public String getDescription() { + return description; + } + + public String getPingPath() { + return pingPath; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + public int getResponsTimeOut() { + return responsTimeOut; + } + + public int getHealthCheckInterval() { + return healthCheckInterval; + } + + public int getHealthyThreshold() { + return healthyThreshold; + } + + public int getUnhealthyThreshold() { + return unhealthyThreshold; + } + + @Override + public void execute() throws ResourceAllocationException, ResourceUnavailableException { + HealthCheckPolicy policy = null; + boolean success = false; + + try { + UserContext.current().setEventDetails("Load balancer healthcheck policy Id : " + getEntityId()); + success = _lbService.applyLBHealthCheckPolicy(this); + if (success) { + // State might be different after the rule is applied, so get new object here + policy = _entityMgr.findById(HealthCheckPolicy.class, getEntityId()); + LoadBalancer lb = _lbService.findById(policy.getLoadBalancerId()); + LBHealthCheckResponse hcResponse = _responseGenerator.createLBHealthCheckPolicyResponse(policy, lb); + setResponseObject(hcResponse); + hcResponse.setResponseName(getCommandName()); + } + } finally { + if (!success || (policy == null)) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create healthcheck policy "); + } + } + } + + @Override + public void create() { + try { + HealthCheckPolicy result = _lbService.createLBHealthCheckPolicy(this); + this.setEntityId(result.getId()); + this.setEntityUuid(result.getUuid()); + } catch (InvalidParameterValueException e) { + s_logger.warn("Exception: ", e); + throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR , e.getMessage()); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE; + } + + @Override + public String getEventDescription() { + return "Create Load Balancer HealthCheck policy"; + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java new file mode 100644 index 00000000000..bf91da51d68 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java @@ -0,0 +1,116 @@ +// 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 org.apache.cloudstack.api.command.user.loadbalancer; + +import org.apache.cloudstack.api.response.LBHealthCheckResponse; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "deleteLBHealthCheckPolicy", description = "Deletes a load balancer HealthCheck policy.", responseObject = SuccessResponse.class, since="4.2.0") +public class DeleteLBHealthCheckPolicyCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteLBHealthCheckPolicyCmd.class.getName()); + private static final String s_name = "deletelbhealthcheckpolicyresponse"; + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = LBHealthCheckResponse.class, + required = true, description = "the ID of the load balancer HealthCheck policy") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + + 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_LB_HEALTHCHECKPOLICY_DELETE; + } + + @Override + public String getEventDescription() { + return "deleting load balancer HealthCheck policy: " + getId(); + } + + @Override + public void execute() { + UserContext.current().setEventDetails("Load balancer healthcheck policy Id: " + getId()); + boolean result = _lbService.deleteLBHealthCheckPolicy(getId() , true); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete load balancer healthcheck policy"); + } + } + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.networkSyncObject; + } + + @Override + public Long getSyncObjId() { + HealthCheckPolicy policy = _entityMgr.findById(HealthCheckPolicy.class, + getId()); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find load balancer healthcheck rule: " + id); + } + LoadBalancer lb = _lbService.findById(policy.getLoadBalancerId()); + if (lb == null) { + throw new InvalidParameterValueException("Unable to find load balancer rule for healthcheck rule: " + id); + } + return lb.getNetworkId(); + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java new file mode 100644 index 00000000000..cf5ea3238b8 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java @@ -0,0 +1,85 @@ +// 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 org.apache.cloudstack.api.command.user.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.LBHealthCheckResponse; +import org.apache.cloudstack.api.response.LBStickinessResponse; +import org.apache.cloudstack.api.response.ListResponse; + +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "listLBHealthCheckPolicies", description = "Lists load balancer HealthCheck policies.", responseObject = LBHealthCheckResponse.class, since="4.2.0") +public class ListLBHealthCheckPoliciesCmd extends BaseListCmd { + public static final Logger s_logger = Logger + .getLogger(ListLBHealthCheckPoliciesCmd.class.getName()); + + private static final String s_name = "listlbhealthcheckpoliciesresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, + required = true, description = "the ID of the load balancer rule") + private Long lbRuleId; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + public Long getLbRuleId() { + return lbRuleId; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + List hcpResponses = new ArrayList(); + LoadBalancer lb = _lbService.findById(getLbRuleId()); + ListResponse response = new ListResponse(); + + if (lb != null) { + List healthCheckPolicies = _lbService.searchForLBHealthCheckPolicies(this); + LBHealthCheckResponse spResponse = _responseGenerator.createLBHealthCheckPolicyResponse(healthCheckPolicies, lb); + hcpResponses.add(spResponse); + response.setResponses(hcpResponses); + } + + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + +} diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index c48534e0bd1..aeb76f507f3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -55,11 +55,14 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the template name") private String templateName; - @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"self-executable\", \"executable\", and \"community\"." + - "* featured-templates that are featured and are public" + - "* self-templates that have been registered/created by the owner" + - "* selfexecutable-templates that have been registered/created by the owner that can be used to deploy a new VM" + - "* executable-all templates that can be used to deploy a new VM* community-templates that are public.") + @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + + "* featured : templates that have been marked as featured and public. " + + "* self : templates that have been registered or created by the calling user. " + + "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " + + "* sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. " + + "* executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. " + + "* community : templates that have been marked as public but not featured. " + + "* all : all templates (only usable by admins).") private String templateFilter; @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index 0f992743f6d..df6b3999dba 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -28,6 +28,8 @@ import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; import com.cloud.async.AsyncJob; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; @@ -83,6 +85,9 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { public Long getNetworkId() { Nic nic = _entityMgr.findById(Nic.class, nicId); + if (nic == null) { + throw new InvalidParameterValueException("Can't find network id for specified nic"); + } Long networkId = nic.getNetworkId(); return networkId; } @@ -98,6 +103,13 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { return null; } } + + public NetworkType getNetworkType() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.getNetworkType(); + } + @Override public long getEntityOwnerId() { Account caller = UserContext.current().getCaller(); @@ -134,7 +146,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { UserContext.current().setEventDetails("Nic Id: " + getNicId() ); String ip; - String SecondaryIp = null; + String secondaryIp = null; if ((ip = getIpaddress()) != null) { if (!NetUtils.isValidIp(ip)) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); @@ -142,15 +154,24 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { } try { - SecondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress()); + secondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress()); } catch (InsufficientAddressCapacityException e) { throw new InvalidParameterValueException("Allocating guest ip for nic failed"); } - if (SecondaryIp != null) { - s_logger.info("Associated ip address to NIC : " + SecondaryIp); + if (secondaryIp != null) { + if (getNetworkType() == NetworkType.Basic) { + // add security group rules for the secondary ip addresses + boolean success = false; + success = _securityGroupService.securityGroupRulesForVmSecIp(getNicId(), getNetworkId(), secondaryIp, (boolean) true); + if (success == false) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); + } + } + + s_logger.info("Associated ip address to NIC : " + secondaryIp); NicSecondaryIpResponse response = new NicSecondaryIpResponse(); - response = _responseGenerator.createSecondaryIPToNicResponse(ip, getNicId(), getNetworkId()); + response = _responseGenerator.createSecondaryIPToNicResponse(secondaryIp, getNicId(), getNetworkId()); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index cb5e0855f64..21a9a0c96b4 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -27,15 +27,21 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; import org.apache.cloudstack.api.response.SuccessResponse; import com.cloud.async.AsyncJob; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.event.EventTypes; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Network; import com.cloud.user.Account; import com.cloud.user.UserContext; +import com.cloud.vm.Nic; +import com.cloud.vm.NicSecondaryIp; @APICommand(name = "removeIpFromNic", description="Assigns secondary IP to NIC.", responseObject=SuccessResponse.class) public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName()); - private static final String s_name = "unassignsecondaryipaddrtonicresponse"; + private static final String s_name = "removeipfromnicresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -43,7 +49,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.UUID, required = true, entityType = NicSecondaryIpResponse.class, description="the ID of the secondary ip address to nic") - private long id; + private Long id; // unexposed parameter needed for events logging @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, expose=false) @@ -57,7 +63,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return "nic_secondary_ips"; } - public long getIpAddressId() { + public Long getIpAddressId() { return id; } @@ -80,6 +86,11 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return EventTypes.EVENT_NET_IP_ASSIGN; } + public NicSecondaryIp getIpEntry() { + NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId()); + return nicSecIp; + } + @Override public String getEventDescription() { return ("Disassociating ip address with id=" + id); @@ -98,15 +109,53 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd { return "addressinfo"; } + public Long getNetworkId() { + NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId()); + if (nicSecIp != null) { + Long networkId = nicSecIp.getNetworkId(); + return networkId; + } else { + return null; + } + } + + public NetworkType getNetworkType() { + Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); + if (ntwk != null) { + DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); + return dc.getNetworkType(); + } + return null; + } + @Override public void execute() throws InvalidParameterValueException { - UserContext.current().setEventDetails("Ip Id: " + getIpAddressId()); - boolean result = _networkService.releaseSecondaryIpFromNic(getIpAddressId()); - if (result) { - SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary ip address for the nic"); + UserContext.current().setEventDetails("Ip Id: " + id); + NicSecondaryIp nicSecIp = getIpEntry(); + + if (nicSecIp == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed"); + } + + if (getNetworkType() == NetworkType.Basic) { + //remove the security group rules for this secondary ip + boolean success = false; + success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getNetworkId(),nicSecIp.getIp4Address(), false); + if (success == false) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip"); + } + } + + try { + boolean result = _networkService.releaseSecondaryIpFromNic(id); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary ip address for the nic"); + } + } catch (InvalidParameterValueException e) { + throw new InvalidParameterValueException("Removing guest ip from nic failed"); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java index 6719b8f0682..fb620001be2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java @@ -22,12 +22,12 @@ import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -88,7 +88,7 @@ public class UpgradeVMCmd extends BaseCmd { } @Override - public void execute(){ + public void execute() throws ResourceAllocationException{ UserContext.current().setEventDetails("Vm Id: "+getId()); ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId); diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 274e7a5becb..b2bc02e9b83 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.apache.cloudstack.api.ApiConstants; @@ -157,7 +158,7 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView private Set nics; public DomainRouterResponse(){ - nics = new HashSet(); + nics = new LinkedHashSet(); } @@ -344,7 +345,7 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView public void addNic(NicResponse nic) { this.nics.add(nic); } - + public String getIp6Dns1() { return ip6Dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java b/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java new file mode 100644 index 00000000000..5dd123c03a3 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java @@ -0,0 +1,98 @@ +// 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 org.apache.cloudstack.api.response; + +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.BaseResponse; + +public class LBHealthCheckPolicyResponse extends BaseResponse { + @SerializedName("id") + @Param(description = "the LB HealthCheck policy ID") + private String id; + + @SerializedName("pingpath") + @Param(description = "the pingpath of the healthcheck policy") + private String pingpath; + + @SerializedName("description") + @Param(description = "the description of the healthcheck policy") + private String description; + + @SerializedName("state") + @Param(description = "the state of the policy") + private String state; + + @SerializedName("responsetime") + @Param(description = "Time to wait when receiving a response from the health check") + private int responseTime; + + @SerializedName("healthcheckinterval") + @Param(description = "Amount of time between health checks") + private int healthcheckInterval; + + @SerializedName("healthcheckthresshold") + @Param(description = "Number of consecutive health check success before declaring an instance healthy") + private int healthcheckthresshold; + + @SerializedName("unhealthcheckthresshold") + @Param(description = "Number of consecutive health check failures before declaring an instance unhealthy.") + private int unhealthcheckthresshold; + + public void setId(String id) { + this.id = id; + } + + public String getpingpath() { + return pingpath; + } + + public void setpingpath(String pingpath) { + this.pingpath = pingpath; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public LBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckpolicy) { + if (healthcheckpolicy.isRevoke()) { + this.setState("Revoked"); + } + if (healthcheckpolicy.getUuid() != null) + setId(healthcheckpolicy.getUuid()); + this.pingpath = healthcheckpolicy.getpingpath(); + this.healthcheckInterval = healthcheckpolicy.getHealthcheckInterval(); + this.responseTime = healthcheckpolicy.getResponseTime(); + this.healthcheckthresshold = healthcheckpolicy.getHealthcheckThresshold(); + this.unhealthcheckthresshold = healthcheckpolicy.getUnhealthThresshold(); + setObjectName("healthcheckpolicy"); + } +} diff --git a/api/src/org/apache/cloudstack/api/response/LBHealthCheckResponse.java b/api/src/org/apache/cloudstack/api/response/LBHealthCheckResponse.java new file mode 100644 index 00000000000..182013ffef0 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/LBHealthCheckResponse.java @@ -0,0 +1,102 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.network.rules.HealthCheckPolicy; +import org.apache.cloudstack.api.ApiConstants; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import java.util.List; +import java.util.UUID; + +@EntityReference(value=HealthCheckPolicy.class) +public class LBHealthCheckResponse extends BaseResponse { +@SerializedName("lbruleid") + @Param(description = "the LB rule ID") + private String lbRuleId; + + + @SerializedName("account") + @Param(description = "the account of the HealthCheck policy") + private String accountName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID of the HealthCheck policy") + private String domainId; + + @SerializedName("domain") + @Param(description = "the domain of the HealthCheck policy") + private String domainName; + + @SerializedName(ApiConstants.ZONE_ID) + @Param(description = "the id of the zone the HealthCheck policy belongs to") + private String zoneId; + + @SerializedName("healthcheckpolicy") + @Param(description = "the list of healthcheckpolicies", responseObject = LBHealthCheckPolicyResponse.class) + private List healthCheckPolicies; + + public void setlbRuleId(String lbRuleId) { + this.lbRuleId = lbRuleId; + } + + public void setRules(List policies) { + this.healthCheckPolicies = policies; + } + + public List getHealthCheckPolicies() { + return healthCheckPolicies; + } + + public void setHealthCheckPolicies(List healthCheckPolicies) { + this.healthCheckPolicies = healthCheckPolicies; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public void setDomainId(String domainId) { + this.domainId = domainId; + } + + public void setZoneId(String zoneId) { + this.zoneId = zoneId; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public LBHealthCheckResponse() { + } + + public LBHealthCheckResponse(HealthCheckPolicy healthcheckpolicy) { + setObjectName("healthcheckpolicy"); + } +} diff --git a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java index 3464a63540e..695468faef2 100644 --- a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java @@ -20,28 +20,38 @@ import java.util.List; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; +import com.cloud.network.rules.FirewallRule; import com.cloud.serializer.Param; +import com.cloud.vm.NicSecondaryIp; import com.google.gson.annotations.SerializedName; +@EntityReference(value=NicSecondaryIp.class) @SuppressWarnings("unused") public class NicSecondaryIpResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the ID of the secondary private IP addr") - private Long id; + private String id; @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="Secondary IP address") private String ipAddr; @SerializedName(ApiConstants.NIC_ID) @Param(description="the ID of the nic") - private Long nicId; + private String nicId; @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the network") - private Long nwId; + private String nwId; @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the ID of the vm") - private Long vmId; + private String vmId; - public Long getId() { + @Override + public String getObjectId() { + return this.getId(); + } + + public String getId() { return id; } @@ -53,32 +63,32 @@ public class NicSecondaryIpResponse extends BaseResponse { this.ipAddr = ipAddr; } - public Long getNicId() { + public String getNicId() { return nicId; } - public void setNicId(Long nicId) { - this.nicId = nicId; + public void setNicId(String string) { + this.nicId = string; } - public Long getNwId() { + public String getNwId() { return nwId; } - public void setNwId(Long nwId) { + public void setNwId(String nwId) { this.nwId = nwId; } - public Long getVmId() { + public String getVmId() { return vmId; } - public void setVmId(Long vmId) { + public void setVmId(String vmId) { this.vmId = vmId; } - public Long setId(Long id) { - return id; + public void setId(String id) { + this.id = id; } diff --git a/api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java b/api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java index 1130ec03f37..96a8bc28ed2 100644 --- a/api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.response; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.apache.cloudstack.api.ApiConstants; @@ -65,9 +66,9 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledVie private Set tags; public SecurityGroupResponse(){ - this.ingressRules = new HashSet(); - this.egressRules = new HashSet(); - this.tags = new HashSet(); + this.ingressRules = new LinkedHashSet(); + this.egressRules = new LinkedHashSet(); + this.tags = new LinkedHashSet(); } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index cb2113e1eaf..71d1b823c6a 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.apache.cloudstack.api.ApiConstants; @@ -169,9 +170,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp private String keyPairName; public UserVmResponse(){ - securityGroupList = new HashSet(); - nics = new HashSet(); - tags = new HashSet(); + securityGroupList = new LinkedHashSet(); + nics = new LinkedHashSet(); + tags = new LinkedHashSet(); } public void setHypervisor(String hypervisor) { diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index b10da0c032a..d5054f0bc26 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.apache.cloudstack.api.ApiConstants; @@ -161,7 +162,7 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity private Set tags; public VolumeResponse(){ - tags = new HashSet(); + tags = new LinkedHashSet(); } @Override diff --git a/api/src/org/apache/cloudstack/region/Region.java b/api/src/org/apache/cloudstack/region/Region.java index 87b028b3d58..7119f1b2c14 100644 --- a/api/src/org/apache/cloudstack/region/Region.java +++ b/api/src/org/apache/cloudstack/region/Region.java @@ -32,9 +32,6 @@ public interface Region { public String getEndPoint(); - public String getApiKey(); - - public String getSecretKey(); public boolean checkIfServiceEnabled(Service service); diff --git a/api/src/org/apache/cloudstack/region/RegionService.java b/api/src/org/apache/cloudstack/region/RegionService.java index 8679ca92b10..303b58c8127 100644 --- a/api/src/org/apache/cloudstack/region/RegionService.java +++ b/api/src/org/apache/cloudstack/region/RegionService.java @@ -43,22 +43,18 @@ public interface RegionService { * @param id * @param name * @param endPoint - * @param apiKey - * @param secretKey * @return Return added Region object */ - public Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey); + public Region addRegion(int id, String name, String endPoint); /** * Update details of the Region with specified Id * @param id * @param name * @param endPoint - * @param apiKey - * @param secretKey * @return Return updated Region object */ - public Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey); + public Region updateRegion(int id, String name, String endPoint); /** * @param id diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java index ede86e9d857..7fd6e0b86b0 100644 --- a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java +++ b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java @@ -37,7 +37,7 @@ public class BackupSnapshotAnswerTest { StoragePool pool = Mockito.mock(StoragePool.class); bsc = new BackupSnapshotCommand( - "secondaryStoragePoolURL", 101L, 102L, 103L, 104L, + "secondaryStoragePoolURL", 101L, 102L, 103L, 104L, 105L, "volumePath", pool, "snapshotUuid", "snapshotName", "prevSnapshotUuid", "prevBackupUuid", false, "vmName", 5); bsa = new BackupSnapshotAnswer(bsc, true, "results", "bussname", false); diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java index 71004977d89..06697c4384f 100644 --- a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java +++ b/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java @@ -147,14 +147,14 @@ public class BackupSnapshotCommandTest { BackupSnapshotCommand bsc = new BackupSnapshotCommand( "http://secondary.Storage.Url", - 101L, 102L, 103L, 104L, "vPath", pool, + 101L, 102L, 103L, 104L, 105L, "vPath", pool, "420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName", "9012793e-0657-11e2-bebc-0050568b0057", "7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5); BackupSnapshotCommand bsc1 = new BackupSnapshotCommand( "http://secondary.Storage.Url", - 101L, 102L, 103L, 104L, "vPath", pool, + 101L, 102L, 103L, 104L, 105L,"vPath", pool, "420fa39c-4ef1-a83c-fd93-46dc1ff515ae", "sName", "9012793e-0657-11e2-bebc-0050568b0057", "7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5); diff --git a/api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java b/api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java index 01cd33bec80..f57dc084472 100644 --- a/api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java +++ b/api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java @@ -64,7 +64,7 @@ public class RegionCmdTest extends TestCase { Region region = Mockito.mock(Region.class); Mockito.when( - regionService.addRegion(Mockito.anyInt(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())) + regionService.addRegion(Mockito.anyInt(), Mockito.anyString(), Mockito.anyString())) .thenReturn(region); addRegionCmd._regionService = regionService; @@ -87,7 +87,7 @@ public class RegionCmdTest extends TestCase { Region region = Mockito.mock(Region.class); Mockito.when( - regionService.addRegion(Mockito.anyInt(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())) + regionService.addRegion(Mockito.anyInt(), Mockito.anyString(), Mockito.anyString())) .thenReturn(null); addRegionCmd._regionService = regionService; diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index d167a5c0a4f..f0b6b363bc9 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -17,6 +17,7 @@ #new labels (begin) ********************************************************************************************** +label.use.vm.ip=Use VM IP: label.menu.regions=Regions label.region=Region label.add.region=Add Region diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 16e9822ece0..38ad5780121 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -151,6 +151,9 @@ createLBStickinessPolicy=15 deleteLBStickinessPolicy=15 listLoadBalancerRules=15 listLBStickinessPolicies=15 +listLBHealthCheckPolicies=15 +createLBHealthCheckPolicy=15 +deleteLBHealthCheckPolicy=15 listLoadBalancerRuleInstances=15 updateLoadBalancerRule=15 diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 23566e204c0..7b64f49ee20 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -107,11 +107,7 @@ - - - - - + - - - - - - - - - - - true - - - diff --git a/client/tomcatconf/components-nonoss.xml.in b/client/tomcatconf/components-nonoss.xml.in deleted file mode 100755 index fbfc5cc2726..00000000000 --- a/client/tomcatconf/components-nonoss.xml.in +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - true - - - - - - diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in deleted file mode 100755 index 1d3faf384dc..00000000000 --- a/client/tomcatconf/components.xml.in +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - true - - - - 1 - 25 - 50000 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in index 20e0c32db57..7e3552db67e 100644 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ b/client/tomcatconf/nonossComponentContext.xml.in @@ -113,11 +113,7 @@ - - - - - + + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 @@ -43,7 +35,7 @@ - + 1.6 UTF-8 @@ -92,6 +84,7 @@ 0.10 build/replace.properties 0.4.9 + target @@ -174,11 +167,11 @@ - - mysql - mysql-connector-java - ${cs.mysql.version} - + + mysql + mysql-connector-java + ${cs.mysql.version} + @@ -188,13 +181,13 @@ junit ${cs.junit.version} test - - - - org.springframework - spring-core - ${org.springframework.version} - + + + + org.springframework + spring-core + ${org.springframework.version} + org.springframework spring-context @@ -205,74 +198,37 @@ spring-web ${org.springframework.version} - + - org.mockito - mockito-all - 1.9.5 - test + org.mockito + mockito-all + 1.9.5 + test - - org.springframework - spring-test - ${org.springframework.version} - test - + + org.springframework + spring-test + ${org.springframework.version} + test + org.aspectj @@ -285,17 +241,19 @@ 1.7.1 - javax.inject - javax.inject - 1 + javax.inject + javax.inject + 1 install + ${basedir}/${cs.target.dir}/classes + ${basedir}/${cs.target.dir}/test-classes - org.eclipse.m2e @@ -381,6 +339,11 @@ tools/appliance/definitions/systemvmtemplate/definition.rb tools/appliance/definitions/systemvmtemplate/preseed.cfg tools/appliance/definitions/systemvmtemplate/zerodisk.sh + tools/appliance/definitions/systemvmtemplate64/base.sh + tools/appliance/definitions/systemvmtemplate64/cleanup.sh + tools/appliance/definitions/systemvmtemplate64/definition.rb + tools/appliance/definitions/systemvmtemplate64/preseed.cfg + tools/appliance/definitions/systemvmtemplate64/zerodisk.sh tools/cli/cloudmonkey.egg-info/* tools/devcloud/src/deps/boxes/basebox-build/definition.rb tools/devcloud/src/deps/boxes/basebox-build/preseed.cfg @@ -448,41 +411,41 @@ ${cs.jdk.version} ${cs.jdk.version} - true - 128m - 512m - -XDignore.symbol.file=true + true + 128m + 512m + -XDignore.symbol.file=true - - org.apache.maven.plugins - maven-jar-plugin - 2.4 - - - - true - true - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - remove-old-installers - - remove-project-artifact - - - true - - - - + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + true + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + remove-old-installers + + remove-project-artifact + + + true + + + + org.apache.maven.plugins maven-dependency-plugin @@ -510,15 +473,31 @@ + eclipse + + target-eclipse + + + developer - - tools/devcloud/devcloud.cfg - + + tools/devcloud/devcloud.cfg + developer tools + + impatient + + tools/devcloud/devcloud.cfg + + + developer + + + vmware @@ -531,112 +510,112 @@ - simulator - - - deploydb-simulator - - - - - - org.codehaus.mojo - properties-maven-plugin - 1.0-alpha-2 - - - initialize - - read-project-properties - - - - ${project.basedir}/utils/conf/db.properties - ${project.basedir}/utils/conf/db.properties.override - - true - - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 - - - - mysql - mysql-connector-java - ${cs.mysql.version} - - - commons-dbcp - commons-dbcp - ${cs.dbcp.version} - - - commons-pool - commons-pool - ${cs.pool.version} - - - org.jasypt - jasypt - ${cs.jasypt.version} - - - org.apache.cloudstack - cloud-utils - ${project.version} - - - org.apache.cloudstack - cloud-server - ${project.version} - - - - - process-resources - create-schema - - java - - - - - false - true - - org.apache.cloudstack - cloud-server - - com.cloud.upgrade.DatabaseCreator - - - ${project.basedir}/utils/conf/db.properties - ${project.basedir}/utils/conf/db.properties.override - - ${basedir}/target/db/create-schema-simulator.sql - ${basedir}/target/db/templates.simulator.sql - - com.cloud.upgrade.DatabaseUpgradeChecker - --database=simulator - --rootpassword=${db.root.password} - - - - - catalina.home - ${project.basedir}/utils - - - - - - - + simulator + + + deploydb-simulator + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + initialize + + read-project-properties + + + + ${project.basedir}/utils/conf/db.properties + ${project.basedir}/utils/conf/db.properties.override + + true + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + + mysql + mysql-connector-java + ${cs.mysql.version} + + + commons-dbcp + commons-dbcp + ${cs.dbcp.version} + + + commons-pool + commons-pool + ${cs.pool.version} + + + org.jasypt + jasypt + ${cs.jasypt.version} + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + org.apache.cloudstack + cloud-server + ${project.version} + + + + + process-resources + create-schema + + java + + + + + false + true + + org.apache.cloudstack + cloud-server + + com.cloud.upgrade.DatabaseCreator + + + ${project.basedir}/utils/conf/db.properties + ${project.basedir}/utils/conf/db.properties.override + + ${basedir}/target/db/create-schema-simulator.sql + ${basedir}/target/db/templates.simulator.sql + + com.cloud.upgrade.DatabaseUpgradeChecker + --database=simulator + --rootpassword=${db.root.password} + + + + + catalina.home + ${project.basedir}/utils + + + + + + + diff --git a/scripts/storage/qcow2/resizevolume.sh b/scripts/storage/qcow2/resizevolume.sh index d15513e250f..6a5c91d9dd6 100755 --- a/scripts/storage/qcow2/resizevolume.sh +++ b/scripts/storage/qcow2/resizevolume.sh @@ -68,7 +68,7 @@ log() { if [ $shouldwelog -eq 1 ] then - echo "$d - $1" >> /var/log/cloud/agent/resizevolume.log + echo "$d - $1" >> /var/log/cloudstack/agent/resizevolume.log fi } @@ -237,7 +237,7 @@ do esac done -shouldwelog=1 #set this to 1 while debugging to get output in /var/log/cloud/agent/resizevolume.log +shouldwelog=1 #set this to 1 while debugging to get output in /var/log/cloudstack/agent/resizevolume.log if [ "$ptype" == "CLVM" ] then diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index db6f6d63ac9..31c9a59663e 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -610,6 +610,7 @@ def destroy_network_rules_for_vm(session, args): util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress) remove_rule_log_for_vm(vm_name) + remove_secip_log_for_vm(vm_name) if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]: return 'true' @@ -749,6 +750,43 @@ def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac): return 'true' + +@echo +def network_rules_vmSecondaryIp(session, args): + vm_name = args.pop('vmName') + vm_mac = args.pop('vmMac') + ip_secondary = args.pop('vmSecIp') + action = args.pop('action') + util.SMlog("vmMac = "+ vm_mac) + util.SMlog("vmName = "+ vm_name) + #action = "-A" + util.SMlog("action = "+ action) + try: + vm = session.xenapi.VM.get_by_name_label(vm_name) + if len(vm) != 1: + return 'false' + vm_rec = session.xenapi.VM.get_record(vm[0]) + vm_vifs = vm_rec.get('VIFs') + vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs] + domid = vm_rec.get('domid') + except: + util.SMlog("### Failed to get domid or vif list for vm ##" + vm_name) + return 'false' + + if domid == '-1': + util.SMlog("### Failed to get domid for vm (-1): " + vm_name) + return 'false' + + vifs = ["vif" + domid + "." + v for v in vifnums] + #vm_name = '-'.join(vm_name.split('-')[:-1]) + vmchain = chain_name(vm_name) + add_to_ipset(vmchain, [ip_secondary], action) + + #add arptables rules for the secondary ip + arp_rules_vmip(vmchain, vifs, [ip_secondary], vm_mac, action) + + return 'true' + @echo def default_network_rules_systemvm(session, args): vm_name = args.pop('vmName') @@ -798,6 +836,55 @@ def default_network_rules_systemvm(session, args): util.SMlog("Failed to log default network rules for systemvm, ignoring") return 'true' +@echo +def create_ipset_forvm (ipsetname): + result = True + try: + util.SMlog("Creating ipset chain .... " + ipsetname) + util.pread2(['ipset', '-F', ipsetname]) + util.pread2(['ipset', '-X', ipsetname]) + util.pread2(['ipset', '-N', ipsetname, 'iphash']) + except: + util.SMlog("ipset chain not exists creating.... " + ipsetname) + util.pread2(['ipset', '-N', ipsetname, 'iphash']) + + return result + +@echo +def add_to_ipset(ipsetname, ips, action): + result = True + for ip in ips: + try: + util.SMlog("vm ip " + ip) + util.pread2(['ipset', action, ipsetname, ip]) + except: + util.SMlog("vm ip alreday in ip set" + ip) + continue + + return result + +@echo +def arp_rules_vmip (vm_chain, vifs, ips, vm_mac, action): + try: + if action == "-A": + action = "-I" + for vif in vifs: + for vm_ip in ips: + #accept any arp requests to this vm as long as the request is for this vm's ip + util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp replies to this vm as long as the mac and ip matches + util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT']) + #accept arp replies into the bridge as long as the source mac and ips match the vm + util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT']) + #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts + #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination + util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN']) + except: + util.SMlog("Failed to program arptables rules for ip") + return 'false' + + return 'true' + @echo def default_network_rules(session, args): @@ -805,6 +892,8 @@ def default_network_rules(session, args): vm_ip = args.pop('vmIP') vm_id = args.pop('vmID') vm_mac = args.pop('vmMAC') + sec_ips = args.pop("secIps") + action = "-A" try: vm = session.xenapi.VM.get_by_name_label(vm_name) @@ -854,6 +943,32 @@ def default_network_rules(session, args): except: util.pread2(['iptables', '-F', vmchain_default]) + vmipset = vm_name + #create ipset and add vm ips to that ip set + if create_ipset_forvm(vmipset) == False: + util.SMlog(" failed to create ipset for rule " + str(tokens)) + return 'false' + + #add primary nic ip to ipset + if add_to_ipset(vmipset, [vm_ip], action ) == False: + util.SMlog(" failed to add vm " + vm_ip + " ip to set ") + return 'false' + + #add secodnary nic ips to ipset + secIpSet = "1" + ips = sec_ips.split(':') + ips.pop() + if ips[0] == "0": + secIpSet = "0"; + + if secIpSet == "1": + util.SMlog("Adding ipset for secondary ips") + add_to_ipset(vmipset, ips, action) + if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False: + util.SMlog("Failed to log default network rules, ignoring") + + keyword = '--' + get_ipset_keyword() + try: for v in vifs: util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) @@ -861,16 +976,22 @@ def default_network_rules(session, args): #don't let vm spoof its ip address for v in vifs: - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', '!', vm_ip, '-j', 'DROP']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '--destination', '!', vm_ip, '-j', 'DROP']) - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress]) + #util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', '!', keyword, vmipset, 'src', '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-m', 'set', '!', keyword, vmipset, 'dst', '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-j', vmchain_egress]) util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) except: util.SMlog("Failed to program default rules for vm " + vm_name) return 'false' default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + #add default arp rules for secondary ips; + if secIpSet == "1": + util.SMlog("Adding arp rules for sec ip") + arp_rules_vmip(vmchain, vifs, ips, vm_mac, action) + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False: @@ -994,10 +1115,45 @@ def network_rules_for_rebooted_vm(session, vmName): destroy_arptables_rules(vmchain) [vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain) default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac) + + #check wether the vm has secondary ips + if is_secondary_ips_set(vm_name) == True: + vmips = get_vm_sec_ips(vm_name) + #add arp rules for the secondaryp ip + for ip in vmips: + arp_rules_vmip(vmchain, vifs, [ip], vm_mac, "-A") + + default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac) rewrite_rule_log_for_vm(vm_name, curr_domid) return True + + +@echo +def get_vm_sec_ips(vm_name): + logfilename = "/var/run/cloud/" + vm_name +".ip" + + lines = (line.rstrip() for line in open(logfilename)) + for line in lines: + try: + [_vmName,_vmIP,_vmID] = line.split(',') + break + except ValueError,v: + [_vmName,_vmIP,_vmID] = line.split(',') + + _vmIPS = _vmIP.split(":")[:-1] + return _vmIPS + +@echo +def is_secondary_ips_set(vm_name): + logfilename = "/var/run/cloud/" + vm_name +".ip" + if not os.path.exists(logfilename): + return False + + return True + +@echo def rewrite_rule_log_for_vm(vm_name, new_domid): logfilename = "/var/run/cloud/" + vm_name +".log" if not os.path.exists(logfilename): @@ -1194,6 +1350,39 @@ def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): return [reprogramDefault, reprogramChain, rewriteLog] +@echo +def write_secip_log_for_vm (vmName, secIps, vmId): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" + util.SMlog("Writing log to " + logfilename) + logf = open(logfilename, 'w') + output = ','.join([vmName, secIps, vmId]) + result = True + + try: + logf.write(output) + logf.write('\n') + except: + util.SMlog("Failed to write to rule log file " + logfilename) + result = False + + logf.close() + + return result + +@echo +def remove_secip_log_for_vm(vmName): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" + + result = True + try: + os.remove(logfilename) + except: + util.SMlog("Failed to delete rule log file " + logfilename) + result = False + + return result @echo def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'): @@ -1289,6 +1478,7 @@ def network_rules(session, args): vm_mac = args.get('vmMAC') signature = args.pop('signature') seqno = args.pop('seqno') + sec_ips = args.pop("secIps") deflated = 'false' if 'deflated' in args: deflated = args.pop('deflated') @@ -1469,6 +1659,7 @@ if __name__ == "__main__": "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, "destroy_network_rules_for_vm":destroy_network_rules_for_vm, "default_network_rules_systemvm":default_network_rules_systemvm, + "network_rules_vmSecondaryIp":network_rules_vmSecondaryIp, "get_rule_logs_for_vms":get_rule_logs_for_vms, "setLinkLocalIP":setLinkLocalIP, "cleanup_rules":cleanup_rules, diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot index 6fb1b18c1df..87a50836b16 100755 --- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot +++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot @@ -321,25 +321,24 @@ def umount(localDir): util.SMlog("Successfully unmounted " + localDir) return -def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId): +def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId, secHostId): # The aim is to mount secondaryStorageMountPath on # And create / dir on it, if it doesn't exist already. # Assuming that secondaryStorageMountPath exists remotely - # Alex's suggestion and currently implemented: - # Just mount secondaryStorageMountPath/ everytime + # Just mount secondaryStorageMountPath//SecondaryStorageHost/ everytime # Never unmount. snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir) # Mkdir local mount point dir, if it doesn't exist. localMountPointPath = os.path.join(CLOUD_DIR, dcId) - localMountPointPath = os.path.join(localMountPointPath, relativeDir) + localMountPointPath = os.path.join(localMountPointPath, relativeDir, secHostId) makedirs(localMountPointPath) - # if something is not mounted already on localMountPointPath, + # if something is not mounted already on localMountPointPath, # mount secondaryStorageMountPath on localMountPath if os.path.ismount(localMountPointPath): - # There is only one secondary storage per zone. + # There is more than one secondary storage per zone. # And we are mounting each sec storage under a zone-specific directory # So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer. util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath) @@ -352,11 +351,22 @@ def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, i makedirs(backupsDir) return backupsDir +def unmountAll(path): + try: + for dir in os.listdir(path): + if dir.isdigit(): + util.SMlog("Unmounting Sub-Directory: " + dir) + localMountPointPath = os.path.join(path, dir) + umount(localMountPointPath) + except: + util.SMlog("Ignoring the error while trying to unmount the snapshots dir") + @echo def unmountSnapshotsDir(session, args): dcId = args['dcId'] localMountPointPath = os.path.join(CLOUD_DIR, dcId) localMountPointPath = os.path.join(localMountPointPath, "snapshots") + unmountAll(localMountPointPath) try: umount(localMountPointPath) except: @@ -482,7 +492,8 @@ def backupSnapshot(session, args): snapshotUuid = args['snapshotUuid'] prevBackupUuid = args['prevBackupUuid'] backupUuid = args['backupUuid'] - isISCSI = getIsTrueString(args['isISCSI']) + isISCSI = getIsTrueString(args['isISCSI']) + secHostId = args['secHostId'] primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI) util.SMlog("primarySRPath: " + primarySRPath) @@ -496,10 +507,10 @@ def backupSnapshot(session, args): # Mount secondary storage mount path on XenServer along the path # /var/run/sr-mount//snapshots/ and create / dir # on it. - backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId) + backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId, secHostId) util.SMlog("Backups dir " + backupsDir) - # Check existence of snapshot on primary storage + # Check existence of snapshot on primary storage isfile(baseCopyPath, isISCSI) if prevBackupUuid: # Check existence of prevBackupFile diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot index f7b2e0e6d7b..05366384820 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot +++ b/scripts/vm/hypervisor/xenserver/xcposs/vmopsSnapshot @@ -321,25 +321,24 @@ def umount(localDir): util.SMlog("Successfully unmounted " + localDir) return -def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId): +def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, instanceId, secHostId): # The aim is to mount secondaryStorageMountPath on # And create / dir on it, if it doesn't exist already. # Assuming that secondaryStorageMountPath exists remotely - # Alex's suggestion and currently implemented: - # Just mount secondaryStorageMountPath/ everytime + # Just mount secondaryStorageMountPath//SecondaryStorageHost/ everytime # Never unmount. snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir) # Mkdir local mount point dir, if it doesn't exist. localMountPointPath = os.path.join(CLOUD_DIR, dcId) - localMountPointPath = os.path.join(localMountPointPath, relativeDir) + localMountPointPath = os.path.join(localMountPointPath, relativeDir, secHostId) makedirs(localMountPointPath) # if something is not mounted already on localMountPointPath, # mount secondaryStorageMountPath on localMountPath if os.path.ismount(localMountPointPath): - # There is only one secondary storage per zone. + # There can be more than one secondary storage per zone. # And we are mounting each sec storage under a zone-specific directory # So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer. util.SMlog("The remote snapshots directory has already been mounted on " + localMountPointPath) @@ -352,11 +351,22 @@ def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, i makedirs(backupsDir) return backupsDir +def unmountAll(path): + try: + for dir in os.listdir(path): + if dir.isdigit(): + util.SMlog("Unmounting Sub-Directory: " + dir) + localMountPointPath = os.path.join(path, dir) + umount(localMountPointPath) + except: + util.SMlog("Ignoring the error while trying to unmount the snapshots dir") + @echo def unmountSnapshotsDir(session, args): dcId = args['dcId'] localMountPointPath = os.path.join(CLOUD_DIR, dcId) localMountPointPath = os.path.join(localMountPointPath, "snapshots") + unmountAll(localMountPointPath) try: umount(localMountPointPath) except: @@ -490,7 +500,8 @@ def backupSnapshot(session, args): snapshotUuid = args['snapshotUuid'] prevBackupUuid = args['prevBackupUuid'] backupUuid = args['backupUuid'] - isISCSI = getIsTrueString(args['isISCSI']) + isISCSI = getIsTrueString(args['isISCSI']) + secHostId = args['secHostId'] primarySRPath = getPrimarySRPath(session, primaryStorageSRUuid, isISCSI) util.SMlog("primarySRPath: " + primarySRPath) @@ -504,10 +515,10 @@ def backupSnapshot(session, args): # Mount secondary storage mount path on XenServer along the path # /var/run/sr-mount//snapshots/ and create / dir # on it. - backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId) + backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId, secHostId) util.SMlog("Backups dir " + backupsDir) - # Check existence of snapshot on primary storage + # Check existence of snapshot on primary storage isfile(baseCopyPath, isISCSI) if prevBackupUuid: # Check existence of prevBackupFile diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 83d7ad13c86..49d9be68ddd 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -25,6 +25,8 @@ import os import xml.dom.minidom from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError import re +import traceback + iptables = Command("iptables") bash = Command("/bin/bash") virsh = Command("virsh") @@ -124,7 +126,12 @@ def destroy_network_rules_for_vm(vm_name, vif=None): execute("iptables -X " + vmchain_egress) except: logging.debug("Ignoring failure to delete chain " + vmchain_egress) - + + try: + execute("ipset -F " + vm_name) + execute("ipset -X " + vm_name) + except: + logging.debug("Ignoring failure to delete ipset " + vmchain) if vif is not None: try: @@ -137,7 +144,8 @@ def destroy_network_rules_for_vm(vm_name, vif=None): except: pass remove_rule_log_for_vm(vm_name) - + remove_secip_log_for_vm(vm_name) + if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]: return 'true' @@ -169,7 +177,7 @@ def destroy_ebtables_rules(vm_name, vif): execute("ebtables -t nat " + cmd) except: logging.debug("Ignoring failure to delete ebtables rules for vm " + vm_name) - chains = [vm_name+"-in", vm_name+"-out"] + chains = [vm_name+"-in", vm_name+"-out", vm_name+"-in-ips", vm_name+"-out-ips"] for chain in chains: try: execute("ebtables -t nat -F " + chain) @@ -180,8 +188,10 @@ def destroy_ebtables_rules(vm_name, vif): def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif): vmchain_in = vm_name + "-in" vmchain_out = vm_name + "-out" + vmchain_in_ips = vm_name + "-in-ips" + vmchain_out_ips = vm_name + "-out-ips" - for chain in [vmchain_in, vmchain_out]: + for chain in [vmchain_in, vmchain_out, vmchain_in_ips, vmchain_out_ips]: try: execute("ebtables -t nat -N " + chain) except: @@ -191,6 +201,8 @@ def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif): # -s ! 52:54:0:56:44:32 -j DROP execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " + vmchain_in) execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vmchain_out) + execute("ebtables -t nat -A " + vmchain_in_ips + " -j DROP") + execute("ebtables -t nat -A " + vmchain_out_ips + " -j DROP") except: logging.debug("Failed to program default rules") return 'false' @@ -200,7 +212,8 @@ def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif): execute("ebtables -t nat -A " + vmchain_in + " -p ARP -s ! " + vm_mac + " -j DROP") execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP") if vm_ip is not None: - execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP") + execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j " + vmchain_in_ips) + execute("ebtables -t nat -I " + vmchain_in_ips + " -p ARP --arp-ip-src " + vm_ip + " -j RETURN") execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Request -j ACCEPT") execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Reply -j ACCEPT") execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j DROP") @@ -211,7 +224,8 @@ def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif): try: execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP") if vm_ip is not None: - execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP") + execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j " + vmchain_out_ips ) + execute("ebtables -t nat -I " + vmchain_out_ips + " -p ARP --arp-ip-dst " + vm_ip + " -j RETURN") execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Request -j ACCEPT") execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply -j ACCEPT") execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j DROP") @@ -253,12 +267,95 @@ def default_network_rules_systemvm(vm_name, localbrname): logging.debug("Failed to log default network rules for systemvm, ignoring") return 'true' +def remove_secip_log_for_vm(vmName): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" -def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): + result = True + try: + os.remove(logfilename) + except: + util.SMlog("Failed to delete rule log file " + logfilename) + result = False + + return result + +def write_secip_log_for_vm (vmName, secIps, vmId): + vm_name = vmName + logfilename = "/var/run/cloud/"+vm_name+".ip" + logging.debug("Writing log to " + logfilename) + logf = open(logfilename, 'w') + output = ','.join([vmName, secIps, vmId]) + result = True + + try: + logf.write(output) + logf.write('\n') + except: + logging.debug("Failed to write to rule log file " + logfilename) + result = False + + logf.close() + + return result + +def create_ipset_forvm (ipsetname): + result = True + try: + logging.debug("Creating ipset chain .... " + ipsetname) + execute("ipset -F " + ipsetname) + execute("ipset -X " + ipsetname) + execute("ipset -N " + ipsetname + " iphash") + except: + logging.debug("ipset chain not exists creating.... " + ipsetname) + execute("ipset -N " + ipsetname + " iphash") + + return result + +def add_to_ipset(ipsetname, ips, action): + result = True + for ip in ips: + try: + logging.debug("vm ip " + ip) + execute("ipset " + action + " " + ipsetname + " " + ip) + except: + logging.debug("vm ip alreday in ip set " + ip) + continue + + return result + +def network_rules_vmSecondaryIp(vm_name, ip_secondary, action): + logging.debug("vmName = "+ vm_name) + logging.debug("action = "+ action) + + domid = getvmId(vm_name) + + vmchain = vm_name + add_to_ipset(vmchain, [ip_secondary], action) + + #add ebtables rules for the secondary ip + ebtables_rules_vmip(vm_name, [ip_secondary], action) + + return 'true' + +def ebtables_rules_vmip (vmname, ips, action): + vmchain_inips = vmname + "-in-ips" + vmchain_outips = vmname + "-out-ips" + + for ip in ips: + logging.debug("ip = "+ip) + try: + execute("ebtables -t nat -I " + vmchain_inips + " -p ARP --arp-ip-src " + ip + " -j RETURN") + execute("ebtables -t nat -I " + vmchain_outips + " -p ARP --arp-ip-dst " + ip + " -j RETURN") + except: + logging.debug("Failed to program ebtables rules for secondary ip "+ ip) + continue + +def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, sec_ips): if not addFWFramework(brname): return False - vmName = vm_name + vmName = vm_name brfw = "BF-" + brname domID = getvmId(vm_name) delete_rules_for_vm_in_bridge_firewall_chain(vmName) @@ -283,6 +380,31 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): except: execute("iptables -F " + vmchain_default) + action = "-A" + vmipsetName = vm_name + #create ipset and add vm ips to that ip set + if create_ipset_forvm(vmipsetName) == False: + logging.debug(" failed to create ipset for rule " + str(tokens)) + return 'false' + + #add primary nic ip to ipset + if add_to_ipset(vmipsetName, [vm_ip], action ) == False: + logging.debug(" failed to add vm " + vm_ip + " ip to set ") + return 'false' + + #add secodnary nic ips to ipset + secIpSet = "1" + ips = sec_ips.split(':') + ips.pop() + if ips[0] == "0": + secIpSet = "0"; + + if secIpSet == "1": + logging.debug("Adding ipset for secondary ips") + add_to_ipset(vmipsetName, ips, action) + if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False: + logging.debug("Failed to log default network rules, ignoring") + try: execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default) execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default) @@ -293,8 +415,8 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): #don't let vm spoof its ip address if vm_ip is not None: - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -p udp --dport 53 -j RETURN ") - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j " + vmchain_egress) + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p udp --dport 53 -j RETURN ") + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -j " + vmchain_egress) execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) execute("iptables -A " + vmchain + " -j DROP") except: @@ -302,6 +424,8 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): return 'false' default_ebtables_rules(vmchain, vm_ip, vm_mac, vif) + #default ebtables rules for vm secondary ips + ebtables_rules_vmip(vm_name, ips, "-I") if vm_ip is not None: if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False: @@ -342,7 +466,7 @@ def post_default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, dhcpS def delete_rules_for_vm_in_bridge_firewall_chain(vmName): vm_name = vmName if vm_name.startswith('i-') or vm_name.startswith('r-'): - vm_name = '-'.join(vm_name.split('-')[:-1]) + vm_name = '-'.join(vm_name.split('-')[:-1]) + "-def" vmchain = vm_name @@ -596,7 +720,7 @@ def remove_rule_log_for_vm(vmName): def egress_chain_name(vm_name): return vm_name + "-eg" -def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname): +def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname, sec_ips): try: vmName = vm_name domId = getvmId(vmName) @@ -612,7 +736,7 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif return 'true' if changes[0] or changes[1] or changes[2] or changes[3]: - default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname) + default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname, sec_ips) if rules == "" or rules == None: lines = [] @@ -620,10 +744,14 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif lines = rules.split(';')[:-1] logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name) - vmchain = vm_name - execute("iptables -F " + vmchain) - egress_vmchain = egress_chain_name(vm_name) - execute("iptables -F " + egress_vmchain) + try: + vmchain = vm_name + execute("iptables -F " + vmchain) + egress_vmchain = egress_chain_name(vm_name) + execute("iptables -F " + egress_vmchain) + except: + logging.debug("Error flushing iptables rules for " + vmchain + ". Presuming firewall rules deleted, re-initializing." ) + default_network_rules(vm_name, vm_id, vm_ip, vmMac, vif, brname) egressrule = 0 for line in lines: @@ -692,7 +820,8 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif return 'true' except: - logging.debug("Failed to network rule !: " + sys.exc_type) + exceptionText = traceback.format_exc() + logging.debug("Failed to network rule !: " + exceptionText) def getVifs(vmName): vifs = [] @@ -797,7 +926,7 @@ def addFWFramework(brname): return False if __name__ == '__main__': - logging.basicConfig(filename="/var/log/cloud/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG) + logging.basicConfig(filename="/var/log/cloudstack/agent/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG) parser = OptionParser() parser.add_option("--vmname", dest="vmName") parser.add_option("--vmip", dest="vmIP") @@ -812,6 +941,8 @@ if __name__ == '__main__': parser.add_option("--dhcpSvr", dest="dhcpSvr") parser.add_option("--hostIp", dest="hostIp") parser.add_option("--hostMacAddr", dest="hostMacAddr") + parser.add_option("--nicsecips", dest="nicSecIps") + parser.add_option("--action", dest="action") (option, args) = parser.parse_args() if len(args) == 0: logging.debug("No command to execute") @@ -820,7 +951,7 @@ if __name__ == '__main__': if cmd == "can_bridge_firewall": can_bridge_firewall(args[1]) elif cmd == "default_network_rules": - default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname) + default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname, option.nicSecIps) elif cmd == "destroy_network_rules_for_vm": destroy_network_rules_for_vm(option.vmName, option.vif) elif cmd == "default_network_rules_systemvm": @@ -828,7 +959,9 @@ if __name__ == '__main__': elif cmd == "get_rule_logs_for_vms": get_rule_logs_for_vms() elif cmd == "add_network_rules": - add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname) + add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname, option.nicSecIps) + elif cmd == "network_rules_vmSecondaryIp": + network_rules_vmSecondaryIp(option.vmName, option.nicSecIps, option.action) elif cmd == "cleanup_rules": cleanup_rules() elif cmd == "post_default_network_rules": diff --git a/server/conf/cloudstack-limits.conf.in b/server/conf/cloudstack-limits.conf.in new file mode 100644 index 00000000000..c28ad8c3c78 --- /dev/null +++ b/server/conf/cloudstack-limits.conf.in @@ -0,0 +1,21 @@ +# 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. + +# Specific limits for the CloudStack management server which +# runs under the user 'cloud' by default +@MSUSER hard nofile 4096 +@MSUSER soft nofile 4096 diff --git a/server/conf/cloudstack-sudoers.in b/server/conf/cloudstack-sudoers.in new file mode 100644 index 00000000000..c525d3cf44b --- /dev/null +++ b/server/conf/cloudstack-sudoers.in @@ -0,0 +1,22 @@ +# 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. + +# The CloudStack management server needs sudo permissions +# without a password. + +@MSUSER ALL =NOPASSWD : ALL + diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 3e95da95528..4c3d7e54d09 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -46,6 +46,8 @@ import org.apache.cloudstack.api.response.ControlledViewEntityResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.IpForwardingRuleResponse; +import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse; +import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; import org.apache.cloudstack.api.response.LDAPConfigResponse; @@ -126,6 +128,13 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.*; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.HealthCheckPolicy; +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.SecurityGroupVO; import com.cloud.network.security.SecurityRule; @@ -168,6 +177,7 @@ import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.InstanceGroup; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.VirtualMachine; @@ -2747,6 +2757,58 @@ public class ApiResponseHelper implements ResponseGenerator { return spResponse; } + @Override + public LBHealthCheckResponse createLBHealthCheckPolicyResponse( + List healthcheckPolicies, LoadBalancer lb) { + LBHealthCheckResponse hcResponse = new LBHealthCheckResponse(); + + if (lb == null) + return hcResponse; + hcResponse.setlbRuleId(lb.getUuid()); + Account account = ApiDBUtils.findAccountById(lb.getAccountId()); + if (account != null) { + hcResponse.setAccountName(account.getAccountName()); + Domain domain = ApiDBUtils.findDomainById(account.getDomainId()); + if (domain != null) { + hcResponse.setDomainId(domain.getUuid()); + hcResponse.setDomainName(domain.getName()); + } + } + + List responses = new ArrayList(); + for (HealthCheckPolicy healthcheckPolicy : healthcheckPolicies) { + LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy); + responses.add(ruleResponse); + } + hcResponse.setRules(responses); + + hcResponse.setObjectName("healthcheckpolicies"); + return hcResponse; + } + + @Override + public LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb) { + LBHealthCheckResponse hcResponse = new LBHealthCheckResponse(); + + hcResponse.setlbRuleId(lb.getUuid()); + Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId()); + if (accountTemp != null) { + hcResponse.setAccountName(accountTemp.getAccountName()); + Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId()); + if (domain != null) { + hcResponse.setDomainId(domain.getUuid()); + hcResponse.setDomainName(domain.getName()); + } + } + + List responses = new ArrayList(); + LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy); + responses.add(ruleResponse); + hcResponse.setRules(responses); + hcResponse.setObjectName("healthcheckpolicies"); + return hcResponse; + } + @Override public LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, @@ -3445,9 +3507,11 @@ public class ApiResponseHelper implements ResponseGenerator { public NicSecondaryIpResponse createSecondaryIPToNicResponse(String ipAddr, Long nicId, Long networkId) { NicSecondaryIpResponse response = new NicSecondaryIpResponse(); + NicVO nic = _entityMgr.findById(NicVO.class, nicId); + NetworkVO network = _entityMgr.findById(NetworkVO.class, networkId); response.setIpAddr(ipAddr); - response.setNicId(nicId); - response.setNwId(networkId); + response.setNicId(nic.getUuid()); + response.setNwId(network.getUuid()); response.setObjectName("nicsecondaryip"); return response; } @@ -3463,7 +3527,7 @@ public class ApiResponseHelper implements ResponseGenerator { List ipList = new ArrayList(); for (NicSecondaryIpVO ip: secondaryIps) { NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse(); - ipRes.setId(ip.getId()); + ipRes.setId(ip.getUuid()); ipRes.setIpAddr(ip.getIp4Address()); ipList.add(ipRes); } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index deb5e12f9fc..3c0857568b4 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -16,51 +16,39 @@ // under the License. package com.cloud.api; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLEncoder; -import java.security.SecureRandom; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.inject.Inject; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - +import com.cloud.api.response.ApiResponseSerializer; +import com.cloud.async.AsyncCommandQueued; +import com.cloud.async.AsyncJob; +import com.cloud.async.AsyncJobManager; +import com.cloud.async.AsyncJobVO; +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.ActionEventUtils; +import com.cloud.exception.*; +import com.cloud.user.*; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; +import com.cloud.utils.component.ComponentContext; +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.exception.CloudRuntimeException; import org.apache.cloudstack.acl.APIChecker; -import org.apache.cloudstack.api.APICommand; -import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.BaseAsyncCmd; -import org.apache.cloudstack.api.BaseAsyncCreateCmd; -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.BaseListCmd; -import org.apache.cloudstack.api.ResponseObject; -import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; -import com.cloud.event.ActionEventUtils; -import org.apache.cloudstack.acl.APILimitChecker; -import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; +import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; +import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectsCmd; import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd; @@ -68,17 +56,12 @@ import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; +import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.response.ExceptionResponse; import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; +import org.apache.cloudstack.region.RegionManager; import org.apache.commons.codec.binary.Base64; -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.NameValuePair; +import org.apache.http.*; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.impl.DefaultHttpResponseFactory; @@ -89,57 +72,29 @@ 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.http.protocol.*; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; -import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; -import com.cloud.api.response.ApiResponseSerializer; -import org.apache.cloudstack.region.RegionManager; - -import com.cloud.async.AsyncCommandQueued; -import com.cloud.async.AsyncJob; -import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobVO; -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.exception.AccountLimitException; -import com.cloud.exception.CloudAuthenticationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.RequestLimitException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -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.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.StringUtils; -import com.cloud.utils.component.ComponentContext; -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.exception.CloudRuntimeException; +import javax.annotation.PostConstruct; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.inject.Inject; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.*; +import java.security.SecureRandom; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; @Component public class ApiServer implements HttpRequestHandler, ApiServerService { @@ -208,11 +163,11 @@ public class ApiServer implements HttpRequestHandler, ApiServerService { for(PluggableService pluggableService: _pluggableServices) cmdClasses.addAll(pluggableService.getCommands()); - for(Class cmdClass: cmdClasses) { - APICommand at = cmdClass.getAnnotation(APICommand.class); - if (at == null) { + for(Class cmdClass: cmdClasses) { + APICommand at = cmdClass.getAnnotation(APICommand.class); + if (at == null) { throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName())); - } + } String apiName = at.name(); if (_apiNameCmdClassMap.containsKey(apiName)) { s_logger.error("API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName); @@ -327,10 +282,12 @@ public class ApiServer implements HttpRequestHandler, ApiServerService { } String[] value = (String[]) params.get(key); // fail if parameter value contains ASCII control (non-printable) characters - String newValue = StringUtils.stripControlCharacters(value[0]); - if ( !newValue.equals(value[0]) ) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value " + value[0] + " for parameter " - + key + " is invalid, contains illegal ASCII non-printable characters"); + if (value[0] != null) { + String newValue = StringUtils.stripControlCharacters(value[0]); + if ( !newValue.equals(value[0]) ) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value " + value[0] + " for parameter " + + key + " is invalid, contains illegal ASCII non-printable characters"); + } } paramMap.put(key, value[0]); } diff --git a/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java index ca0f171dd1a..1dfed3421bb 100644 --- a/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java @@ -56,7 +56,9 @@ public class ProjectInvitationJoinDaoImpl extends GenericDaoBase dcs = _dcDao.listAllIncludingRemoved(); - for (DataCenterVO dc : dcs) { - List pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.PxeServer, dc.getId()); - if (pxeServers.size() == 0) { - throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + dc.getName()); - } - } - } else { - List pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.PxeServer, profile.getZoneId()); - if (pxeServers.size() == 0) { - throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + profile.getZoneId()); - } - } - - return profile; - } - - @Override - public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { - throw new CloudRuntimeException("Baremetal doesn't support ISO template"); - } - - private void templateCreateUsage(VMTemplateVO template, HostVO host) { - if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(), - template.getId(), template.getName(), null, template.getSourceTemplateId(), 0L, - template.getClass().getName(), template.getUuid()); - } - } - - @Override - public VMTemplateVO create(TemplateProfile profile) { - VMTemplateVO template = persistTemplate(profile); - Long zoneId = profile.getZoneId(); - - /* There is no secondary storage vm for baremetal, we use pxe server id. - * Tempalte is not bound to pxeserver right now, and we assume the pxeserver - * cannot be removed once it was added. so we use host id of first found pxe - * server as reference in template_host_ref. - * This maybe a FIXME in future. - */ - VMTemplateHostVO vmTemplateHost = null; - if (zoneId == null || zoneId == -1) { - List dcs = _dcDao.listAllIncludingRemoved(); - for (DataCenterVO dc : dcs) { - HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.PxeServer, dc.getId()).get(0); - - vmTemplateHost = _tmpltHostDao.findByHostTemplate(dc.getId(), template.getId()); - if (vmTemplateHost == null) { - vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100, - Status.DOWNLOADED, null, null, null, null, template.getUrl()); - _tmpltHostDao.persist(vmTemplateHost); - templateCreateUsage(template, pxe); - } - } - } else { - HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.PxeServer, zoneId).get(0); - vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100, - Status.DOWNLOADED, null, null, null, null, template.getUrl()); - _tmpltHostDao.persist(vmTemplateHost); - templateCreateUsage(template, pxe); - } - - _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); - return template; - } - - public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { - throw new CloudRuntimeException("Baremetal doesn't support ISO, how the delete get here???"); - } - - @Override @DB - public boolean delete(TemplateProfile profile) { - VMTemplateVO template = (VMTemplateVO)profile.getTemplate(); - Long templateId = template.getId(); - boolean success = true; - String zoneName; - boolean isAllZone; - - if (!template.isCrossZones() && profile.getZoneId() != null) { - isAllZone = false; - zoneName = profile.getZoneId().toString(); - } else { - zoneName = "all zones"; - isAllZone = true; - } - - s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - String eventType = EventTypes.EVENT_TEMPLATE_DELETE; - List templateHostVOs = _tmpltHostDao.listByTemplateId(templateId); - - for (VMTemplateHostVO vo : templateHostVOs) { - VMTemplateHostVO lock = null; - try { - HostVO pxeServer = _hostDao.findById(vo.getHostId()); - if (!isAllZone && pxeServer.getDataCenterId() != profile.getZoneId()) { - continue; - } - - lock = _tmpltHostDao.acquireInLockTable(vo.getId()); - if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + vo.getId()); - success = false; - break; - } - - vo.setDestroyed(true); - _tmpltHostDao.update(vo.getId(), vo); - VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(pxeServer.getDataCenterId(), templateId); - if (templateZone != null) { - _tmpltZoneDao.remove(templateZone.getId()); - } - - UsageEventUtils.publishUsageEvent(eventType, account.getId(), pxeServer.getDataCenterId(), - templateId, null, template.getClass().getName(), template.getUuid()); - } finally { - if (lock != null) { - _tmpltHostDao.releaseFromLockTable(lock.getId()); - } - } - } - - s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); - - // If there are no more non-destroyed template host entries for this template, delete it - if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) { - long accountId = template.getAccountId(); - - VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId); - - try { - if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId); - success = false; - } else if (_tmpltDao.remove(templateId)) { - // Decrement the number of templates - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); - } - - } finally { - if (lock != null) { - _tmpltDao.releaseFromLockTable(lock.getId()); - } - } - s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed."); - } - - return success; - } -} diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 505b332d848..1a57a64488d 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -211,7 +211,11 @@ public enum Config { AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), - DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), + // LB HealthCheck Interval. + LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600", + "Time Interval to fetch the LB health check states (in sec)", null), + + DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null), CheckPodCIDRs("Advanced", ManagementServer.class, String.class, "check.pod.cidrs", "true", "If true, different pods must belong to different CIDR subnets.", "true,false"), NetworkGcWait("Advanced", ManagementServer.class, Integer.class, "network.gc.wait", "600", "Time (in seconds) to wait before shutting down a network that's not in used", null), @@ -377,7 +381,7 @@ public enum Config { IntervalToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "interval.baremetal.securitygroup.agent.echo", "10", "Interval to echo baremetal security group agent, in seconds", null), TimeoutToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "timeout.baremetal.securitygroup.agent.echo", "3600", "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null), - ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "true", "Enable/disable Api rate limit", null), + ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null), ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null), ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null), ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 7f449dec60e..b1ad6b7fb9d 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -252,17 +252,19 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao? @Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao; - private int _maxVolumeSizeInGb; - private long _defaultPageSize; + private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.getDefaultValue()); + private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue()); protected Set configValuesForValidation; @Override public boolean configure(final String name, final Map params) throws ConfigurationException { - String maxVolumeSizeInGbString = _configDao.getValue("storage.max.volume.size"); - _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, 2000); + String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key()); + _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, + Integer.parseInt(Config.MaxVolumeSize.getDefaultValue())); - String defaultPageSizeString = _configDao.getValue("default.page.size"); - _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, 500L); + String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key()); + _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, + Long.parseLong(Config.DefaultPageSize.getDefaultValue())); populateConfigValuesForValidationSet(); return true; diff --git a/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java b/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java index 62094eb5ea6..03e87743851 100755 --- a/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java +++ b/server/src/com/cloud/deploy/AbstractDeployPlannerSelector.java @@ -18,15 +18,23 @@ package com.cloud.deploy; import java.util.Map; +import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.utils.component.AdapterBase; import com.cloud.vm.UserVmVO; -public abstract class AbstractDeployPlannerSelector implements DeployPlannerSelector { +public abstract class AbstractDeployPlannerSelector extends AdapterBase implements DeployPlannerSelector { protected Map params; protected String name; protected int runLevel; - + + @Inject + protected ConfigurationDao _configDao; + protected String _allocationAlgorithm = "random"; + @Override public String getName() { return name; @@ -59,6 +67,8 @@ public abstract class AbstractDeployPlannerSelector implements DeployPlannerSele @Override public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key()); return true; } diff --git a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java index 034a9aafc92..8b2a1441151 100755 --- a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java +++ b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java @@ -18,6 +18,7 @@ package com.cloud.deploy; import javax.ejb.Local; +import com.cloud.deploy.DeploymentPlanner.AllocationAlgorithm; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.vm.UserVmVO; @@ -26,8 +27,20 @@ public class HypervisorVmPlannerSelector extends AbstractDeployPlannerSelector { @Override public String selectPlanner(UserVmVO vm) { if (vm.getHypervisorType() != HypervisorType.BareMetal) { - return "FirstFitPlanner"; + //check the allocation strategy + if (_allocationAlgorithm != null) { + if (_allocationAlgorithm.equals(AllocationAlgorithm.random.toString()) + || _allocationAlgorithm.equals(AllocationAlgorithm.firstfit.toString())) { + return "FirstFitPlanner"; + } else if (_allocationAlgorithm.equals(AllocationAlgorithm.userdispersing.toString())) { + return "UserDispersingPlanner"; + } else if (_allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_random.toString()) + || _allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_firstfit.toString())) { + return "UserConcentratedPodPlanner"; + } + } } + return null; } } diff --git a/server/src/com/cloud/domain/DomainVO.java b/server/src/com/cloud/domain/DomainVO.java index 346e19f8f06..a87bedc1e1e 100644 --- a/server/src/com/cloud/domain/DomainVO.java +++ b/server/src/com/cloud/domain/DomainVO.java @@ -75,12 +75,9 @@ public class DomainVO implements Domain { @Column(name="uuid") private String uuid; - @Column(name="region_id") - private int regionId; - public DomainVO() {} - public DomainVO(String name, long owner, Long parentId, String networkDomain, int regionId) { + public DomainVO(String name, long owner, Long parentId, String networkDomain) { this.parent = parentId; this.name = name; this.accountId = owner; @@ -89,10 +86,9 @@ public class DomainVO implements Domain { this.state = Domain.State.Active; this.networkDomain = networkDomain; this.uuid = UUID.randomUUID().toString(); - this.regionId = regionId; } - public DomainVO(String name, long owner, Long parentId, String networkDomain, String uuid, int regionId) { + public DomainVO(String name, long owner, Long parentId, String networkDomain, String uuid) { this.parent = parentId; this.name = name; this.accountId = owner; @@ -101,7 +97,6 @@ public class DomainVO implements Domain { this.state = Domain.State.Active; this.networkDomain = networkDomain; this.uuid = uuid; - this.regionId = regionId; } @Override @@ -216,12 +211,5 @@ public class DomainVO implements Domain { this.uuid = uuid; } - public int getRegionId() { - return regionId; - } - - public void setRegionId(int regionId) { - this.regionId = regionId; - } } diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index efe93966fe9..d77796da300 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -34,6 +34,7 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.VMInstanceDao; public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru { @@ -41,7 +42,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis @Inject VMTemplateDetailsDao _templateDetailsDao; @Inject NicDao _nicDao; @Inject VMInstanceDao _virtualMachineDao; - + @Inject NicSecondaryIpDao _nicSecIpDao; + protected HypervisorGuruBase() { super(); } @@ -68,6 +70,14 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis // Workaround to make sure the TO has the UUID we need for Niciri integration NicVO nicVO = _nicDao.findById(profile.getId()); to.setUuid(nicVO.getUuid()); + //check whether the this nic has secondary ip addresses set + //set nic secondary ip address in NicTO which are used for security group + // configuration. Use full when vm stop/start + List secIps = null; + if (nicVO.getSecondaryIp()) { + secIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nicVO.getId()); + } + to.setNicSecIps(secIps); return to; } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java index 9f559304ae4..9f11b850180 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java @@ -18,6 +18,7 @@ package com.cloud.network; import java.util.List; +import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; @@ -98,7 +99,9 @@ public interface ExternalLoadBalancerDeviceManager extends Manager{ * @throws ResourceUnavailableException * @throws InsufficientCapacityException */ - public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, + public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException; - + + public List getLBHealthChecks(Network network, List rules) + throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 7d04b3fca4b..c995566a736 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -20,7 +20,13 @@ 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.*; +import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand; +import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand; +import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer; +import com.cloud.agent.api.routing.HealthCheckLBConfigCommand; +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.to.IpAddressTO; import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.Config; @@ -876,7 +882,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { boolean inline = _networkMgr.isNetworkInlineMode(network); - LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies()); + LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies()); if (rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } @@ -1099,4 +1105,95 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase s_logger.info("Let " + element.getName() + " handle ip association for " + getName() + " in network " + network.getId()); return (IpDeployer)element; } + + @Override + public List getLBHealthChecks(Network network, List rules) + throws ResourceUnavailableException { + + // Find the external load balancer in this zone + long zoneId = network.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); + HealthCheckLBConfigAnswer answer = null; + + List loadBalancingRules = new ArrayList(); + + for (FirewallRule rule : rules) { + if (rule.getPurpose().equals(Purpose.LoadBalancing)) { + loadBalancingRules.add((LoadBalancingRule) rule); + } + } + + if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { + return null; + } + + 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 null; + } + + HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + + boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network); + + 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 null; + } + + List loadBalancersToApply = new ArrayList(); + List mappingStates = 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 uuid = rule.getUuid(); + String srcIp = _networkModel.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + + if (externalLoadBalancerIsInline) { + MappingNic nic = getLoadBalancingIpNic(zone, network, rule.getSourceIpAddressId(), revoked, null); + mappingStates.add(nic.getState()); + NicVO loadBalancingIpNic = nic.getNic(); + if (loadBalancingIpNic == null) { + 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()) { + boolean inline = _networkMgr.isNetworkInlineMode(network); + LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, + false, inline, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies()); + loadBalancersToApply.add(loadBalancer); + } + } + + try { + if (loadBalancersToApply.size() > 0) { + int numLoadBalancersForCommand = loadBalancersToApply.size(); + LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply + .toArray(new LoadBalancerTO[numLoadBalancersForCommand]); + // LoadBalancerConfigCommand cmd = new + // LoadBalancerConfigCommand(loadBalancersForCommand, null); + HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand); + long guestVlanTag = Integer.parseInt(network.getBroadcastUri().getHost()); + cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); + + answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd); + } + } catch (Exception ex) { + s_logger.error("Exception Occured ", ex); + } + return answer.getLoadBalancers(); + } + } diff --git a/server/src/com/cloud/network/LBHealthCheckPolicyVO.java b/server/src/com/cloud/network/LBHealthCheckPolicyVO.java new file mode 100644 index 00000000000..ed03a2bbc89 --- /dev/null +++ b/server/src/com/cloud/network/LBHealthCheckPolicyVO.java @@ -0,0 +1,157 @@ +// 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; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +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.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +import com.cloud.network.rules.HealthCheckPolicy; +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = ("load_balancer_healthcheck_policies")) +@PrimaryKeyJoinColumn(name = "load_balancer_id", referencedColumnName = "id") +public class LBHealthCheckPolicyVO implements HealthCheckPolicy { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "load_balancer_id") + private long loadBalancerId; + + @Column(name = "pingpath") + private String pingPath; + + @Column(name = "description") + private String description; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "response_time") + private int responseTime; + + @Column(name = "healthcheck_interval") + private int healthcheckInterval; + + @Column(name = "healthcheck_thresshold") + private int healthcheckThresshold; + + @Column(name = "unhealth_thresshold") + private int unhealthThresshold; + + @Column(name = "revoke") + private boolean revoke = false; + + protected LBHealthCheckPolicyVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public LBHealthCheckPolicyVO(long loadBalancerId, String pingPath, String description, int responseTime, + int healthcheckInterval, int healthcheckThresshold, int unhealthThresshold) { + this.loadBalancerId = loadBalancerId; + + if (pingPath == null || pingPath.isEmpty()) + this.pingPath = "/"; + else + this.pingPath = pingPath; + + if (responseTime == 0) + this.responseTime = 2; + else + this.responseTime = responseTime; + + if (healthcheckInterval == 0) + this.healthcheckInterval = 5; + else + this.healthcheckInterval = healthcheckInterval; + + if (healthcheckThresshold == 0) + this.healthcheckThresshold = 2; + else + this.healthcheckThresshold = healthcheckThresshold; + + if (unhealthThresshold == 0) + this.unhealthThresshold = 1; + else + this.unhealthThresshold = unhealthThresshold; + this.uuid = UUID.randomUUID().toString(); + + } + + public int getResponseTime() { + return responseTime; + } + + public int getHealthcheckInterval() { + return healthcheckInterval; + } + + public int getHealthcheckThresshold() { + return healthcheckThresshold; + } + + public int getUnhealthThresshold() { + return unhealthThresshold; + } + + public long getId() { + return id; + } + + public long getLoadBalancerId() { + return loadBalancerId; + } + + public String getpingpath() { + return pingPath; + } + + public String getDescription() { + return description; + } + + public boolean isRevoke() { + return revoke; + } + + public void setRevoke(boolean revoke) { + this.revoke = revoke; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 8b6bf9a7402..48e017edabd 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -21,6 +21,8 @@ import java.util.Map; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; @@ -339,8 +341,9 @@ public interface NetworkManager { public String allocateGuestIP(Account ipOwner, boolean isSystem, long zoneId, Long networkId, String requestedIp) throws InsufficientAddressCapacityException; - boolean removeVmSecondaryIps(long vmId); List listVmNics(Long vmId, Long nicId); + String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, Pod pod, Account caller, String requestedIp) throws InsufficientAddressCapacityException; + boolean removeVmSecondaryIpsOfNic(long nicId); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index ba5ab5d378b..591910b13c6 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -106,6 +106,7 @@ import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.*; @@ -1765,12 +1766,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _nicDao.remove(nic.getId()); s_logger.debug("Removed nic id=" + nic.getId()); //remove the secondary ip addresses corresponding to to this nic - List secondaryIps = _nicSecondaryIpDao.listByNicId(nic.getId()); - if (secondaryIps != null) { - for (NicSecondaryIpVO ip : secondaryIps) { - _nicSecondaryIpDao.remove(ip.getId()); - } - s_logger.debug("Removed nic " + nic.getId() + " secondary ip addreses"); + if (!removeVmSecondaryIpsOfNic(nic.getId())) { + s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed"); } } @@ -2314,52 +2311,51 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L @Override public boolean applyRules(List rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError) throws ResourceUnavailableException { - if (rules == null || rules.size() == 0) { - s_logger.debug("There are no rules to forward to the network elements"); - return true; - } + if (rules == null || rules.size() == 0) { + s_logger.debug("There are no rules to forward to the network elements"); + return true; + } - boolean success = true; - Network network = _networksDao.findById(rules.get(0).getNetworkId()); + boolean success = true; + Network network = _networksDao.findById(rules.get(0).getNetworkId()); FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType(); - List publicIps = new ArrayList(); + List publicIps = new ArrayList(); - if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) { + if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) { // get the list of public ip's owned by the network List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); if (userIps != null && !userIps.isEmpty()) { for (IPAddressVO userIp : userIps) { - PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); - publicIps.add(publicIp); - } - } + PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); + publicIps.add(publicIp); + } + } - // rules can not programmed unless IP is associated with network service provider, so run IP assoication for - // the network so as to ensure IP is associated before applying rules (in add state) - applyIpAssociations(network, false, continueOnError, publicIps); - } - - try { - applier.applyRules(network, purpose, rules); - } catch (ResourceUnavailableException e) { - if (!continueOnError) { - throw e; - } - s_logger.warn("Problems with applying " + purpose + " rules but pushing on", e); - success = false; - } - - if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) ) { - // if all the rules configured on public IP are revoked then dis-associate IP with network service provider + // rules can not programmed unless IP is associated with network + // service provider, so run IP assoication for + // the network so as to ensure IP is associated before applying + // rules (in add state) + applyIpAssociations(network, false, continueOnError, publicIps); + } + + try { + applier.applyRules(network, purpose, rules); + } catch (ResourceUnavailableException e) { + if (!continueOnError) { + throw e; + } + s_logger.warn("Problems with applying " + purpose + " rules but pushing on", e); + success = false; + } + + if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) { + // if all the rules configured on public IP are revoked then + // dis-associate IP with network service provider applyIpAssociations(network, true, continueOnError, publicIps); } - return success; + return success; } - - - - public class NetworkGarbageCollector implements Runnable { @@ -2835,7 +2831,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _accountMgr.checkAccess(caller, null, false, network); - //return acquireGuestIpAddress(network, requestedIp); ipaddr = acquireGuestIpAddress(network, requestedIp); return ipaddr; } @@ -3104,13 +3099,14 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L lb.setState(FirewallRule.State.Revoke); List dstList = _lbMgr.getExistingDestinations(lb.getId()); List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + List hcPolicyList = _lbMgr.getHealthCheckPolicies (lb.getId()); // mark all destination with revoke state for (LbDestination dst : dstList) { s_logger.trace("Marking lb destination " + dst + " with Revoke state"); dst.setRevoked(true); } - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); lbRules.add(loadBalancing); } @@ -3654,11 +3650,11 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L return nic.getSecondaryIp(); } - @Override - public boolean removeVmSecondaryIps(long vmId) { + @Override + public boolean removeVmSecondaryIpsOfNic(long nicId) { Transaction txn = Transaction.currentTxn(); txn.start(); - List ipList = _nicSecondaryIpDao.listByVmId(vmId); + List ipList = _nicSecondaryIpDao.listByNicId(nicId); if (ipList != null) { for (NicSecondaryIpVO ip: ipList) { _nicSecondaryIpDao.remove(ip.getId()); @@ -3669,4 +3665,16 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L return true; } -} + @Override + public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, Pod pod,Account owner, + String requestedIp) throws InsufficientAddressCapacityException { + PublicIp ip = assignPublicIpAddress(dc.getId(), null, owner, VlanType.DirectAttached, networkId, requestedIp, false); + if (ip == null) { + s_logger.debug("There is no free public ip address"); + return null; + } + Ip ipAddr = ip.getAddress(); + return ipAddr.addr(); + } + + } diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index e83c0d28ad4..779b9f23466 100644 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -742,7 +742,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Override public Nic getNicInNetwork(long vmId, long networkId) { - return _nicDao.findByInstanceIdAndNetworkId(networkId, vmId); + return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId); } @Override @@ -1457,11 +1457,11 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { if (network.getGuestType() != Network.GuestType.Shared) { List networkMap = _networksDao.listBy(owner.getId(), network.getId()); if (networkMap == null || networkMap.isEmpty()) { - throw new PermissionDeniedException("Unable to use network with id= " + network.getId() + ", permission denied"); + throw new PermissionDeniedException("Unable to use network with id= " + network.getUuid() + ", permission denied"); } } else { if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) { - throw new PermissionDeniedException("Shared network id=" + network.getId() + " is not available in domain id=" + owner.getDomainId()); + throw new PermissionDeniedException("Shared network id=" + network.getUuid() + " is not available in domain id=" + owner.getDomainId()); } } } @@ -1972,4 +1972,21 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { } } } + + @Override + public String getStartIpv6Address(long networkId) { + List vlans = _vlanDao.listVlansByNetworkId(networkId); + if (vlans == null) { + return null; + } + String startIpv6 = null; + // Get the start ip of first create vlan(not the lowest, because if you add a lower vlan, lowest vlan would change) + for (Vlan vlan : vlans) { + if (vlan.getIp6Range() != null) { + startIpv6 = vlan.getIp6Range().split("-")[0]; + break; + } + } + return startIpv6; + } } diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 821aa6db26f..52e81e5c8c8 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -517,8 +517,45 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } catch (InsufficientAddressCapacityException e) { throw new InvalidParameterValueException("Allocating guest ip for nic failed"); } + } else if (dc.getNetworkType() == NetworkType.Basic) { + Account caller = UserContext.current().getCaller(); + long callerUserId = UserContext.current().getCallerUserId(); + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + //handle the basic networks here + VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId()); + if (vm == null) { + throw new InvalidParameterValueException("There is no vm with the nic"); + } + VMInstanceVO vmi = (VMInstanceVO)vm; + Long podId = vmi.getPodIdToDeployIn(); + if (podId == null) { + throw new InvalidParameterValueException("vm pod id is null"); + } + Pod pod = _hostPodDao.findById(podId); + if (pod == null) { + throw new InvalidParameterValueException("vm pod is null"); + } + + try { + ipaddr = _networkMgr.allocatePublicIpForGuestNic(networkId, dc, pod, caller, requestedIp); + if (ipaddr == null) { + throw new InvalidParameterValueException("Allocating ip to guest nic " + nicId + " failed"); + } + } catch (InsufficientAddressCapacityException e) { + s_logger.error("Allocating ip to guest nic " + nicId + " failed"); + return null; + } + } else if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && zone.getNetworkType() == NetworkType.Advanced) { + // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork' + Account caller = UserContext.current().getCaller(); + long callerUserId = UserContext.current().getCallerUserId(); + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); + } } else { - throw new InvalidParameterValueException("AddIpToVMNic is not supported in this network..."); + s_logger.error("AddIpToVMNic is not supported in this network..."); + return null; } if (ipaddr != null) { @@ -549,18 +586,18 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { boolean success = false; // Verify input parameters - NicSecondaryIpVO ipVO= _nicSecondaryIpDao.findById(ipAddressId); - if (ipVO == null) { + NicSecondaryIpVO secIpVO= _nicSecondaryIpDao.findById(ipAddressId); + if (secIpVO == null) { throw new InvalidParameterValueException("Unable to find ip address by id"); } - Network network = _networksDao.findById(ipVO.getNetworkId()); + Network network = _networksDao.findById(secIpVO.getNetworkId()); // verify permissions _accountMgr.checkAccess(caller, null, true, network); - Long nicId = ipVO.getNicId(); - s_logger.debug("ip id and nic id" + ipAddressId + "..." + nicId); + Long nicId = secIpVO.getNicId(); + s_logger.debug("ip id = " + ipAddressId + " nic id = " + nicId); //check is this the last secondary ip for NIC List ipList = _nicSecondaryIpDao.listByNicId(nicId); boolean lastIp = false; @@ -568,20 +605,41 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // this is the last secondary ip to nic lastIp = true; } - //check PF or static NAT is configured on this ip address - String secondaryIp = ipVO.getIp4Address(); - List pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp); - if (pfRuleList.size() != 0) { - s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule"); - throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule"); + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + if (dc == null) { + throw new InvalidParameterValueException("Invalid zone Id is given"); } - //check if the secondary ip associated with any static nat rule - IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp); - if (publicIpVO != null) { - s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId()); - throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId()); + + s_logger.debug("Calling the ip allocation ..."); + if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) { + //check PF or static NAT is configured on this ip address + String secondaryIp = secIpVO.getIp4Address(); + List pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp); + if (pfRuleList.size() != 0) { + s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule"); + throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule"); + } + //check if the secondary ip associated with any static nat rule + IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp); + if (publicIpVO != null) { + s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId()); + throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId()); + } + } else if (dc.getNetworkType() == NetworkType.Basic) { + IPAddressVO ip = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address()); + if (ip != null) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + _networkMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + txn.commit(); + } + } else if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && dc.getNetworkType() == NetworkType.Advanced) { + throw new InvalidParameterValueException("Not supported for this network now"); } - success = removeNicSecondaryIP(ipVO, lastIp); + + success = removeNicSecondaryIP(secIpVO, lastIp); return success; } diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index 1052639ebf2..3d588fa9307 100755 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -66,4 +66,6 @@ public interface IPAddressDao extends GenericDao { IPAddressVO findByVmIp(String vmIp); IPAddressVO findByAssociatedVmIdAndVmIp(long vmId, String vmIp); + + IPAddressVO findByIpAndNetworkId(long networkId, String ipAddress); } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index b0eef4f3043..73f310fd628 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -184,6 +184,14 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen return findOneBy(sc); } + @Override + public IPAddressVO findByIpAndNetworkId(long networkId, String ipAddress) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("ipAddress", ipAddress); + return findOneBy(sc); + } + @Override public IPAddressVO findByIpAndDcId(long dcId, String ipAddress) { SearchCriteria sc = AllFieldsSearch.create(); diff --git a/server/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java b/server/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java new file mode 100644 index 00000000000..42a9e421485 --- /dev/null +++ b/server/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java @@ -0,0 +1,35 @@ +// 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.dao; + +import java.util.List; + +import com.cloud.network.LBHealthCheckPolicyVO; +import com.cloud.utils.db.GenericDao; + + +public interface LBHealthCheckPolicyDao extends + GenericDao { + void remove(long loadBalancerId); + + void remove(long loadBalancerId, Boolean pending); + + List listByLoadBalancerId(long loadBalancerId); + + List listByLoadBalancerId(long loadBalancerId, + boolean revoke); +} diff --git a/server/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java b/server/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java new file mode 100644 index 00000000000..65e0689e79a --- /dev/null +++ b/server/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java @@ -0,0 +1,71 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.network.LBHealthCheckPolicyVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchCriteria; + + +@Component +@Local(value = { LBHealthCheckPolicyDao.class }) +public class LBHealthCheckPolicyDaoImpl extends + GenericDaoBase implements + LBHealthCheckPolicyDao { + + @Override + public void remove(long loadBalancerId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + + expunge(sc); + } + + @Override + public void remove(long loadBalancerId, Boolean revoke) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke); + + expunge(sc); + } + + @Override + public List listByLoadBalancerId(long loadBalancerId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + + return listBy(sc); + } + + @Override + public List listByLoadBalancerId(long loadBalancerId, + boolean pending) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("revoke", SearchCriteria.Op.EQ, pending); + + return listBy(sc); + } + +} diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java b/server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java index 8856993a982..852302e0949 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java +++ b/server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java @@ -39,10 +39,14 @@ public class LoadBalancerVMMapVO implements InternalIdentity { @Column(name="instance_id") private long instanceId; - @Column(name="revoke") + @Column(name = "revoke") private boolean revoke = false; - public LoadBalancerVMMapVO() { } + @Column(name = "state") + private String state; + + public LoadBalancerVMMapVO() { + } public LoadBalancerVMMapVO(long loadBalancerId, long instanceId) { this.loadBalancerId = loadBalancerId; @@ -74,4 +78,12 @@ public class LoadBalancerVMMapVO implements InternalIdentity { public void setRevoke(boolean revoke) { this.revoke = revoke; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 500d0b68ece..169db3283e3 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElement import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd; import org.apache.log4j.Logger; +import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; @@ -363,7 +364,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } } else { - return true; + return false; } } @@ -938,4 +939,11 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl protected VirtualRouterProviderType getVirtualRouterProvider() { return VirtualRouterProviderType.VirtualRouter; } + + @Override + public List updateHealthChecks(Network network, + List lbrules) { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index 46a525e214a..8707cfd418c 100755 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.network.guru; +import java.util.List; + import javax.ejb.Local; import javax.inject.Inject; @@ -54,7 +56,9 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.vm.Nic.ReservationStrategy; +import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.NicProfile; +import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -79,7 +83,9 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { UserIpv6AddressDao _ipv6Dao; @Inject Ipv6AddressManager _ipv6Mgr; - + @Inject + NicSecondaryIpDao _nicSecondaryIpDao; + private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; @Override @@ -230,6 +236,16 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { txn.start(); _networkMgr.markIpAsUnavailable(ip.getId()); _ipAddressDao.unassignIpAddress(ip.getId()); + //unassign nic secondary ip address + s_logger.debug("remove nic " + nic.getId() + " secondary ip "); + List nicSecIps = null; + nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId()); + for (String secIp: nicSecIps) { + IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp); + _networkMgr.markIpAsUnavailable(pubIp.getId()); + _ipAddressDao.unassignIpAddress(pubIp.getId()); + } + txn.commit(); } } diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManager.java b/server/src/com/cloud/network/lb/LBHealthCheckManager.java new file mode 100644 index 00000000000..2e24965aa35 --- /dev/null +++ b/server/src/com/cloud/network/lb/LBHealthCheckManager.java @@ -0,0 +1,24 @@ +// 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.lb; + + +public interface LBHealthCheckManager { + + void updateLBHealthCheck(); + +} diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java new file mode 100644 index 00000000000..90547328714 --- /dev/null +++ b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java @@ -0,0 +1,110 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.lb; + +import static java.lang.String.format; + +import java.util.Map; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.concurrency.NamedThreadFactory; + +@Component +@Local(value = {LBHealthCheckManager.class}) +public class LBHealthCheckManagerImpl extends ManagerBase implements LBHealthCheckManager, Manager { + private static final Logger s_logger = Logger.getLogger(LBHealthCheckManagerImpl.class); + + @Inject + ConfigurationDao _configDao; + @Inject + LoadBalancingRulesService _lbService; + + private String name; + private Map _configs; + ScheduledExecutorService _executor; + + private long _interval; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _configs = _configDao.getConfiguration("management-server", params); + if (s_logger.isInfoEnabled()) { + s_logger.info(format("Configuring LBHealthCheck Manager %1$s", name)); + } + this.name = name; + _interval = NumbersUtil.parseLong(_configs.get(Config.LBHealthCheck.key()), 600); + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("LBHealthCheck")); + return true; + } + + @Override + public boolean start() { + s_logger.debug("LB HealthCheckmanager is getting Started"); + _executor.scheduleAtFixedRate(new UpdateLBHealthCheck(), 10, _interval, TimeUnit.SECONDS); + return true; + } + + @Override + public boolean stop() { + s_logger.debug("HealthCheckmanager is getting Stopped"); + _executor.shutdown(); + return true; + } + + @Override + public String getName() { + return this.name; + } + + protected class UpdateLBHealthCheck implements Runnable { + @Override + public void run() { + try { + updateLBHealthCheck(); + } catch (Exception e) { + s_logger.error("Exception in LB HealthCheck Update Checker", e); + } + } + } + + @Override + public void updateLBHealthCheck() { + try { + _lbService.updateLBHealthChecks(); + } catch (ResourceUnavailableException e) { + s_logger.debug("Error while updating the LB HealtCheck ", e); + } + s_logger.debug("LB HealthCheck Manager is running and getting the updates from LB providers and updating service status"); + } + +} diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java index 9d7d22fdad7..da19f86c21f 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java @@ -20,6 +20,7 @@ import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; @@ -38,6 +39,7 @@ public interface LoadBalancingRulesManager extends LoadBalancingRulesService { List getExistingDestinations(long lbId); List getStickinessPolicies(long lbId); List getStickinessMethods(long networkid); + List getHealthCheckPolicies(long lbId); /** * Remove vm from all load balancers diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 531a42805b6..890e776974c 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -16,32 +16,7 @@ // under the License. package com.cloud.network.lb; -import java.security.InvalidParameterException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; -import javax.inject.Inject; - -import com.cloud.event.UsageEventUtils; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.springframework.stereotype.Component; - +import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; @@ -52,67 +27,24 @@ 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.UsageEventUtils; 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.IpAddress; -import com.cloud.network.Network; +import com.cloud.exception.*; +import com.cloud.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.NetworkModel; -import com.cloud.network.NetworkRuleApplier; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScalePolicyConditionMapVO; -import com.cloud.network.as.AutoScaleVmGroup; -import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; -import com.cloud.network.as.AutoScaleVmGroupVO; -import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.*; 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.IPAddressVO; -import com.cloud.network.dao.LBStickinessPolicyDao; -import com.cloud.network.dao.LBStickinessPolicyVO; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.LoadBalancerVMMapDao; -import com.cloud.network.dao.LoadBalancerVMMapVO; -import com.cloud.network.dao.LoadBalancerVO; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.NetworkVO; +import com.cloud.network.as.dao.*; +import com.cloud.network.dao.*; import com.cloud.network.element.LoadBalancingServiceProvider; -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.lb.LoadBalancingRule.*; +import com.cloud.network.rules.*; 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.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -121,24 +53,14 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.VMTemplateDao; 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.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; -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.db.*; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; @@ -148,10 +70,21 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.command.user.loadbalancer.*; +import org.apache.cloudstack.api.response.ServiceResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.security.InvalidParameterException; +import java.util.*; @Component @Local(value = { LoadBalancingRulesManager.class, LoadBalancingRulesService.class }) -public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService, NetworkRuleApplier { +public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, + LoadBalancingRulesService, NetworkRuleApplier { private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class); @Inject @@ -175,6 +108,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Inject LBStickinessPolicyDao _lb2stickinesspoliciesDao; @Inject + LBHealthCheckPolicyDao _lb2healthcheckDao; + @Inject UserVmDao _vmDao; @Inject AccountDao _accountDao; @@ -199,7 +134,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Inject ExternalLoadBalancerUsageManager _externalLBUsageMgr; - @Inject + @Inject NetworkServiceMapDao _ntwkSrvcDao; @Inject ResourceTagDao _resourceTagDao; @@ -229,9 +164,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements DataCenterDao _dcDao = null; @Inject UserDao _userDao; - @Inject List _lbProviders; + @Inject + List _lbProviders; - // Will return a string. For LB Stickiness this will be a json, for autoscale this will be "," separated values + // 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 = _networkModel.getNetworkCapabilities(networkid); @@ -240,11 +177,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements ServiceResponse serviceResponse = new ServiceResponse(); serviceResponse.setName(service.getName()); if ("Lb".equalsIgnoreCase(service.getName())) { - Map serviceCapabilities = serviceCapabilitiesMap - .get(service); + Map serviceCapabilities = serviceCapabilitiesMap.get(service); if (serviceCapabilities != null) { - for (Capability capability : serviceCapabilities - .keySet()) { + for (Capability capability : serviceCapabilities.keySet()) { if (capabilityName.equals(capability.getName())) { return serviceCapabilities.get(capability); } @@ -255,14 +190,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } return null; } + private LbAutoScaleVmGroup getLbAutoScaleVmGroup(AutoScaleVmGroupVO vmGroup, String currentState, LoadBalancerVO lb) { long lbNetworkId = lb.getNetworkId(); String lbName = lb.getName(); - List vmGroupPolicyMapList = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(vmGroup.getId()); + 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 autoScalePolicyConditionMapList = _autoScalePolicyConditionMapDao + .listByAll(autoScalePolicy.getId(), null); List lbConditions = new ArrayList(); for (AutoScalePolicyConditionMapVO autoScalePolicyConditionMap : autoScalePolicyConditionMapList) { Condition condition = _conditionDao.findById(autoScalePolicyConditionMap.getConditionId()); @@ -296,32 +234,39 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } } - if (apiKey == null) { - throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it"); + throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + + " is empty. Please generate it"); } if (secretKey == null) { - throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it"); + throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + + " is empty. Please generate it"); } if (csUrl == null || csUrl.contains("localhost")) { - throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point"); + throw new InvalidParameterValueException( + "Global setting endpointe.url has to be set to the Management Server's API end point"); } - - LbAutoScaleVmProfile lbAutoScaleVmProfile = new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, csUrl, zoneId, domainId, serviceOfferingId, templateId, vmName, lbNetworkUuid); + LbAutoScaleVmProfile lbAutoScaleVmProfile = new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, + csUrl, zoneId, domainId, serviceOfferingId, templateId, vmName, lbNetworkUuid); return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, lbAutoScaleVmProfile, currentState); } - private boolean applyAutoScaleConfig(LoadBalancerVO lb, AutoScaleVmGroupVO vmGroup, String currentState) throws ResourceUnavailableException { + private boolean applyAutoScaleConfig(LoadBalancerVO lb, AutoScaleVmGroupVO vmGroup, String currentState) + throws ResourceUnavailableException { LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup, currentState, lb); - /* Regular config like destinations need not be packed for applying autoscale config as of today.*/ - LoadBalancingRule rule = new LoadBalancingRule(lb, null, null); + /* + * Regular config like destinations need not be packed for applying + * autoscale config as of today. + */ + LoadBalancingRule rule = new LoadBalancingRule(lb, null, null, null); rule.setAutoScaleVmGroup(lbAutoScaleVmGroup); if (!isRollBackAllowedForProvider(lb)) { - // this is for Netscaler type of devices. if their is failure the db entries will be rollbacked. + // this is for Netscaler type of devices. if their is failure the db + // entries will be rollbacked. return false; } @@ -348,9 +293,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) { loadBalancer.setState(FirewallRule.State.Add); _lbDao.persist(loadBalancer); - } - else if (loadBalancer.getState() == FirewallRule.State.Active && - vmGroup.getState().equals(AutoScaleVmGroup.State_Revoke)) { + } else if (loadBalancer.getState() == FirewallRule.State.Active + && vmGroup.getState().equals(AutoScaleVmGroup.State_Revoke)) { loadBalancer.setState(FirewallRule.State.Add); _lbDao.persist(loadBalancer); } @@ -358,11 +302,13 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements try { success = applyAutoScaleConfig(loadBalancer, vmGroup, currentState); } catch (ResourceUnavailableException e) { - s_logger.warn("Unable to configure AutoScaleVmGroup to the lb rule: " + loadBalancer.getId() + " because resource is unavaliable:", 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"); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + + " lb state rolback while creating AutoscaleVmGroup"); } throw e; } finally { @@ -387,15 +333,24 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return success; } + private boolean validateHealthCheck(CreateLBHealthCheckPolicyCmd cmd) { + LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); + String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.HealthCheckPolicy.getName()); + if (capability != null) { + return true; + } + return false; + } + 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()); + List stickinessMethodList = getStickinessMethods(loadBalancer.getNetworkId()); boolean methodMatch = false; if (stickinessMethodList == null) { - throw new InvalidParameterValueException("Failed: No Stickiness method available for LB rule:" + cmd.getLbRuleId()); + throw new InvalidParameterValueException("Failed: No Stickiness method available for LB rule:" + + cmd.getLbRuleId()); } for (LbStickinessMethod method : stickinessMethodList) { if (method.getMethodName().equalsIgnoreCase(cmd.getStickinessMethodName())) { @@ -422,14 +377,16 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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()); + throw new InvalidParameterValueException("Failed : Value expected for the Param :" + + param.getParamName()); } found = true; break; } } if (!found) { - throw new InvalidParameterValueException("Failed : Stickiness policy does not support param name :" + paramName); + throw new InvalidParameterValueException( + "Failed : Stickiness policy does not support param name :" + paramName); } } } @@ -438,7 +395,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements for (LbStickinessMethodParam param : methodParamList) { if (param.getRequired()) { if (tempParamList.get(param.getParamName()) == null) { - throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + param.getParamName()); + throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + + param.getParamName()); } } } @@ -447,13 +405,16 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } } if (methodMatch == false) { - throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule:" + cmd.getLbRuleId()); + throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule:" + + cmd.getLbRuleId()); } /* Validation : check for the multiple policies to the rule id */ - List stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false); + List stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId( + cmd.getLbRuleId(), false); if (stickinessPolicies.size() > 0) { - throw new InvalidParameterValueException("Failed to create Stickiness policy: Already policy attached " + cmd.getLbRuleId()); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Already policy attached " + + cmd.getLbRuleId()); } return true; } @@ -462,7 +423,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @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 { + public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) + throws NetworkRuleConflictException { UserContext caller = UserContext.current(); /* Validation : check corresponding load balancer rule exist */ @@ -473,30 +435,108 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); if (loadBalancer.getState() == FirewallRule.State.Revoke) { - throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " is in deleting state: "); + throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + + " is in deleting state: "); } /* Generic validations */ if (!genericValidator(cmd)) { - throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId()); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + + cmd.getLbRuleId()); } - /* Specific validations using network element validator for specific validations */ - LBStickinessPolicyVO lbpolicy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); + /* + * 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); + LoadBalancingRule lbRule = new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), + policyList, null); if (!validateRule(lbRule)) { - throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId()); + throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + + cmd.getLbRuleId()); } /* Finally Insert into DB */ - LBStickinessPolicyVO policy = new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); + 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_HEALTHCHECKPOLICY_CREATE, eventDescription = "create load balancer health check to load balancer", create = true) + public HealthCheckPolicy createLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) { + UserContext caller = UserContext.current(); + + /* + * Validation of cmd Monitor interval must be greater than response + * timeout + */ + Map paramMap = cmd.getFullUrlParams(); + + if (paramMap.containsKey(ApiConstants.HEALTHCHECK_RESPONSE_TIMEOUT) + && paramMap.containsKey(ApiConstants.HEALTHCHECK_INTERVAL_TIME)) { + if (cmd.getResponsTimeOut() > cmd.getHealthCheckInterval()) + throw new InvalidParameterValueException( + "Failed to create HealthCheck policy : Monitor interval must be greater than response timeout"); + } + /* Validation : check corresponding load balancer rule exist */ + LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); + if (loadBalancer == null) { + throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " not present "); + } + + _accountMgr.checkAccess(caller.getCaller(), null, true, loadBalancer); + + if (loadBalancer.getState() == FirewallRule.State.Revoke) { + throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + + " is in deleting state: "); + } + + /* + * Validate Whether LB Provider has the capabilities to support Health + * Checks + */ + if (!validateHealthCheck(cmd)) { + throw new InvalidParameterValueException( + "Failed to create HealthCheck policy: Validation Failed (HealthCheck Policy is not supported by LB Provider for the LB rule id :)" + + cmd.getLbRuleId()); + } + + /* Validation : check for the multiple hc policies to the rule id */ + List hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(cmd.getLbRuleId(), false); + if (hcPolicies.size() > 0) { + throw new InvalidParameterValueException( + "Failed to create HealthCheck policy: Already policy attached for the LB Rule id :" + + cmd.getLbRuleId()); + } + /* + * Specific validations using network element validator for specific + * validations + */ + LBHealthCheckPolicyVO hcpolicy = new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), + cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(), cmd.getHealthyThreshold(), + cmd.getUnhealthyThreshold()); + + List hcPolicyList = new ArrayList(); + hcPolicyList.add(new LbHealthCheckPolicy(hcpolicy.getpingpath(), hcpolicy.getDescription(), hcpolicy + .getResponseTime(), hcpolicy.getHealthcheckInterval(), hcpolicy.getHealthcheckThresshold(), hcpolicy + .getUnhealthThresshold())); + + // Finally Insert into DB + LBHealthCheckPolicyVO policy = new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), + cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(), cmd.getHealthyThreshold(), + cmd.getUnhealthyThreshold()); + + policy = _lb2healthcheckDao.persist(policy); + return policy; + } private boolean validateRule(LoadBalancingRule lbRule) { Network network = _networkDao.findById(lbRule.getNetworkId()); @@ -506,7 +546,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return false; } for (LoadBalancingServiceProvider ne : _lbProviders) { - boolean validated = ne.validateLBRule(network, lbRule); + boolean validated = ne.validateLBRule(network, lbRule); if (!validated) return false; } @@ -521,7 +561,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); if (loadBalancer == null) { - throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId()); + throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId()); } FirewallRule.State backupState = loadBalancer.getState(); loadBalancer.setState(FirewallRule.State.Add); @@ -529,11 +569,13 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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); + 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"); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + + " lb state rolback while creating sticky policy"); } deleteLBStickinessPolicy(cmd.getEntityId(), false); success = false; @@ -542,6 +584,36 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return success; } + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE, eventDescription = "Apply HealthCheckPolicy to load balancer ", async = true) + public boolean applyLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd 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 healthcheck 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 healthcheck policy"); + } + deleteLBHealthCheckPolicy(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) { @@ -555,13 +627,13 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(stickinessPolicy.getLoadBalancerId())); if (loadBalancer == null) { - throw new InvalidParameterException("Invalid Load balancer : " + stickinessPolicy.getLoadBalancerId() + " for Stickiness policy id: " + stickinessPolicyId); + 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); @@ -571,12 +643,15 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements boolean backupStickyState = stickinessPolicy.isRevoke(); stickinessPolicy.setRevoke(true); _lb2stickinesspoliciesDao.persist(stickinessPolicy); - s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", stickinesspolicyID " + stickinessPolicyId); + 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); + 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)) { @@ -584,7 +659,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements _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.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; @@ -592,9 +668,149 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } else { _lb2stickinesspoliciesDao.remove(stickinessPolicy.getLoadBalancerId()); } - return success; - } + } + + @DB + @Override + @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_DELETE, eventDescription = "revoking LB HealthCheck policy ", async = true) + public boolean deleteLBHealthCheckPolicy(long healthCheckPolicyId, boolean apply) { + boolean success = true; + + UserContext caller = UserContext.current(); + LBHealthCheckPolicyVO healthCheckPolicy = _lb2healthcheckDao.findById(healthCheckPolicyId); + + if (healthCheckPolicy == null) { + throw new InvalidParameterException("Invalid HealthCheck policy id value: " + healthCheckPolicyId); + } + LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(healthCheckPolicy.getLoadBalancerId())); + if (loadBalancer == null) { + throw new InvalidParameterException("Invalid Load balancer : " + healthCheckPolicy.getLoadBalancerId() + + " for HealthCheck policy id: " + healthCheckPolicyId); + } + 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 = healthCheckPolicy.isRevoke(); + healthCheckPolicy.setRevoke(true); + _lb2healthcheckDao.persist(healthCheckPolicy); + s_logger.debug("Set health check policy to revoke for loadbalancing rule id : " + loadBalancerId + + ", healthCheckpolicyID " + healthCheckPolicyId); + + // removing the state of services set by the monitor. + List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + if (maps != null) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + s_logger.debug("Resetting health state policy for services in loadbalancing rule id : " + + loadBalancerId); + for (LoadBalancerVMMapVO map : maps) { + map.setState(null); + _lb2VmMapDao.persist(map); + } + txn.commit(); + } + + try { + if (!applyLoadBalancerConfig(loadBalancerId)) { + s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + + " for healthCheckpolicyID " + healthCheckPolicyId); + throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + + " for healthCheckpolicyID " + healthCheckPolicyId); + } + } catch (ResourceUnavailableException e) { + if (isRollBackAllowedForProvider(loadBalancer)) { + healthCheckPolicy.setRevoke(backupStickyState); + _lb2healthcheckDao.persist(healthCheckPolicy); + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + + " while deleting healthcheck policy: " + healthCheckPolicyId); + } + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + success = false; + } + } else { + _lb2healthcheckDao.remove(healthCheckPolicy.getLoadBalancerId()); + } + return success; + } + + // This method will check the status of services which has monitors created + // by CloudStack and update them in lbvmmap table + @DB + @Override + public void updateLBHealthChecks() throws ResourceUnavailableException { + List rules = _lbDao.listAll(); + List networks = _networkDao.listAll(); + List stateRules = null; + boolean isHandled = false; + for (NetworkVO ntwk : networks) { + Network network = _networkDao.findById(ntwk.getId()); + String capability = getLBCapability(network.getId(), Capability.HealthCheckPolicy.getName()); + + if (capability != null && capability.equalsIgnoreCase("true")) { + /* + * s_logger.debug( + * "HealthCheck Manager :: LB Provider in the Network has the Healthcheck policy capability :: " + * + provider.get(0).getName()); + */ + rules = _lbDao.listByNetworkId(network.getId()); + if (rules != null && rules.size() > 0) { + List lbrules = new ArrayList(); + for (LoadBalancerVO lb : rules) { + List dstList = getExistingDestinations(lb.getId()); + List hcPolicyList = getHealthCheckPolicies(lb.getId()); + // adding to lbrules list only if the LB rule + // hashealtChecks + if (hcPolicyList != null && hcPolicyList.size() > 0) { + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList); + lbrules.add(loadBalancing); + } + } + if (lbrules.size() > 0) { + isHandled = false; + for (LoadBalancingServiceProvider lbElement : _lbProviders) { + stateRules = lbElement.updateHealthChecks(network, (List) lbrules); + if (stateRules != null && stateRules.size() > 0) { + for (LoadBalancerTO lbto : stateRules) { + LoadBalancerVO ulb = _lbDao.findByUuid(lbto.getUuid()); + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(ulb.getId()); + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); + Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved( + ulb.getNetworkId(), vm.getId()); + String dstIp = nic.getIp4Address(); + for (int i = 0; i < lbto.getDestinations().length; i++) { + LoadBalancerTO.DestinationTO des = lbto.getDestinations()[i]; + if (dstIp.equalsIgnoreCase(lbto.getDestinations()[i].getDestIp())) { + lbVmMap.setState(des.getMonitorState()); + _lb2VmMapDao.persist(lbVmMap); + s_logger.debug("Updating the LB VM Map table with the service state"); + } + } + } + } + isHandled = true; + } + if (isHandled) { + break; + } + } + } + } + } else { + // s_logger.debug("HealthCheck Manager :: LB Provider in the Network DNOT the Healthcheck policy capability "); + } + } + } private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) { Network network = _networkDao.findById(loadBalancer.getNetworkId()); @@ -607,6 +823,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } return false; } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true) @@ -616,7 +833,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); if (loadBalancer == null) { - throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found."); + throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + + ", the load balancer was not found."); } List mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false); @@ -635,7 +853,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements UserVm vm = _vmDao.findById(instanceId); if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified"); - ex.addProxyObject(vm, instanceId, "instanceId"); + ex.addProxyObject(vm, instanceId, "instanceId"); throw ex; } @@ -645,7 +863,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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. + // Let's check to make sure the vm has a nic in the same network as + // the load balancing rule. List nics = _networkModel.getNics(vm.getId()); Nic nicInSameNetwork = null; for (Nic nic : nics) { @@ -656,8 +875,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } if (nicInSameNetwork == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("VM " + instanceId + " cannot be added because it doesn't belong in the same network."); - ex.addProxyObject(vm, instanceId, "instanceId"); + InvalidParameterValueException ex = new InvalidParameterValueException("VM " + instanceId + + " cannot be added because it doesn't belong in the same network."); + ex.addProxyObject(vm, instanceId, "instanceId"); throw ex; } @@ -698,7 +918,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements txn.commit(); if (!vmInstanceIds.isEmpty()) { _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null); - s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while attaching VM: " + vmInstanceIds); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while attaching VM: " + + vmInstanceIds); } loadBalancer.setState(backupState); _lbDao.persist(loadBalancer); @@ -707,9 +928,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } if (!success) { - CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + instanceIds); - ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); - // TBD: Also pack in the instanceIds in the exception using the right VO object or table name. + CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + // TBD: Also pack in the instanceIds in the exception using the + // right VO object or table name. throw ex; } @@ -748,15 +971,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { // For autoscaled loadbalancer, the rules need not be applied, // meaning the call need not reach the resource layer. - // We can consider the job done and only need to remove the rules in DB + // We can consider the job done and only need to remove the + // rules in DB _lb2VmMapDao.remove(loadBalancer.getId(), instanceIds, null); 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"); + CloudRuntimeException ex = new CloudRuntimeException( + "Failed to remove specified load balancer rule id for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); throw ex; } success = true; @@ -777,8 +1002,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); } if (!success) { - CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); - ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + CloudRuntimeException ex = new CloudRuntimeException( + "Failed to remove specified load balancer rule id for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); throw ex; } return success; @@ -806,7 +1032,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements map.setRevoke(true); _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + instanceId); + s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + + instanceId); } // Reapply all lbs that had the vm assigned @@ -827,10 +1054,10 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements Account caller = ctx.getCaller(); LoadBalancerVO rule = _lbDao.findById(loadBalancerId); + if (rule == null) { throw new InvalidParameterValueException("Unable to find load balancer rule " + loadBalancerId); } - _accountMgr.checkAccess(caller, null, true, rule); boolean result = deleteLoadBalancerRule(loadBalancerId, apply, caller, ctx.getCallerUserId(), true); @@ -841,7 +1068,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @DB - public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) { + 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; @@ -865,10 +1093,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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()); + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + + map.getInstanceId()); } } + List hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(loadBalancerId); + for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) { + lbHealthCheck.setRevoke(true); + _lb2healthcheckDao.persist(lbHealthCheck); + } + if (generateUsageEvent) { // Generate usage event right after all rules were marked for revoke UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), @@ -890,7 +1125,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { // Get the associated VmGroup AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.listByAll(loadBalancerId, null).get(0); - if (!applyAutoScaleConfig(lb, vmGroup,vmGroup.getState())) { + if (!applyAutoScaleConfig(lb, vmGroup, vmGroup.getState())) { s_logger.warn("Unable to apply the autoscale config"); return false; } @@ -920,15 +1155,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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"); + 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); } - // FIXME: breaking the dependency on ELB manager. This breaks functionality of ELB using virtual router + // FIXME: breaking the dependency on ELB manager. This breaks + // functionality of ELB using virtual router // Bug CS-15411 opened to document this - //_elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); + // _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); if (success) { s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); @@ -939,7 +1176,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Override @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer") - public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException { + public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) + throws NetworkRuleConflictException, InsufficientAddressCapacityException { Account lbOwner = _accountMgr.getAccount(lb.getEntityOwnerId()); int defPortStart = lb.getDefaultPortStart(); @@ -949,7 +1187,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortEnd); } if (defPortStart > defPortEnd) { - throw new InvalidParameterValueException("private port range is invalid: " + defPortStart + "-" + defPortEnd); + throw new InvalidParameterValueException("private port range is invalid: " + defPortStart + "-" + + defPortEnd); } if ((lb.getAlgorithm() == null) || !NetUtils.isValidAlgorithm(lb.getAlgorithm())) { throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm()); @@ -963,9 +1202,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements Network network = _networkModel.getNetwork(lb.getNetworkId()); - // FIXME: breaking the dependency on ELB manager. This breaks functionality of ELB using virtual router + // FIXME: breaking the dependency on ELB manager. This breaks + // functionality of ELB using virtual router // Bug CS-15411 opened to document this - //LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId()); + // LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, + // lbOwner, lb.getNetworkId()); LoadBalancer result = null; if (result == null) { IpAddress systemIp = null; @@ -978,7 +1219,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements // Validate ip address if (ipVO == null) { - throw new InvalidParameterValueException("Unable to create load balance rule; can't find/allocate source IP"); + throw new InvalidParameterValueException( + "Unable to create load balance rule; can't find/allocate source IP"); } else if (ipVO.isOneToOneNat()) { throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipVO.getAddress()); } @@ -986,13 +1228,14 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements boolean performedIpAssoc = false; try { if (ipVO.getAssociatedWithNetworkId() == null) { - boolean assignToVpcNtwk = network.getVpcId() != null - && ipVO.getVpcId() != null && ipVO.getVpcId().longValue() == network.getVpcId(); + boolean assignToVpcNtwk = network.getVpcId() != null && ipVO.getVpcId() != null + && ipVO.getVpcId().longValue() == network.getVpcId(); if (assignToVpcNtwk) { - //set networkId just for verification purposes + // set networkId just for verification purposes _networkModel.checkIpForService(ipVO, Service.Lb, lb.getNetworkId()); - s_logger.debug("The ip is not associated with the VPC network id="+ lb.getNetworkId() + " so assigning"); + 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; } @@ -1000,8 +1243,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements _networkModel.checkIpForService(ipVO, Service.Lb, null); } - if (ipVO.getAssociatedWithNetworkId() == null) { - throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + network); + if (ipVO.getAssociatedWithNetworkId() == null) { + throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + + network); } if (lb.getSourceIpAddressId() == null) { @@ -1015,7 +1259,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } } finally { if (result == null && systemIp != null) { - s_logger.debug("Releasing system IP address " + systemIp + " as corresponding lb rule failed to create"); + 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 @@ -1035,7 +1280,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Override @DB - public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException { + public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) + throws NetworkRuleConflictException { UserContext caller = UserContext.current(); int srcPortStart = lb.getSourcePortStart(); int defPortStart = lb.getDefaultPortStart(); @@ -1045,45 +1291,48 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); // make sure ip address exists if (ipAddr == null || !ipAddr.readyToUse()) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "Unable to create load balancer rule, invalid IP address id specified"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } else if (ipAddr.isOneToOneNat()) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "Unable to create load balancer rule; specified sourceip id has static nat enabled"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } Long networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "Unable to create load balancer rule ; specified sourceip id is not associated with any network"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; - } _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), Purpose.LoadBalancing, FirewallRuleType.User, networkId, null); - NetworkVO network = _networkDao.findById(networkId); - _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr); // verify that lb service is supported by the network if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id"); - ex.addProxyObject(network, networkId, "networkId"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "LB service is not supported in specified network id"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } 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()); + LoadBalancerVO newRule = new LoadBalancerVO(lb.getXid(), lb.getName(), lb.getDescription(), + lb.getSourceIpAddressId(), lb.getSourcePortEnd(), lb.getDefaultPortStart(), lb.getAlgorithm(), + network.getId(), ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); // verify rule is supported by Lb provider of the network - LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), new ArrayList()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), + new ArrayList(), new ArrayList()); if (!validateRule(loadBalancing)) { throw new InvalidParameterValueException("LB service provider cannot support this rule"); } @@ -1091,7 +1340,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements newRule = _lbDao.persist(newRule); if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); } @@ -1102,10 +1351,12 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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."); + 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()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), - ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), newRule.getUuid()); + ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), + newRule.getUuid()); txn.commit(); return newRule; @@ -1131,8 +1382,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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. + 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 @@ -1153,13 +1405,14 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @Override - public boolean applyRules(Network network, Purpose purpose, List rules) + public boolean applyRules(Network network, Purpose purpose, List rules) throws ResourceUnavailableException { - assert(purpose == Purpose.LoadBalancing): "LB Manager asked to handle non-LB rules"; + assert (purpose == Purpose.LoadBalancing) : "LB Manager asked to handle non-LB rules"; boolean handled = false; - for (LoadBalancingServiceProvider lbElement: _lbProviders) { + for (LoadBalancingServiceProvider lbElement : _lbProviders) { Provider provider = lbElement.getProvider(); - boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider); + boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, + provider); if (!isLbProvider) { continue; } @@ -1171,14 +1424,16 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @DB - protected boolean applyLoadBalancerRules(List lbs, boolean updateRulesInDB) throws ResourceUnavailableException { + 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()); + List hcPolicyList = getHealthCheckPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); rules.add(loadBalancing); } @@ -1217,18 +1472,28 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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"); + 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); + 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(); + // remove LB-HealthCheck policy mapping that were state to + // revoke + List healthCheckpolicies = _lb2healthcheckDao.listByLoadBalancerId(lb.getId(), + true); + if (!healthCheckpolicies.isEmpty()) { + _lb2healthcheckDao.remove(lb.getId(), true); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies"); + } + txn.commit(); if (checkForReleaseElasticIp) { boolean success = true; long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId()); @@ -1236,7 +1501,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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); + 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) { @@ -1245,7 +1511,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } } } - // if the rule is the last one for the ip address assigned to VPC, unassign it from the network + // if the rule is the last one for the ip address assigned to + // VPC, unassign it from the network IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId()); _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), lb.getNetworkId()); } @@ -1259,14 +1526,16 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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"); + 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"); + s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + + " as a part of delete lb rule"); } } - return success; } @@ -1287,7 +1556,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Override public boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId) { - List rules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing); + List rules = _firewallDao + .listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing); if (rules != null) s_logger.debug("Found " + rules.size() + " lb rules to cleanup"); for (FirewallRule rule : rules) { @@ -1306,12 +1576,28 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements List sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lbId); for (LBStickinessPolicyVO sDbPolicy : sDbpolicies) { - LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), sDbPolicy.isRevoke()); + LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), + sDbPolicy.isRevoke()); stickinessPolicies.add(sPolicy); } return stickinessPolicies; } + @Override + public List getHealthCheckPolicies(long lbId) { + List healthCheckPolicies = new ArrayList(); + List hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerId(lbId); + + for (LBHealthCheckPolicyVO policy : hcDbpolicies) { + String pingpath = policy.getpingpath(); + LbHealthCheckPolicy hDbPolicy = new LbHealthCheckPolicy(pingpath, policy.getDescription(), + policy.getResponseTime(), policy.getHealthcheckInterval(), policy.getHealthcheckThresshold(), + policy.getUnhealthThresshold(), policy.isRevoke()); + healthCheckPolicies.add(hDbPolicy); + } + return healthCheckPolicies; + } + @Override public List getExistingDestinations(long lbId) { List dstList = new ArrayList(); @@ -1323,7 +1609,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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()); + LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, + lbVmMap.isRevoke()); dstList.add(lbDst); } return dstList; @@ -1369,16 +1656,19 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements applyLoadBalancerConfig(lbRuleId); } catch (ResourceUnavailableException e) { if (isRollBackAllowedForProvider(lb)) { - /* NOTE : We use lb object to update db instead of lbBackup object since db layer will fail to update if there is no change in the object. + /* + * NOTE : We use lb object to update db instead of lbBackup + * object since db layer will fail to update if there is no + * change in the object. */ if (lbBackup.getName() != null) { - lb.setName(lbBackup.getName()); + lb.setName(lbBackup.getName()); } if (lbBackup.getDescription() != null) { lb.setDescription(lbBackup.getDescription()); } if (lbBackup.getAlgorithm() != null) { - lb.setAlgorithm(lbBackup.getAlgorithm()); + lb.setAlgorithm(lbBackup.getAlgorithm()); } lb.setState(lbBackup.getState()); _lbDao.update(lb.getId(), lb); @@ -1399,7 +1689,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @Override - public List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) throws PermissionDeniedException { + public List listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) + throws PermissionDeniedException { Account caller = UserContext.current().getCaller(); Long loadBalancerId = cmd.getId(); Boolean applied = cmd.isApplied(); @@ -1428,10 +1719,12 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } IPAddressVO addr = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()); - List userVms = _vmDao.listVirtualNetworkInstancesByAcctAndZone(loadBalancer.getAccountId(), addr.getDataCenterId(), loadBalancer.getNetworkId()); + 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 + // 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: @@ -1449,10 +1742,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return loadBalancerInstances; } - @Override - public List getStickinessMethods(long networkid) - { + public List getStickinessMethods(long networkid) { String capability = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName()); if (capability == null) { return null; @@ -1465,7 +1756,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @Override - public List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException { + public List searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) + throws PermissionDeniedException { Account caller = UserContext.current().getCaller(); Long loadBalancerId = cmd.getLbRuleId(); LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); @@ -1480,6 +1772,20 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return sDbpolicies; } + @Override + public List searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd 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 hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerId(cmd.getLbRuleId()); + return hcDbpolicies; + } + @Override public Pair, Integer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) { Long ipId = cmd.getPublicIpId(); @@ -1493,8 +1799,10 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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); + 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(); @@ -1510,13 +1818,15 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements 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); + 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); + sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), + JoinBuilder.JoinType.INNER); } if (tags != null && !tags.isEmpty()) { @@ -1528,7 +1838,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } 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); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), + JoinBuilder.JoinType.INNER); } SearchCriteria sc = sb.create(); @@ -1561,7 +1872,6 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements sc.setJoinParameters("ipSearch", "zoneId", zoneId); } - if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); @@ -1583,7 +1893,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements for (LoadBalancerVO lb : lbs) { List dstList = getExistingDestinations(lb.getId()); List policyList = this.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + List hcPolicyList = this.getHealthCheckPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); lbRules.add(loadBalancing); } return lbRules; @@ -1594,10 +1905,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return _lbDao.findById(lbId); } - protected void removeLBRule(LoadBalancerVO rule) { - //remove the rule + protected void removeLBRule(LoadBalancerVO rule) { + // remove the rule _lbDao.remove(rule.getId()); } - - } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 3cbd51d4cc4..6742f7b378d 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -162,10 +162,12 @@ import com.cloud.network.dao.Site2SiteCustomerGatewayDao; import com.cloud.network.dao.Site2SiteVpnConnectionDao; import com.cloud.network.dao.Site2SiteVpnConnectionVO; import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.dao.UserIpv6AddressDao; 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.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualRouter.RedundantState; @@ -340,6 +342,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V Site2SiteVpnConnectionDao _s2sVpnConnectionDao; @Inject Site2SiteVpnManager _s2sVpnMgr; + @Inject + UserIpv6AddressDao _ipv6Dao; int _routerRamSize; @@ -1696,18 +1700,30 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V 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 = _networkModel.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"); - } + String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null; + if (!setupPublicNetwork) { + if (guestNetwork.getCidr() != null) { + String startIp = _networkModel.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"); + } + } + + if (guestNetwork.getIp6Cidr() != null) { + String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId()); + if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) { + defaultNetworkStartIpv6 = startIpv6; + } else if (s_logger.isDebugEnabled()){ + s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ipv6 address from the range"); + } + } } - NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, null); + NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6); if (setupPublicNetwork) { if (isRedundant) { gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); @@ -2367,11 +2383,12 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V for (LoadBalancerVO lb : lbs) { List dstList = _lbMgr.getExistingDestinations(lb.getId()); List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); 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); @@ -3269,7 +3286,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V for (LoadBalancerVO lb : lbs) { List dstList = _lbMgr.getExistingDestinations(lb.getId()); List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList,policyList); + List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId() ); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); lbRules.add(loadBalancing); } return sendLBRules(router, lbRules, network.getId()); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index eafe88e36a4..1c189c44688 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -46,8 +46,10 @@ import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupI import org.apache.commons.codec.digest.DigestUtils; import org.apache.log4j.Logger; +import com.amazonaws.services.identitymanagement.model.User; import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; +import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.manager.Commands; @@ -67,12 +69,6 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkModel; import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.network.security.SecurityRule.SecurityRuleType; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.security.dao.SecurityGroupRuleDao; -import com.cloud.network.security.dao.SecurityGroupRulesDao; -import com.cloud.network.security.dao.SecurityGroupVMMapDao; -import com.cloud.network.security.dao.SecurityGroupWorkDao; -import com.cloud.network.security.dao.VmRulesetLogDao; import com.cloud.network.security.dao.*; import com.cloud.projects.ProjectManager; import com.cloud.tags.dao.ResourceTagDao; @@ -97,6 +93,8 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; import edu.emory.mathcs.backport.java.util.Collections; @@ -149,6 +147,10 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro ProjectManager _projectMgr; @Inject ResourceTagDao _resourceTagDao; + @Inject + NicDao _nicDao; + @Inject + NicSecondaryIpDao _nicSecIpDao; ScheduledExecutorService _executorPool; ScheduledExecutorService _cleanupExecutor; @@ -489,7 +491,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro return affectedVms; } - protected SecurityGroupRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map> ingressRules, Map> egressRules) { + protected SecurityGroupRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map> ingressRules, Map> egressRules, List secIps) { List ingressResult = new ArrayList(); List egressResult = new ArrayList(); for (PortAndProto pAp : ingressRules.keySet()) { @@ -506,7 +508,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro egressResult.add(ipPortAndProto); } } - return new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, ingressResult.toArray(new IpPortAndProto[ingressResult.size()]), egressResult.toArray(new IpPortAndProto[egressResult.size()])); + return new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, ingressResult.toArray(new IpPortAndProto[ingressResult.size()]), egressResult.toArray(new IpPortAndProto[egressResult.size()]), secIps); } protected void handleVmStopped(VMInstanceVO vm) { @@ -947,8 +949,19 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); agentId = vm.getHostId(); if (agentId != null) { + // get nic secondary ip address + String privateIp = vm.getPrivateIpAddress(); + NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId()); + List nicSecIps = null; + if (nic != null) { + if (nic.getSecondaryIp()) { + //get secondary ips of the vm + long networkId = nic.getNetworkId(); + nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId()); + } + } SecurityGroupRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(ingressRules, egressRules), seqnum, - ingressRules, egressRules); + ingressRules, egressRules, nicSecIps); Commands cmds = new Commands(cmd); try { _agentMgr.send(agentId, cmds, _answerListener); @@ -1272,4 +1285,66 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro return true; } } + + @Override + public boolean securityGroupRulesForVmSecIp(Long nicId, Long networkId, + String secondaryIp, boolean ruleAction) { + + String vmMac = null; + String vmName = null; + + if (secondaryIp == null || nicId == null || networkId == null) { + throw new InvalidParameterValueException("Vm nicId or networkId or secondaryIp can't be null"); + } + + NicVO nic = _nicDao.findById(nicId); + Long vmId = nic.getInstanceId(); + + // Validate parameters + List vmSgGrps = getSecurityGroupsForVm(vmId); + if (vmSgGrps == null) { + s_logger.debug("Vm is not in any Security group "); + return true; + } + + Account caller = UserContext.current().getCaller(); + + for (SecurityGroupVO securityGroup: vmSgGrps) { + Account owner = _accountMgr.getAccount(securityGroup.getAccountId()); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find security group owner by id=" + securityGroup.getAccountId()); + } + // Verify permissions + _accountMgr.checkAccess(caller, null, true, securityGroup); + } + + UserVm vm = _userVMDao.findById(vmId); + if (vm.getType() != VirtualMachine.Type.User) { + throw new InvalidParameterValueException("Can't configure the SG ipset, arprules rules for the non user vm"); + } + + if (vm != null) { + vmMac = vm.getPrivateMacAddress(); + vmName = vm.getInstanceName(); + if (vmMac == null || vmName == null) { + throw new InvalidParameterValueException("vm name or vm mac can't be null"); + } + } + + //create command for the to add ip in ipset and arptables rules + NetworkRulesVmSecondaryIpCommand cmd = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, ruleAction); + s_logger.debug("Asking agent to configure rules for vm secondary ip"); + Commands cmds = null; + + cmds = new Commands(cmd); + try { + _agentMgr.send(vm.getHostId(), cmds); + } catch (AgentUnavailableException e) { + s_logger.debug(e.toString()); + } catch (OperationTimedoutException e) { + s_logger.debug(e.toString()); + } + + return true; + } } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java index a3a0fc300f9..a42881ec905 100644 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java @@ -40,6 +40,7 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.Profiler; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.mgmt.JmxUtil; +import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.network.security.SecurityRule.SecurityRuleType; @@ -169,9 +170,19 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{ Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); Long agentId = vm.getHostId(); if (agentId != null) { + String privateIp = vm.getPrivateIpAddress(); + NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId()); + List nicSecIps = null; + if (nic != null) { + if (nic.getSecondaryIp()) { + //get secondary ips of the vm + long networkId = nic.getNetworkId(); + nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId()); + } + } SecurityGroupRulesCmd cmd = generateRulesetCmd(vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), null, - work.getLogsequenceNumber(), ingressRules, egressRules); + work.getLogsequenceNumber(), ingressRules, egressRules, nicSecIps); cmd.setMsId(_serverId); if (s_logger.isDebugEnabled()) { s_logger.debug("SecurityGroupManager v2: sending ruleset update for vm " + vm.getInstanceName() + diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 33feb5dd57e..de4f3ccd11b 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -205,7 +205,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { StringBuilder acctNm = new StringBuilder("PrjAcct-"); acctNm.append(name).append("-").append(owner.getDomainId()); - Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString(), 0); + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString()); Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 47b1d55ddac..15d32e0640d 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -770,6 +770,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } } clusterId = cluster.getId(); + if (_clusterDetailsDao.findDetail(clusterId,"cpuOvercommitRatio") == null) { + ClusterDetailsVO cluster_cpu_detail = new ClusterDetailsVO(clusterId,"cpuOvercommitRatio","1"); + ClusterDetailsVO cluster_memory_detail = new ClusterDetailsVO(clusterId,"memoryOvercommitRatio","1"); + _clusterDetailsDao.persist(cluster_cpu_detail); + _clusterDetailsDao.persist(cluster_memory_detail); + } + } try { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index d70c45f1f8a..b9a11f120a5 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -16,105 +16,6 @@ // under the License. package com.cloud.server; -import java.lang.reflect.Field; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.inject.Inject; -import javax.management.InstanceAlreadyExistsException; -import javax.management.MBeanRegistrationException; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.ApiConstants; - -import com.cloud.event.ActionEventUtils; -import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; - -import org.apache.cloudstack.api.command.admin.account.*; -import org.apache.cloudstack.api.command.admin.autoscale.*; -import org.apache.cloudstack.api.command.admin.cluster.*; -import org.apache.cloudstack.api.command.admin.config.*; -import org.apache.cloudstack.api.command.admin.domain.*; -import org.apache.cloudstack.api.command.admin.host.*; -import org.apache.cloudstack.api.command.admin.ldap.*; -import org.apache.cloudstack.api.command.admin.network.*; -import org.apache.cloudstack.api.command.admin.offering.*; -import org.apache.cloudstack.api.command.admin.pod.*; -import org.apache.cloudstack.api.command.admin.region.*; -import org.apache.cloudstack.api.command.admin.resource.*; -import org.apache.cloudstack.api.command.admin.router.*; -import org.apache.cloudstack.api.command.admin.storage.*; -import org.apache.cloudstack.api.command.admin.swift.*; -import org.apache.cloudstack.api.command.admin.systemvm.*; -import org.apache.cloudstack.api.command.admin.template.*; -import org.apache.cloudstack.api.command.admin.usage.*; -import org.apache.cloudstack.api.command.admin.user.*; -import org.apache.cloudstack.api.command.admin.vlan.*; -import org.apache.cloudstack.api.command.admin.vm.*; -import org.apache.cloudstack.api.command.admin.vpc.*; -import org.apache.cloudstack.api.command.admin.zone.*; -import org.apache.cloudstack.api.command.user.account.*; -import org.apache.cloudstack.api.command.user.address.*; -import org.apache.cloudstack.api.command.user.autoscale.*; -import org.apache.cloudstack.api.command.user.config.*; -import org.apache.cloudstack.api.command.user.event.*; -import org.apache.cloudstack.api.command.user.firewall.*; -import org.apache.cloudstack.api.command.user.guest.*; -import org.apache.cloudstack.api.command.user.iso.*; -import org.apache.cloudstack.api.command.user.job.*; -import org.apache.cloudstack.api.command.user.loadbalancer.*; -import org.apache.cloudstack.api.command.user.nat.*; -import org.apache.cloudstack.api.command.user.network.*; -import org.apache.cloudstack.api.command.user.offering.*; -import org.apache.cloudstack.api.command.user.project.*; -import org.apache.cloudstack.api.command.user.region.*; -import org.apache.cloudstack.api.command.user.resource.*; -import org.apache.cloudstack.api.command.user.securitygroup.*; -import org.apache.cloudstack.api.command.user.snapshot.*; -import org.apache.cloudstack.api.command.user.ssh.*; -import org.apache.cloudstack.api.command.user.tag.*; -import org.apache.cloudstack.api.command.user.template.*; -import org.apache.cloudstack.api.command.user.vm.*; -import org.apache.cloudstack.api.command.user.vmgroup.*; -import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd; -import org.apache.cloudstack.api.command.user.volume.*; -import org.apache.cloudstack.api.command.user.vpc.*; -import org.apache.cloudstack.api.command.user.vpn.*; -import org.apache.cloudstack.api.command.user.zone.*; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; @@ -126,12 +27,7 @@ import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; -import com.cloud.api.query.vo.EventJoinVO; -import com.cloud.async.AsyncJobExecutor; -import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobResult; -import com.cloud.async.AsyncJobVO; -import com.cloud.async.BaseAsyncJobExecutor; +import com.cloud.async.*; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; @@ -144,36 +40,19 @@ import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManagementState; import com.cloud.consoleproxy.ConsoleProxyManager; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.Vlan; +import com.cloud.dc.*; import com.cloud.dc.Vlan.VlanType; -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.PodVlanMapDao; -import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.*; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; +import com.cloud.event.ActionEventUtils; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InternalErrorException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; +import com.cloud.exception.*; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.DetailVO; import com.cloud.host.Host; @@ -190,13 +69,7 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.info.ConsoleProxyInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IpAddress; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.LoadBalancerVO; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.*; import com.cloud.org.Cluster; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project; @@ -207,26 +80,10 @@ import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.auth.UserAuthenticator; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.GuestOSVO; -import com.cloud.storage.GuestOsCategory; -import com.cloud.storage.Storage; -import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; -import com.cloud.storage.UploadVO; -import com.cloud.storage.Volume; -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.UploadDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.*; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; @@ -236,64 +93,142 @@ import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.SSHKeyPair; -import com.cloud.user.SSHKeyPairVO; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.UserVO; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; -import com.cloud.utils.EnumUtils; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.PasswordGenerator; -import com.cloud.utils.Ternary; -import com.cloud.utils.component.Adapter; -import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.*; import com.cloud.utils.component.ComponentLifecycle; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.component.SystemIntegrityChecker; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.DBEncryptionUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchCriteria.Op; -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.mgmt.JmxUtil; -import com.cloud.utils.mgmt.ManagementBean; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHKeysHelper; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfileImpl; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.InstanceGroupDao; -import com.cloud.vm.dao.SecondaryStorageVmDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.VMInstanceDao; - +import com.cloud.vm.dao.*; import edu.emory.mathcs.backport.java.util.Arrays; import edu.emory.mathcs.backport.java.util.Collections; +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; +import org.apache.cloudstack.api.command.admin.account.*; +import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; +import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd; +import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; +import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd; +import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd; +import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd; +import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd; +import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd; +import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; +import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd; +import org.apache.cloudstack.api.command.admin.domain.*; +import org.apache.cloudstack.api.command.admin.host.*; +import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd; +import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd; +import org.apache.cloudstack.api.command.admin.network.*; +import org.apache.cloudstack.api.command.admin.offering.*; +import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd; +import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd; +import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; +import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd; +import org.apache.cloudstack.api.command.admin.region.AddRegionCmd; +import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd; +import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd; +import org.apache.cloudstack.api.command.admin.resource.*; +import org.apache.cloudstack.api.command.admin.router.*; +import org.apache.cloudstack.api.command.admin.storage.*; +import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; +import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; +import org.apache.cloudstack.api.command.admin.systemvm.*; +import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd; +import org.apache.cloudstack.api.command.admin.usage.*; +import org.apache.cloudstack.api.command.admin.user.*; +import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; +import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; +import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; +import org.apache.cloudstack.api.command.admin.vpc.*; +import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; +import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; +import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd; +import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; +import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd; +import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd; +import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; +import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; +import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd; +import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd; +import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; +import org.apache.cloudstack.api.command.user.autoscale.*; +import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; +import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd; +import org.apache.cloudstack.api.command.user.event.ListEventsCmd; +import org.apache.cloudstack.api.command.user.firewall.*; +import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; +import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; +import org.apache.cloudstack.api.command.user.iso.*; +import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; +import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.*; +import org.apache.cloudstack.api.command.user.nat.*; +import org.apache.cloudstack.api.command.user.network.*; +import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; +import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; +import org.apache.cloudstack.api.command.user.project.*; +import org.apache.cloudstack.api.command.user.region.ListRegionsCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.*; +import org.apache.cloudstack.api.command.user.resource.*; +import org.apache.cloudstack.api.command.user.securitygroup.*; +import org.apache.cloudstack.api.command.user.snapshot.*; +import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; +import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd; +import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd; +import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; +import org.apache.cloudstack.api.command.user.template.*; +import org.apache.cloudstack.api.command.user.vm.*; +import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; +import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd; +import org.apache.cloudstack.api.command.user.volume.*; +import org.apache.cloudstack.api.command.user.vpc.*; +import org.apache.cloudstack.api.command.user.vpn.*; +import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; +import org.apache.cloudstack.api.response.ExtractResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.lang.reflect.Field; +import java.net.*; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; public class ManagementServerImpl extends ManagerBase implements ManagementServer { public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName()); @@ -2103,10 +2038,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(QueryAsyncJobResultCmd.class); cmdList.add(AssignToLoadBalancerRuleCmd.class); cmdList.add(CreateLBStickinessPolicyCmd.class); + cmdList.add(CreateLBHealthCheckPolicyCmd .class); cmdList.add(CreateLoadBalancerRuleCmd.class); cmdList.add(DeleteLBStickinessPolicyCmd.class); + cmdList.add(DeleteLBHealthCheckPolicyCmd .class); cmdList.add(DeleteLoadBalancerRuleCmd.class); cmdList.add(ListLBStickinessPoliciesCmd.class); + cmdList.add(ListLBHealthCheckPoliciesCmd .class); cmdList.add(ListLoadBalancerRuleInstancesCmd.class); cmdList.add(ListLoadBalancerRulesCmd.class); cmdList.add(RemoveFromLoadBalancerRuleCmd.class); @@ -2238,6 +2176,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(DeleteAlertsCmd.class); cmdList.add(ArchiveEventsCmd.class); cmdList.add(DeleteEventsCmd.class); + cmdList.add(CreateGlobalLoadBalancerRuleCmd.class); + cmdList.add(DeleteGlobalLoadBalancerRuleCmd.class); + cmdList.add(ListGlobalLoadBalancerRuleCmd.class); + cmdList.add(AssignToGlobalLoadBalancerRuleCmd.class); + cmdList.add(RemoveFromGlobalLoadBalancerRuleCmd.class); return cmdList; } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index f0e60283067..4951975786f 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -813,6 +813,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Long diskOfferingId = null; DiskOfferingVO diskOffering = null; Long size = null; + // Volume VO used for extracting the source template id + VolumeVO parentVolume = null; // validate input parameters before creating the volume if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) @@ -891,6 +893,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation"); } + parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId()); diskOfferingId = snapshotCheck.getDiskOfferingId(); diskOffering = _diskOfferingDao.findById(diskOfferingId); @@ -947,6 +950,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setUpdated(new Date()); volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller .getDomainId()); + if (parentVolume != null) { + volume.setTemplateId(parentVolume.getTemplateId()); + } else { + volume.setTemplateId(null); + } volume = _volsDao.persist(volume); if (cmd.getSnapshotId() == null) { diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index c4928be8fee..b51b216717b 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -78,12 +78,12 @@ import com.cloud.utils.exception.CloudRuntimeException; @Local(value={VMTemplateDao.class}) public class VMTemplateDaoImpl extends GenericDaoBase implements VMTemplateDao { private static final Logger s_logger = Logger.getLogger(VMTemplateDaoImpl.class); - + @Inject VMTemplateZoneDao _templateZoneDao; @Inject VMTemplateDetailsDao _templateDetailsDao; - + @Inject ConfigurationDao _configDao; @Inject @@ -94,10 +94,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem DataCenterDao _dcDao; private final String SELECT_TEMPLATE_HOST_REF = "SELECT t.id, h.data_center_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; - + private final String SELECT_TEMPLATE_ZONE_REF = "SELECT t.id, tzr.zone_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t INNER JOIN template_zone_ref tzr on (t.id = tzr.template_id) "; - + private final String SELECT_TEMPLATE_SWIFT_REF = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; @@ -132,17 +132,17 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private String routerTmpltName; private String consoleProxyTmpltName; - + public VMTemplateDaoImpl() { } - + @Override public List listByPublic() { SearchCriteria sc = PublicSearch.create(); sc.setParameters("public", 1); return listBy(sc); } - + @Override public VMTemplateVO findByName(String templateName) { SearchCriteria sc = UniqueNameSearch.create(); @@ -159,7 +159,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags){ - + SearchBuilder sb = null; if (tags == null || tags.isEmpty()) { sb = PublicIsoSearch; @@ -170,7 +170,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sb.and("type", sb.entity().getTemplateType(), SearchCriteria.Op.EQ); sb.and("bootable", sb.entity().isBootable(), SearchCriteria.Op.EQ); sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.EQ); - + SearchBuilder tagSearch = _tagsDao.createSearchBuilder(); for (int count=0; count < tags.size(); count++) { tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); @@ -181,20 +181,20 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sb.groupBy(sb.entity().getId()); sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - + SearchCriteria sc = sb.create(); - + sc.setParameters("public", 1); sc.setParameters("format", "ISO"); sc.setParameters("type", TemplateType.PERHOST.toString()); if (bootable != null) { sc.setParameters("bootable", bootable); } - + if (!listRemoved) { sc.setParameters("removed", (Object)null); } - + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.ISO.toString()); @@ -204,10 +204,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem count++; } } - + return listBy(sc); } - + @Override public List userIsoSearch(boolean listRemoved){ @@ -228,7 +228,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listAllSystemVMTemplates() { SearchCriteria sc = tmpltTypeSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); - + Filter filter = new Filter(VMTemplateVO.class, "id", false, null, null); return listBy(sc, filter); } @@ -236,7 +236,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public List listPrivateTemplatesByHost(Long hostId) { - String sql = "select * from template_host_ref as thr INNER JOIN vm_template as t ON t.id=thr.template_id " + String sql = "select * from template_host_ref as thr INNER JOIN vm_template as t ON t.id=thr.template_id " + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.removed is NULL"; List l = new ArrayList(); @@ -256,7 +256,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } return l; } - + @Override public List listReadyTemplates() { SearchCriteria sc = createSearchCriteria(); @@ -264,7 +264,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.addAnd("format", SearchCriteria.Op.NEQ, Storage.ImageFormat.ISO); return listIncludingRemovedBy(sc); } - + @Override public List findIsosByIdAndPath(Long domainId, Long accountId, String path) { SearchCriteria sc = createSearchCriteria(); @@ -287,7 +287,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("accountId", accountId); return listBy(sc); } - + @Override public List listByHypervisorType(List hyperTypes) { SearchCriteria sc = createSearchCriteria(); @@ -299,17 +299,17 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public boolean configure(String name, Map params) throws ConfigurationException { boolean result = super.configure(name, params); - + PublicSearch = createSearchBuilder(); PublicSearch.and("public", PublicSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); routerTmpltName = (String)params.get("routing.uniquename"); - + s_logger.debug("Found parameter routing unique name " + routerTmpltName); if (routerTmpltName==null) { routerTmpltName="routing"; } - + consoleProxyTmpltName = (String)params.get("consoleproxy.uniquename"); if(consoleProxyTmpltName == null) { consoleProxyTmpltName = "routing"; @@ -345,16 +345,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem hostHyperSearch.and("type", hostHyperSearch.entity().getType(), SearchCriteria.Op.EQ); hostHyperSearch.and("zoneId", hostHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); hostHyperSearch.groupBy(hostHyperSearch.entity().getHypervisorType()); - + tmpltTypeHyperSearch.join("tmplHyper", hostHyperSearch, hostHyperSearch.entity().getHypervisorType(), tmpltTypeHyperSearch.entity().getHypervisorType(), JoinBuilder.JoinType.INNER); hostHyperSearch.done(); tmpltTypeHyperSearch.done(); - + tmpltTypeHyperSearch2 = createSearchBuilder(); tmpltTypeHyperSearch2.and("templateType", tmpltTypeHyperSearch2.entity().getTemplateType(), SearchCriteria.Op.EQ); tmpltTypeHyperSearch2.and("hypervisorType", tmpltTypeHyperSearch2.entity().getHypervisorType(), SearchCriteria.Op.EQ); - + tmpltTypeSearch = createSearchBuilder(); tmpltTypeSearch.and("removed", tmpltTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL); tmpltTypeSearch.and("templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); @@ -363,11 +363,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.and("publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); AccountIdSearch.done(); - + SearchBuilder tmpltZoneSearch = _templateZoneDao.createSearchBuilder(); tmpltZoneSearch.and("removed", tmpltZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); - + TmpltsInZoneSearch = createSearchBuilder(); TmpltsInZoneSearch.and("removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); TmpltsInZoneSearch.and().op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ); @@ -378,11 +378,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem TmpltsInZoneSearch.done(); CountTemplatesByAccount = createSearchBuilder(Long.class); - CountTemplatesByAccount.select(null, Func.COUNT, null); + CountTemplatesByAccount.select(null, Func.COUNT, null); CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); CountTemplatesByAccount.done(); - + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -472,7 +472,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } else { whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; } - } else if (templateFilter == TemplateFilter.sharedexecutable && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + } else if ((templateFilter == TemplateFilter.shared || templateFilter == TemplateFilter.sharedexecutable) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { joinClause += " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE" + " (t.account_id IN (" + permittedAccountsStr + ") OR" + " lp.account_id IN (" + permittedAccountsStr + "))"; @@ -517,7 +517,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override - public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, + public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { @@ -527,17 +527,17 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem builder.append(permittedAccount.getAccountId() + ","); } } - + String permittedAccountsStr = builder.toString(); - + if (permittedAccountsStr.length() > 0) { //chop the "," off permittedAccountsStr = permittedAccountsStr.substring(0, permittedAccountsStr.length()-1); } - + Transaction txn = Transaction.currentTxn(); txn.start(); - + /* Use LinkedHashSet here to guarantee iteration order */ Set> templateZonePairList = new LinkedHashSet>(); PreparedStatement pstmt = null; @@ -545,15 +545,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem StringBuilder relatedDomainIds = new StringBuilder(); String sql = SELECT_TEMPLATE_ZONE_REF; String groupByClause = ""; - try { + try { //short accountType; //String accountId = null; - String guestOSJoin = ""; + String guestOSJoin = ""; StringBuilder templateHostRefJoin = new StringBuilder(); String dataCenterJoin = "", lpjoin = ""; String tagsJoin = ""; - if (isIso && !hyperType.equals(HypervisorType.None)) { + if (isIso && !hyperType.equals(HypervisorType.None)) { guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; } if (onlyReady){ @@ -564,34 +564,34 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - - if (templateFilter == TemplateFilter.sharedexecutable){ + + if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){ lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } - + if (tags != null && !tags.isEmpty()) { tagsJoin = " INNER JOIN resource_tags r ON t.id = r.resource_id "; } - + sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin + tagsJoin; String whereClause = ""; - + //All joins have to be made before we start setting the condition settings - if ((listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources - || (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.featured))) && + if ((listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources + || (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.featured))) && !(caller.getType() != Account.ACCOUNT_TYPE_NORMAL && templateFilter == TemplateFilter.all)) { whereClause += " INNER JOIN account a on (t.account_id = a.id)"; - if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { - whereClause += " INNER JOIN domain d on (a.domain_id = d.id) WHERE d.path LIKE '" + domain.getPath() + "%'"; + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + whereClause += " INNER JOIN domain d on (a.domain_id = d.id) WHERE d.path LIKE '" + domain.getPath() + "%'"; if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { whereClause += " AND a.type != " + Account.ACCOUNT_TYPE_PROJECT; } - } else + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { whereClause += " WHERE a.type != " + Account.ACCOUNT_TYPE_PROJECT; } } - + if (!permittedAccounts.isEmpty()) { for (Account account : permittedAccounts) { //accountType = account.getType(); @@ -621,12 +621,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem relatedDomainIds.setLength(relatedDomainIds.length()-1); } } - + String attr = " AND "; if (whereClause.endsWith(" WHERE ")) { attr += " WHERE "; } - + if (!isIso) { if ( hypers.isEmpty() ) { return templateZonePairList; @@ -642,9 +642,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem whereClause += attr + " t.hypervisor_type IN (" + relatedHypers + ")"; } } - - if (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.featured || - templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.executable) && !isAdmin(caller.getType()) ) { + + if (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.featured || + templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.executable + || templateFilter == TemplateFilter.shared || templateFilter == TemplateFilter.sharedexecutable) && !isAdmin(caller.getType()) ) { whereClause += attr + "t.account_id IN (" + permittedAccountsStr + ")"; } @@ -652,13 +653,13 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem whereClause += attr + "t.public = 1 AND t.featured = 1"; if (!permittedAccounts.isEmpty()) { whereClause += attr + "(dc.domain_id IN (" + relatedDomainIds + ") OR dc.domain_id is NULL)"; - } + } } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; - } else if (templateFilter == TemplateFilter.sharedexecutable) { + } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ) { whereClause += " AND " + " (t.account_id IN (" + permittedAccountsStr + ") OR" + - " lp.account_id IN (" + permittedAccountsStr + "))"; + " lp.account_id IN (" + permittedAccountsStr + "))"; } else if (templateFilter == TemplateFilter.executable && !permittedAccounts.isEmpty()) { whereClause += attr + "(t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))"; } else if (templateFilter == TemplateFilter.community) { @@ -669,7 +670,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && !isIso) { return templateZonePairList; } - + if (tags != null && !tags.isEmpty()) { whereClause += " AND ("; boolean first = true; @@ -682,13 +683,13 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } whereClause += ")"; } - + if (whereClause.equals("")) { whereClause += " WHERE "; } else if (!whereClause.equals(" WHERE ")) { whereClause += " AND "; } - + sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, onlyReady, showDomr) + groupByClause + getOrderByLimit(pageSize, startIndex); @@ -699,8 +700,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem Pair templateZonePair = new Pair(rs.getLong(1), rs.getLong(2)); templateZonePairList.add(templateZonePair); } - //for now, defaulting pageSize to a large val if null; may need to revisit post 2.2RC2 - if(isIso && templateZonePairList.size() < (pageSize != null ? pageSize : 500) + //for now, defaulting pageSize to a large val if null; may need to revisit post 2.2RC2 + if(isIso && templateZonePairList.size() < (pageSize != null ? pageSize : 500) && templateFilter != TemplateFilter.community && !(templateFilter == TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType())) ){ //evaluates to true If root admin and filter=self @@ -747,7 +748,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem s_logger.warn("Error in cleaning up", sqle); } } - + return templateZonePairList; } @@ -770,7 +771,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sql += " AND t.hypervisor_type = '" + hyperType.toString() + "'"; } } - + if (bootable != null) { sql += " AND t.bootable = " + bootable; } @@ -787,7 +788,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } if (!showDomr){ sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; - } + } sql += " AND t.removed IS NULL"; @@ -797,14 +798,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private String getOrderByLimit(Long pageSize, Long startIndex) { Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); isAscending = (isAscending == null ? true : isAscending); - + String sql; if (isAscending) { sql = " ORDER BY t.sort_key ASC"; } else { sql = " ORDER BY t.sort_key DESC"; } - + if ((pageSize != null) && (startIndex != null)) { sql += " LIMIT " + startIndex.toString() + "," + pageSize.toString(); } @@ -835,7 +836,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem _templateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); } txn.commit(); - + return tmplt.getId(); } @@ -854,7 +855,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("templateType", Storage.TemplateType.BUILTIN); return listBy(sc); } - + @Override public VMTemplateVO findSystemVMTemplate(long zoneId) { SearchCriteria sc = tmpltTypeHyperSearch.create(); @@ -864,14 +865,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem //order by descending order of id and select the first (this is going to be the latest) List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1l)); - + if (tmplts.size() > 0) { return tmplts.get(0); } else { return null; } } - + public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { SearchCriteria sc = tmpltTypeHyperSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); @@ -900,7 +901,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem //order by descending order of id and select the first (this is going to be the latest) List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1l)); - + if (tmplts.size() > 0) { return tmplts.get(0); } else { @@ -914,7 +915,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("account", accountId); return customSearch(sc, null).get(0); } - + @Override @DB public boolean remove(Long id) { @@ -922,7 +923,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem txn.start(); VMTemplateVO template = createForUpdate(); template.setRemoved(new Date()); - + VMTemplateVO vo = findById(id); if (vo != null) { if (vo.getFormat() == ImageFormat.ISO) { @@ -936,14 +937,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem txn.commit(); return result; } - + private 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)); } - + @Override public List findTemplatesToSyncToS3() { return executeList(SELECT_S3_CANDIDATE_TEMPLATES, new Object[] {}); @@ -1037,7 +1038,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem joinClause.append(" LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE (t.account_id IN ("); joinClause.append(permittedAccountsStr); joinClause.append(") OR lp.account_id IN ("); - joinClause.append(permittedAccountsStr); + joinClause.append(permittedAccountsStr); joinClause.append("))"); } else { joinClause.append(" INNER JOIN account a on (t.account_id = a.id) "); @@ -1088,8 +1089,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem TemplateState nextState, VMTemplateVO vo, Object data) { Long oldUpdated = vo.getUpdatedCount(); Date oldUpdatedTime = vo.getUpdated(); - - + + SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", vo.getId()); sc.setParameters("state", currentState); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java index 92687643185..4a2fe4fc331 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java @@ -88,30 +88,6 @@ public class Upgrade40to41 implements DbUpgrade { pstmt.setInt(1, region_id); pstmt.executeUpdate(); - //Update regionId in account table - s_logger.debug("Updating account table with Id: "+region_id); - pstmt = conn.prepareStatement("update `cloud`.`account` set region_id = ?"); - pstmt.setInt(1, region_id); - pstmt.executeUpdate(); - - //Update regionId in user table - s_logger.debug("Updating user table with Id: "+region_id); - pstmt = conn.prepareStatement("update `cloud`.`user` set region_id = ?"); - pstmt.setInt(1, region_id); - pstmt.executeUpdate(); - - //Update regionId in domain table - s_logger.debug("Updating domain table with Id: "+region_id); - pstmt = conn.prepareStatement("update `cloud`.`domain` set region_id = ?"); - pstmt.setInt(1, region_id); - pstmt.executeUpdate(); - - //Update regionId in cloud_usage account table - s_logger.debug("Updating cloud_usage account table with Id: "+region_id); - pstmt = conn.prepareStatement("update `cloud_usage`.`account` set region_id = ?"); - pstmt.setInt(1, region_id); - pstmt.executeUpdate(); - s_logger.debug("Successfully updated region entries with regionId: "+region_id); } catch (SQLException e) { throw new CloudRuntimeException("Error while updating region entries", e); } finally { diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index 4b3a601b802..6ba1f6a7f96 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -51,9 +51,9 @@ public interface AccountManager extends AccountService { Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId); - Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, int regionId); + Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid); - UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone); + UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID); /** * Logs out a user diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 9b916024cbb..be5f4f4d77d 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -54,9 +54,6 @@ import com.cloud.api.ApiDBUtils; import com.cloud.api.query.dao.UserAccountJoinDao; import com.cloud.api.query.vo.ControlledViewEntity; - -import org.apache.cloudstack.region.RegionManager; - import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceLimit; @@ -217,8 +214,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Inject private IPAddressDao _ipAddressDao; @Inject - private RegionManager _regionMgr; - @Inject private VpcManager _vpcMgr; @Inject private DomainRouterDao _routerDao; @@ -764,7 +759,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @DB @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account") public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, - Long domainId, String networkDomain, Map details) { + Long domainId, String networkDomain, Map details, String accountUUID, String userUUID) { if (accountName == null) { accountName = userName; @@ -810,11 +805,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M txn.start(); // create account - AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, UUID.randomUUID().toString(), _regionMgr.getId()); + if(accountUUID == null){ + accountUUID = UUID.randomUUID().toString(); + } + AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, accountUUID); long accountId = account.getId(); // create the first user for the account - UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone); + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID); if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { // set registration token @@ -829,7 +827,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } @Override - public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId) { + public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID) { // default domain to ROOT if not specified if (domainId == null) { @@ -858,7 +856,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId); } UserVO user = null; - user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone); + user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID); return user; } @@ -1646,7 +1644,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB - public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid, int regionId) { + public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid) { // Validate domain Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { @@ -1690,7 +1688,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M Transaction txn = Transaction.currentTxn(); txn.start(); - AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid, regionId)); + AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid)); if (account == null) { throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); @@ -1714,7 +1712,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") - public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone) { + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID) { if (s_logger.isDebugEnabled()) { s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); } @@ -1730,30 +1728,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new CloudRuntimeException("Failed to encode password"); } - UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, UUID.randomUUID().toString(), _regionMgr.getId())); - - return user; - } - - //ToDo Add events?? - public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String uuid, int regionId) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); + if(userUUID == null){ + userUUID = UUID.randomUUID().toString(); } - - String encodedPassword = null; - for (Iterator en = _userAuthenticators.iterator(); en.hasNext();) { - UserAuthenticator authenticator = en.next(); - encodedPassword = authenticator.encode(password); - if (encodedPassword != null) { - break; - } - } - if (encodedPassword == null) { - throw new CloudRuntimeException("Failed to encode password"); - } - - UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, uuid, regionId)); + UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, userUUID)); return user; } @@ -1983,7 +1961,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { - //Send keys to other Regions Long userId = cmd.getId(); User user = getUserIncludingRemoved(userId); diff --git a/server/src/com/cloud/user/DomainManager.java b/server/src/com/cloud/user/DomainManager.java index f268f6ec4eb..7bc2abbc756 100644 --- a/server/src/com/cloud/user/DomainManager.java +++ b/server/src/com/cloud/user/DomainManager.java @@ -27,7 +27,7 @@ import com.cloud.domain.DomainVO; public interface DomainManager extends DomainService { Set getDomainChildrenIds(String parentDomainPath); - Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain); + Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, String domainUUID); Set getDomainParentIds(long domainId); diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index babaed37494..dbcbe4ee431 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -16,10 +16,7 @@ // under the License. package com.cloud.user; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import javax.ejb.Local; import javax.inject.Inject; @@ -118,7 +115,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom @Override @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_CREATE, eventDescription = "creating Domain") - public Domain createDomain(String name, Long parentId, String networkDomain) { + public Domain createDomain(String name, Long parentId, String networkDomain, String domainUUID) { Account caller = UserContext.current().getCaller(); if (parentId == null) { @@ -136,13 +133,13 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom _accountMgr.checkAccess(caller, parentDomain); - return createDomain(name, parentId, caller.getId(), networkDomain); + return createDomain(name, parentId, caller.getId(), networkDomain, domainUUID); } @Override @DB - public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain) { + public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, String domainUUID) { // Verify network domain if (networkDomain != null) { if (!NetUtils.verifyDomainName(networkDomain)) { @@ -161,10 +158,13 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId); } + if(domainUUID == null){ + domainUUID = UUID.randomUUID().toString(); + } + Transaction txn = Transaction.currentTxn(); txn.start(); - - DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, _regionMgr.getId())); + DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainUUID)); _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain); txn.commit(); return domain; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 6b2f762a74d..82a69bd24ba 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -750,7 +750,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use /* * TODO: cleanup eventually - Refactored API call */ - public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) { + public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException { Long vmId = cmd.getId(); Long svcOffId = cmd.getServiceOfferingId(); Account caller = UserContext.current().getCaller(); @@ -764,6 +764,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _accountMgr.checkAccess(caller, null, true, vmInstance); + // Check resource limits for CPU and Memory. + ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId); + ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); + + int newCpu = newServiceOffering.getCpu(); + int newMemory = newServiceOffering.getRamSize(); + int currentCpu = currentServiceOffering.getCpu(); + int currentMemory = currentServiceOffering.getRamSize(); + + if (newCpu > currentCpu) { + _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, + newCpu - currentCpu); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, + newMemory - currentMemory); + } + // Check that the specified service offering ID is valid _itMgr.checkIfCanUpgrade(vmInstance, svcOffId); @@ -782,6 +800,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _itMgr.upgradeVmDb(vmId, svcOffId); + // Increment or decrement CPU and Memory count accordingly. + if (newCpu > currentCpu) { + _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu)); + } else if (currentCpu > newCpu) { + _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (currentCpu - newCpu)); + } + if (newMemory > currentMemory) { + _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory)); + } else if (currentMemory > newMemory) { + _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (currentMemory - newMemory)); + } + return _vmDao.findById(vmInstance.getId()); } @@ -1360,13 +1390,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use + " as a part of vm id=" + vmId + " expunge because resource is unavailable", e); } - //remove vm secondary ip addresses - if (_networkMgr.removeVmSecondaryIps(vmId)) { - s_logger.debug("Removed vm " + vmId + " secondary ip address of the VM Nics as a part of expunge process"); - } else { - success = false; - s_logger.warn("Fail to remove secondary ip address of vm " + vmId + " Nics as a part of expunge process"); - } return success; } diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 794bacc6e8b..35d719131bb 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -60,4 +60,6 @@ public interface NicDao extends GenericDao { NicVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, long instanceId, String ip4Address); List listByVmIdAndNicId(Long vmId, Long nicId); + + NicVO findByIp4AddressAndVmId(String ip4Address, long instance); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 44911740e96..b9ec72ee7c9 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -212,4 +212,13 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { sc.setParameters("nicid", nicId); return listBy(sc); } + + @Override + public NicVO findByIp4AddressAndVmId(String ip4Address, long instance) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("address", ip4Address); + sc.setParameters("instance", instance); + return findOneBy(sc); + } + } diff --git a/server/src/org/apache/cloudstack/region/RegionManager.java b/server/src/org/apache/cloudstack/region/RegionManager.java index 4cbd664ce5a..2d517302081 100644 --- a/server/src/org/apache/cloudstack/region/RegionManager.java +++ b/server/src/org/apache/cloudstack/region/RegionManager.java @@ -43,11 +43,9 @@ public interface RegionManager { * @param id * @param name * @param endPoint - * @param apiKey - * @param secretKey * @return Returns added Region object */ - Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey); + Region addRegion(int id, String name, String endPoint); /** * Update details of the Region with specified Id @@ -59,7 +57,7 @@ public interface RegionManager { * @param secretKey * @return Returns update Region object */ - Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey); + Region updateRegion(int id, String name, String endPoint); /** * @param id diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java index cb0b1a69ad8..9bcf4be69c8 100755 --- a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java @@ -17,30 +17,22 @@ package org.apache.cloudstack.region; import com.cloud.domain.Domain; -import com.cloud.domain.DomainVO; -import com.cloud.domain.dao.DomainDao; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; import com.cloud.user.DomainManager; import com.cloud.user.UserAccount; -import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; -import com.cloud.user.dao.UserDao; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.exception.CloudRuntimeException; -import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.region.dao.RegionDao; -import org.apache.commons.httpclient.NameValuePair; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -63,13 +55,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man @Inject private AccountManager _accountMgr; @Inject - private UserDao _userDao; - @Inject - private DomainDao _domainDao; - @Inject private DomainManager _domainMgr; - @Inject - private UserAccountDao _userAccountDao; private String _name; private int _id; @@ -104,7 +90,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man * {@inheritDoc} */ @Override - public Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey) { + public Region addRegion(int id, String name, String endPoint) { //Region Id should be unique if( _regionDao.findById(id) != null ){ throw new InvalidParameterValueException("Region with id: "+id+" already exists"); @@ -113,7 +99,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man if( _regionDao.findByName(name) != null ){ throw new InvalidParameterValueException("Region with name: "+name+" already exists"); } - RegionVO region = new RegionVO(id, name, endPoint, apiKey, secretKey); + RegionVO region = new RegionVO(id, name, endPoint); return _regionDao.persist(region); } @@ -121,7 +107,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man * {@inheritDoc} */ @Override - public Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey) { + public Region updateRegion(int id, String name, String endPoint) { RegionVO region = _regionDao.findById(id); if(region == null){ @@ -144,14 +130,6 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man region.setEndPoint(endPoint); } - if(apiKey != null){ - region.setApiKey(apiKey); - } - - if(secretKey != null){ - region.setSecretKey(secretKey); - } - _regionDao.update(id, region); return _regionDao.findById(id); } @@ -196,30 +174,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public boolean deleteUserAccount(long accountId) { - AccountVO account = _accountDao.findById(accountId); - if(account == null){ - throw new InvalidParameterValueException("The specified account does not exist in the system"); - } - String accountUUID = account.getUuid(); - int regionId = account.getRegionId(); - - String command = "deleteAccount"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, accountUUID)); - - if(getId() == regionId){ - return _accountMgr.deleteUserAccount(accountId); - } else { - //First delete in the Region where account is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully deleted account :"+accountUUID+" in Region: "+region.getId()); - return true; - } else { - s_logger.error("Error while deleting account :"+accountUUID+" in Region: "+region.getId()); - return false; - } - } + return _accountMgr.deleteUserAccount(accountId); } /** @@ -227,51 +182,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public Account updateAccount(UpdateAccountCmd cmd) { - Long accountId = cmd.getId(); - Long domainId = cmd.getDomainId(); - DomainVO domain = _domainDao.findById(domainId); - String accountName = cmd.getAccountName(); - String newAccountName = cmd.getNewName(); - String networkDomain = cmd.getNetworkDomain(); - //ToDo send details - Map details = cmd.getDetails(); - - Account account = null; - if (accountId != null) { - account = _accountDao.findById(accountId); - } else { - account = _accountDao.findEnabledAccount(accountName, domainId); - } - - // Check if account exists - if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); - throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); - } - - String command = "updateAccount"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, account.getUuid())); - params.add(new NameValuePair(ApiConstants.ACCOUNT, accountName)); - params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); - params.add(new NameValuePair(ApiConstants.NETWORK_DOMAIN, networkDomain)); - params.add(new NameValuePair(ApiConstants.NEW_NAME, newAccountName)); - if(details != null){ - params.add(new NameValuePair(ApiConstants.ACCOUNT_DETAILS, details.toString())); - } - int regionId = account.getRegionId(); - if(getId() == regionId){ - return _accountMgr.updateAccount(cmd); - } else { - //First update in the Region where account is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully updated account :"+account.getUuid()+" in source Region: "+region.getId()); - return account; - } else { - throw new CloudRuntimeException("Error while updating account :"+account.getUuid()+" in source Region: "+region.getId()); - } - } + return _accountMgr.updateAccount(cmd); } /** @@ -280,46 +191,12 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man @Override public Account disableAccount(String accountName, Long domainId, Long accountId, Boolean lockRequested) throws ConcurrentOperationException, ResourceUnavailableException { Account account = null; - if (accountId != null) { - account = _accountDao.findById(accountId); + if(lockRequested){ + account = _accountMgr.lockAccount(accountName, domainId, accountId); } else { - account = _accountDao.findActiveAccount(accountName, domainId); - } - - if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); - } - - String accountUUID = account.getUuid(); - - String command = "disableAccount"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.LOCK, lockRequested.toString())); - params.add(new NameValuePair(ApiConstants.ID, accountUUID)); - DomainVO domain = _domainDao.findById(domainId); - if(domain != null){ - params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); - } - - int regionId = account.getRegionId(); - if(getId() == regionId){ - Account retAccount = null; - if(lockRequested){ - retAccount = _accountMgr.lockAccount(accountName, domainId, accountId); - } else { - retAccount = _accountMgr.disableAccount(accountName, domainId, accountId); - } - return retAccount; - } else { - //First disable account in the Region where account is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully disabled account :"+accountUUID+" in source Region: "+region.getId()); - return account; - } else { - throw new CloudRuntimeException("Error while disabling account :"+accountUUID+" in source Region: "+region.getId()); - } + account = _accountMgr.disableAccount(accountName, domainId, accountId); } + return account; } /** @@ -327,42 +204,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public Account enableAccount(String accountName, Long domainId, Long accountId) { - // Check if account exists - Account account = null; - if (accountId != null) { - account = _accountDao.findById(accountId); - } else { - account = _accountDao.findActiveAccount(accountName, domainId); - } - - if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); - } - - String accountUUID = account.getUuid(); - - String command = "enableAccount"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, accountUUID)); - params.add(new NameValuePair(ApiConstants.ACCOUNT, accountName)); - DomainVO domain = _domainDao.findById(domainId); - if(domain != null){ - params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); - } - - int regionId = account.getRegionId(); - if(getId() == regionId){ - return _accountMgr.enableAccount(accountName, domainId, accountId); - } else { - //First disable account in the Region where account is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully enabled account :"+accountUUID+" in source Region: "+region.getId()); - return account; - } else { - throw new CloudRuntimeException("Error while enabling account :"+accountUUID+" in source Region: "+region.getId()); - } - } + return _accountMgr.enableAccount(accountName, domainId, accountId); } /** @@ -370,34 +212,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public boolean deleteUser(DeleteUserCmd cmd) { - long id = cmd.getId(); - - UserVO user = _userDao.findById(id); - - if (user == null) { - throw new InvalidParameterValueException("The specified user doesn't exist in the system"); - } - - String userUUID = user.getUuid(); - int regionId = user.getRegionId(); - - String command = "deleteUser"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, userUUID)); - - if(getId() == regionId){ - return _accountMgr.deleteUser(cmd); - } else { - //First delete in the Region where user is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully deleted user :"+userUUID+" in source Region: "+region.getId()); - return true; - } else { - s_logger.error("Error while deleting user :"+userUUID+" in source Region: "+region.getId()); - return false; - } - } + return _accountMgr.deleteUser(cmd); } /** @@ -405,33 +220,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public Domain updateDomain(UpdateDomainCmd cmd) { - long id = cmd.getId(); - DomainVO domain = _domainDao.findById(id); - if(domain == null){ - throw new InvalidParameterValueException("The specified domain doesn't exist in the system"); - } - - String domainUUID = domain.getUuid(); - - String command = "updateDomain"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, domainUUID)); - params.add(new NameValuePair(ApiConstants.NAME, cmd.getDomainName())); - params.add(new NameValuePair(ApiConstants.NETWORK_DOMAIN, cmd.getNetworkDomain())); - - int regionId = domain.getRegionId(); - if(getId() == regionId){ - return _domainMgr.updateDomain(cmd); - } else { - //First update in the Region where domain was created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully updated user :"+domainUUID+" in source Region: "+region.getId()); - return domain; - } else { - throw new CloudRuntimeException("Error while updating user :"+domainUUID+" in source Region: "+region.getId()); - } - } + return _domainMgr.updateDomain(cmd); } /** @@ -439,32 +228,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public boolean deleteDomain(Long id, Boolean cleanup) { - DomainVO domain = _domainDao.findById(id); - if(domain == null){ - throw new InvalidParameterValueException("The specified domain doesn't exist in the system"); - } - - String domainUUID = domain.getUuid(); - - String command = "deleteDomain"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, domainUUID)); - params.add(new NameValuePair(ApiConstants.CLEANUP, cleanup.toString())); - - int regionId = domain.getRegionId(); - if(getId() == regionId){ - return _domainMgr.deleteDomain(id, cleanup); - } else { - //First delete in the Region where domain is created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully deleted domain :"+domainUUID+" in Region: "+region.getId()); - return true; - } else { - s_logger.error("Error while deleting domain :"+domainUUID+" in Region: "+region.getId()); - return false; - } - } + return _domainMgr.deleteDomain(id, cleanup); } /** @@ -472,40 +236,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public UserAccount updateUser(UpdateUserCmd cmd) { - long id = cmd.getId(); - - UserVO user = _userDao.findById(id); - if (user == null) { - throw new InvalidParameterValueException("The specified user doesn't exist in the system"); - } - - String userUUID = user.getUuid(); - - String command = "updateUser"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, userUUID)); - params.add(new NameValuePair(ApiConstants.API_KEY, cmd.getApiKey())); - params.add(new NameValuePair(ApiConstants.EMAIL, cmd.getEmail())); - params.add(new NameValuePair(ApiConstants.FIRSTNAME, cmd.getFirstname())); - params.add(new NameValuePair(ApiConstants.LASTNAME, cmd.getLastname())); - params.add(new NameValuePair(ApiConstants.PASSWORD, cmd.getPassword())); - params.add(new NameValuePair(ApiConstants.SECRET_KEY, cmd.getSecretKey())); - params.add(new NameValuePair(ApiConstants.TIMEZONE, cmd.getTimezone())); - params.add(new NameValuePair(ApiConstants.USERNAME, cmd.getUsername())); - - int regionId = user.getRegionId(); - if(getId() == regionId){ - return _accountMgr.updateUser(cmd); - } else { - //First update in the Region where user was created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully updated user :"+userUUID+" in source Region: "+region.getId()); - return _userAccountDao.findById(id); - } else { - throw new CloudRuntimeException("Error while updating user :"+userUUID+" in source Region: "+region.getId()); - } - } + return _accountMgr.updateUser(cmd); } /** @@ -513,29 +244,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public UserAccount disableUser(Long userId) { - UserVO user = _userDao.findById(userId); - if (user == null || user.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find active user by id " + userId); - } - - int regionId = user.getRegionId(); - - String command = "disableUser"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, user.getUuid())); - - if(getId() == regionId){ - return _accountMgr.disableUser(userId); - } else { - //First disable in the Region where user was created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully disabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return _userAccountDao.findById(userId); - } else { - throw new CloudRuntimeException("Error while disabling user :"+user.getUuid()+" in source Region: "+region.getId()); - } - } + return _accountMgr.disableUser(userId); } /** @@ -543,29 +252,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man */ @Override public UserAccount enableUser(long userId) { - UserVO user = _userDao.findById(userId); - if (user == null || user.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find active user by id " + userId); - } - - int regionId = user.getRegionId(); - - String command = "enableUser"; - List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.ID, user.getUuid())); - - if(getId() == regionId){ - return _accountMgr.enableUser(userId); - } else { - //First enable in the Region where user was created - Region region = _regionDao.findById(regionId); - if (RegionsApiUtil.makeAPICall(region, command, params)) { - s_logger.debug("Successfully enabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return _userAccountDao.findById(userId); - } else { - throw new CloudRuntimeException("Error while enabling user :"+user.getUuid()+" in source Region: "+region.getId()); - } - } + return _accountMgr.enableUser(userId); } } diff --git a/server/src/org/apache/cloudstack/region/RegionServiceImpl.java b/server/src/org/apache/cloudstack/region/RegionServiceImpl.java index 0662c320145..cb03df6bddc 100755 --- a/server/src/org/apache/cloudstack/region/RegionServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionServiceImpl.java @@ -78,20 +78,20 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man * {@inheritDoc} */ @Override - public Region addRegion(int id, String name, String endPoint, String apiKey, String secretKey) { + public Region addRegion(int id, String name, String endPoint) { //Check for valid Name //Check valid end_point url - return _regionMgr.addRegion(id, name, endPoint, apiKey, secretKey); + return _regionMgr.addRegion(id, name, endPoint); } /** * {@inheritDoc} */ @Override - public Region updateRegion(int id, String name, String endPoint, String apiKey, String secretKey) { + public Region updateRegion(int id, String name, String endPoint) { //Check for valid Name //Check valid end_point url - return _regionMgr.updateRegion(id, name, endPoint, apiKey, secretKey); + return _regionMgr.updateRegion(id, name, endPoint); } /** diff --git a/server/src/org/apache/cloudstack/region/RegionVO.java b/server/src/org/apache/cloudstack/region/RegionVO.java index f62f571eeba..6890bc850a8 100644 --- a/server/src/org/apache/cloudstack/region/RegionVO.java +++ b/server/src/org/apache/cloudstack/region/RegionVO.java @@ -36,11 +36,6 @@ public class RegionVO implements Region{ @Column(name="end_point") private String endPoint; - @Column(name="api_key") - private String apiKey; - - @Column(name="secret_key") - private String secretKey; public boolean getGslbEnabled() { return gslbEnabled; @@ -56,12 +51,10 @@ public class RegionVO implements Region{ public RegionVO() { } - public RegionVO(int id, String name, String endPoint, String apiKey, String secretKey) { + public RegionVO(int id, String name, String endPoint) { this.id = id; this.name = name; this.endPoint = endPoint; - this.apiKey = apiKey; - this.secretKey = secretKey; this.gslbEnabled = true; } @@ -85,26 +78,10 @@ public class RegionVO implements Region{ this.endPoint = endPoint; } - public String getApiKey() { - return apiKey; - } - - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } - - public String getSecretKey() { - return secretKey; - } @Override public boolean checkIfServiceEnabled(Service service) { return gslbEnabled; } - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - } - - } diff --git a/server/src/org/apache/cloudstack/region/RegionsApiUtil.java b/server/src/org/apache/cloudstack/region/RegionsApiUtil.java index 2ace4f9295c..0dbee5fb541 100644 --- a/server/src/org/apache/cloudstack/region/RegionsApiUtil.java +++ b/server/src/org/apache/cloudstack/region/RegionsApiUtil.java @@ -227,8 +227,8 @@ public class RegionsApiUtil { */ private static String buildUrl(String apiParams, Region region) { - String apiKey = region.getApiKey(); - String secretKey = region.getSecretKey(); + String apiKey = ""; + String secretKey = ""; if (apiKey == null || secretKey == null) { diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 80043102648..eb43cce0b9e 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -32,6 +32,7 @@ import org.springframework.stereotype.Component; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; @@ -854,11 +855,6 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage return null; } - @Override - public boolean removeVmSecondaryIps(long vmId) { - // TODO Auto-generated method stub - return false; - } @Override public List listVmNics(Long vmId, Long nicId) { @@ -871,4 +867,18 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage // TODO Auto-generated method stub return null; } + + @Override + public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, + Pod pod, Account caller, String requestedIp) + throws InsufficientAddressCapacityException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean removeVmSecondaryIpsOfNic(long nicId) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index d7ffa7da280..83dddf4e735 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -835,4 +835,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { throws InvalidParameterValueException { // TODO Auto-generated method stub } + + @Override + public String getStartIpv6Address(long id) { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index b637c2aaf4e..64919afa74f 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -264,7 +264,7 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco } @Override - public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone) { + public UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID) { return null; } @@ -328,7 +328,7 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long domainId, - String networkDomain, Map details) { + String networkDomain, Map details, String accountUUID, String userUUID) { // TODO Auto-generated method stub return null; } @@ -336,15 +336,14 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco @Override public User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, - Long domainId) { + Long domainId, String userUUID) { // TODO Auto-generated method stub return null; } @Override public Account createAccount(String accountName, short accountType, - Long domainId, String networkDomain, Map details, String uuid, - int regionId) { + Long domainId, String networkDomain, Map details, String uuid) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/user/MockDomainManagerImpl.java b/server/test/com/cloud/user/MockDomainManagerImpl.java index bc92965849c..616e12de0d3 100644 --- a/server/test/com/cloud/user/MockDomainManagerImpl.java +++ b/server/test/com/cloud/user/MockDomainManagerImpl.java @@ -139,7 +139,7 @@ public class MockDomainManagerImpl extends ManagerBase implements DomainManager, @Override public Domain createDomain(String name, Long parentId, - String networkDomain) { + String networkDomain, String domainUUID) { // TODO Auto-generated method stub return null; } @@ -152,7 +152,7 @@ public class MockDomainManagerImpl extends ManagerBase implements DomainManager, @Override public Domain createDomain(String name, Long parentId, Long ownerId, - String networkDomain) { + String networkDomain, String domainUUID) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 63ef8744be8..c798cdf7810 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -34,6 +34,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; @@ -1365,12 +1366,6 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage - @Override - public boolean removeVmSecondaryIps(long vmId) { - // TODO Auto-generated method stub - return false; - } - @@ -1390,4 +1385,30 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage // TODO Auto-generated method stub return null; } + + + + + + @Override + public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, + Pod pod, Account caller, String requestedIp) + throws InsufficientAddressCapacityException { + // TODO Auto-generated method stub + return null; + } + + + + + + + + + + @Override + public boolean removeVmSecondaryIpsOfNic(long nicId) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 5ac87772529..7f1f945f630 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -848,4 +848,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { // TODO Auto-generated method stub } + @Override + public String getStartIpv6Address(long id) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/test/org/apache/cloudstack/region/RegionManagerTest.java b/server/test/org/apache/cloudstack/region/RegionManagerTest.java index 330f0b49d22..b6d1969a107 100644 --- a/server/test/org/apache/cloudstack/region/RegionManagerTest.java +++ b/server/test/org/apache/cloudstack/region/RegionManagerTest.java @@ -48,27 +48,14 @@ public class RegionManagerTest extends TestCase { public void testUniqueName() { RegionManagerImpl regionMgr = new RegionManagerImpl(); RegionDao regionDao = Mockito.mock(RegionDao.class); - RegionVO region = new RegionVO(2, "APAC", "", null, null); + RegionVO region = new RegionVO(2, "APAC", ""); Mockito.when(regionDao.findByName(Mockito.anyString())).thenReturn(region); regionMgr._regionDao = regionDao; try { - regionMgr.addRegion(2, "APAC", "", null, null); + regionMgr.addRegion(2, "APAC", ""); } catch (InvalidParameterValueException e){ Assert.assertEquals("Region with name: APAC already exists", e.getMessage()); } } - - @Test - public void testUserDelete() { - RegionManagerImpl regionMgr = new RegionManagerImpl(); - AccountDao accountDao = Mockito.mock(AccountDao.class); - Mockito.when(accountDao.findById(Mockito.anyLong())).thenReturn(null); - regionMgr._accountDao = accountDao; - try { - regionMgr.deleteUserAccount(5); - } catch (InvalidParameterValueException e){ - Assert.assertEquals("The specified account does not exist in the system", e.getMessage()); - } - } } diff --git a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java index cea4fd9324b..700fe8f7dde 100644 --- a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java +++ b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java @@ -158,7 +158,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { gslbServiceImpl._accountMgr = Mockito.mock(AccountManager.class); Account account = (Account) new AccountVO("testaccount", 1, - "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); gslbServiceImpl._gslbRuleDao = Mockito.mock(GlobalLoadBalancerRuleDao.class); @@ -223,7 +223,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { gslbServiceImpl._accountMgr = Mockito.mock(AccountManager.class); Account account = (Account) new AccountVO("testaccount", 1, - "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); gslbServiceImpl._gslbRuleDao = Mockito.mock(GlobalLoadBalancerRuleDao.class); @@ -288,7 +288,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { gslbServiceImpl._accountMgr = Mockito.mock(AccountManager.class); Account account = (Account) new AccountVO("testaccount", 1, - "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); gslbServiceImpl._gslbRuleDao = Mockito.mock(GlobalLoadBalancerRuleDao.class); @@ -353,7 +353,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { gslbServiceImpl._accountMgr = Mockito.mock(AccountManager.class); Account account = (Account) new AccountVO("testaccount", 1, - "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); gslbServiceImpl._gslbRuleDao = Mockito.mock(GlobalLoadBalancerRuleDao.class); @@ -418,7 +418,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { gslbServiceImpl._accountMgr = Mockito.mock(AccountManager.class); Account account = (Account) new AccountVO("testaccount", 1, - "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); gslbServiceImpl._gslbRuleDao = Mockito.mock(GlobalLoadBalancerRuleDao.class); @@ -496,7 +496,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { AssignToGlobalLoadBalancerRuleCmd assignCmd = new AssignToGlobalLoadBalancerRuleCmdExtn(); Class _class = assignCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -561,7 +561,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { AssignToGlobalLoadBalancerRuleCmd assignCmd = new AssignToGlobalLoadBalancerRuleCmdExtn(); Class _class = assignCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 3, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 3, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -635,7 +635,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { AssignToGlobalLoadBalancerRuleCmd assignCmd = new AssignToGlobalLoadBalancerRuleCmdExtn(); Class _class = assignCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -695,7 +695,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd = new RemoveFromGlobalLoadBalancerRuleCmdExtn(); Class _class = removeFromGslbCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -765,7 +765,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd = new RemoveFromGlobalLoadBalancerRuleCmdExtn(); Class _class = removeFromGslbCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -827,7 +827,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd = new RemoveFromGlobalLoadBalancerRuleCmdExtn(); Class _class = removeFromGslbCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -872,7 +872,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { DeleteGlobalLoadBalancerRuleCmd deleteCmd = new DeleteGlobalLoadBalancerRuleCmdExtn(); Class _class = deleteCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); @@ -920,7 +920,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { DeleteGlobalLoadBalancerRuleCmd deleteCmd = new DeleteGlobalLoadBalancerRuleCmdExtn(); Class _class = deleteCmd.getClass().getSuperclass(); - Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString(), 1); + Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString()); when(gslbServiceImpl._accountMgr.getAccount(anyLong())).thenReturn(account); UserContext.registerContext(1, account, null, true); diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index 7f79bae657f..6815b0d43bc 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -50,9 +50,10 @@ public class ConsoleProxyHttpHandlerHelper { ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor( ConsoleProxy.getEncryptorPassword()); + ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token")); + // make sure we get information from token only map.clear(); - ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token")); if(param != null) { if(param.getClientHostAddress() != null) map.put("host", param.getClientHostAddress()); diff --git a/setup/bindir/cloud-setup-databases.in b/setup/bindir/cloud-setup-databases.in index 1603c23eecb..0b5cbaca249 100755 --- a/setup/bindir/cloud-setup-databases.in +++ b/setup/bindir/cloud-setup-databases.in @@ -257,7 +257,7 @@ for full help self.runMysql(text, p, True) self.info(None, True) - awsApiDbDir = '/usr/share/cloud/setup/bridge/db' + awsApiDbDir = '/usr/share/cloudstack-bridge/setup' for f in ["cloudbridge_db.sql"]: p = os.path.join(awsApiDbDir,f) if not os.path.exists(p): continue diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index b9bfe1aae4f..865fbd3181c 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -258,17 +258,10 @@ CREATE TABLE `cloud`.`region` ( `id` int unsigned NOT NULL UNIQUE, `name` varchar(255) NOT NULL UNIQUE, `end_point` varchar(255) NOT NULL, - `api_key` varchar(255), - `secret_key` varchar(255), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client/api','',''); - -ALTER TABLE `cloud`.`account` ADD COLUMN `region_id` int unsigned NOT NULL DEFAULT '1'; -ALTER TABLE `cloud`.`user` ADD COLUMN `region_id` int unsigned NOT NULL DEFAULT '1'; -ALTER TABLE `cloud`.`domain` ADD COLUMN `region_id` int unsigned NOT NULL DEFAULT '1'; +INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client/api'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.cpus', '40', 'The default maximum number of cpu cores that can be used for an account'); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index cdef38f9fda..83fcd3909fd 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -27,6 +27,7 @@ UPDATE `cloud`.`hypervisor_capabilities` SET `max_hosts_per_cluster`=32 WHERE `h INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '5.1', 128, 0, 32); DELETE FROM `cloud`.`configuration` where name='vmware.percluster.host.max'; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'AgentManager', 'xen.nics.max', '7', 'Maximum allowed nics for Vms created on Xen'); +ALTER TABLE `cloud`.`load_balancer_vm_map` ADD state VARCHAR(40) NULL COMMENT 'service status updated by LB healthcheck manager'; alter table template_host_ref add state varchar(255); alter table template_host_ref add update_count bigint unsigned; @@ -97,6 +98,21 @@ CREATE TABLE `vpc_service_map` ( UNIQUE (`vpc_id`, `service`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`load_balancer_healthcheck_policies` ( + `id` bigint(20) NOT NULL auto_increment, + `uuid` varchar(40), + `load_balancer_id` bigint unsigned NOT NULL, + `pingpath` varchar(225) NULL DEFAULT '/', + `description` varchar(4096) NULL, + `response_time` int(11) DEFAULT 5, + `healthcheck_interval` int(11) DEFAULT 5, + `healthcheck_thresshold` int(11) DEFAULT 2, + `unhealth_thresshold` int(11) DEFAULT 10, + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', + PRIMARY KEY (`id`), + UNIQUE KEY `id_UNIQUE` (`id`), + CONSTRAINT `fk_load_balancer_healthcheck_policies_loadbalancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.instancename.flag', 'false', 'Append guest VM display Name (if set) to the internal name of the VM'); @@ -199,11 +215,14 @@ CREATE TABLE `cloud`.`global_load_balancing_rules` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', `uuid` varchar(40), `account_id` bigint unsigned NOT NULL COMMENT 'account id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', `region_id` int unsigned NOT NULL, `name` varchar(255) NOT NULL, `description` varchar(4096) NULL COMMENT 'description', + `state` char(32) NOT NULL COMMENT 'current state of this rule', `algorithm` varchar(255) NOT NULL COMMENT 'load balancing algorithm used to distribbute traffic across zones', `persistence` varchar(255) NOT NULL COMMENT 'session persistence used across the zone', + `service_type` varchar(255) NOT NULL COMMENT 'GSLB service type (tcp/udp)', `gslb_domain_name` varchar(255) NOT NULL COMMENT 'DNS name for the GSLB service that is used to provide a FQDN for the GSLB service', PRIMARY KEY (`id`), CONSTRAINT `fk_global_load_balancing_rules_account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, diff --git a/tools/appliance/README.md b/tools/appliance/README.md index 2f6f656212d..bb28829a366 100644 --- a/tools/appliance/README.md +++ b/tools/appliance/README.md @@ -26,11 +26,11 @@ under the License. export PATH=~/.rvm/bin:$PATH - Install Ruby 1.9.3, if it installed some other version: rvm install 1.9.3 + - Install bundler: (if you get any openssl issue see https://rvm.io/packages/openssl) + gem install bundler All the dependencies will be fetched automatically. -Vagrant: https://github.com/chipchilders/vagrant.git - To save some time if you've downloaded iso of your distro, put the isos in: tools/appliance/iso/ @@ -43,7 +43,7 @@ Note, gem may require gcc-4.2, make sure link exists: Just run build.sh, it will export archived appliances for KVM, Xen, VMWare and HyperV in `dist`: - sh build.sh + sh build.sh [systemvmtemplate|systemvmtemplate64] # Building SystemVM template appliance manually @@ -51,7 +51,7 @@ List available appliances one can build: veewee vbox list -Modify scripts in definitions/systemvmtemplate/ as per needs. +Modify scripts in definitions/*appliance*/ as per needs. Build systemvm template appliance: veewee vbox build 'systemvmtemplate' diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 69e15d88ca7..f1ee4a64b40 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -18,7 +18,13 @@ set -x -appliance="systemvmtemplate" +if [ ! -z "$1" ] +then + appliance="$1" +else + appliance="systemvmtemplate" +fi + build_date=`date +%Y-%m-%d` branch="master" rootdir=$PWD @@ -46,7 +52,7 @@ hdd_path=`vboxmanage list hdds | grep $appliance | grep vdi | cut -c 14-` shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` while [ "$shared_folders" != "" ] do - vboxmanage sharedfolder remove systemvmtemplate --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" + vboxmanage sharedfolder remove $appliance --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` done diff --git a/tools/appliance/definitions/systemvmtemplate/zerodisk.sh b/tools/appliance/definitions/systemvmtemplate/zerodisk.sh index 25bd8c4af2d..b00f7ae7ccc 100644 --- a/tools/appliance/definitions/systemvmtemplate/zerodisk.sh +++ b/tools/appliance/definitions/systemvmtemplate/zerodisk.sh @@ -6,7 +6,7 @@ rm -fv .veewee_version .veewee_params .vbox_version echo "Cleaning up" # Zero out the free space to save space in the final image: -for path in / /boot /usr /var /opt /tmp +for path in / /boot /usr /var /opt /tmp /home do dd if=/dev/zero of=$path/zero bs=1M sync diff --git a/tools/appliance/definitions/systemvmtemplate64/base.sh b/tools/appliance/definitions/systemvmtemplate64/base.sh new file mode 100644 index 00000000000..d6faea04b41 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/base.sh @@ -0,0 +1,25 @@ +# Update the box +apt-get -y update +#apt-get -y install linux-headers-$(uname -r) build-essential +#apt-get -y install zlib1g-dev libssl-dev libreadline-gplv2-dev +apt-get -y install curl unzip + +# Set up sudo +echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant + +# Tweak sshd to prevent DNS resolution (speed up logins) +echo 'UseDNS no' >> /etc/ssh/sshd_config + +# Remove 5s grub timeout to speed up booting +cat < /etc/default/grub +# If you change this file, run 'update-grub' afterwards to update +# /boot/grub/grub.cfg. + +GRUB_DEFAULT=0 +GRUB_TIMEOUT=0 +GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` +GRUB_CMDLINE_LINUX_DEFAULT="quiet" +GRUB_CMDLINE_LINUX="debian-installer=en_US" +EOF + +update-grub diff --git a/tools/appliance/definitions/systemvmtemplate64/cleanup.sh b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh new file mode 100644 index 00000000000..9e98ab03531 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh @@ -0,0 +1,21 @@ +# Clean up +#apt-get -y remove linux-headers-$(uname -r) build-essential +apt-get -y remove dictionaries-common busybox +apt-get -y autoremove +apt-get autoclean +apt-get clean + +# Removing leftover leases and persistent rules +echo "cleaning up dhcp leases" +rm /var/lib/dhcp/* + +# Make sure Udev doesn't block our network +echo "cleaning up udev rules" +rm /etc/udev/rules.d/70-persistent-net.rules +mkdir /etc/udev/rules.d/70-persistent-net.rules +rm -rf /dev/.udev/ +rm /lib/udev/rules.d/75-persistent-net-generator.rules + +echo "Adding a 2 sec delay to the interface up, to make the dhclient happy" +echo "pre-up sleep 2" >> /etc/network/interfaces + diff --git a/tools/appliance/definitions/systemvmtemplate64/definition.rb b/tools/appliance/definitions/systemvmtemplate64/definition.rb new file mode 100644 index 00000000000..35ef878d35a --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/definition.rb @@ -0,0 +1,45 @@ +Veewee::Definition.declare({ + :cpu_count => '1', + :memory_size=> '256', + :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', + :os_type_id => 'Debian_64', + :iso_file => "debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_src => "http://cdimage.debian.org/cdimage/wheezy_di_rc1/amd64/iso-cd/debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_md5 => "412f77d4b98adf2a7d575745fd282d78", + :iso_download_timeout => "1000", + :boot_wait => "10", :boot_cmd_sequence => [ + '', + 'install ', + 'preseed/url=http://%IP%:%PORT%/preseed.cfg ', + 'debian-installer=en_US ', + 'auto ', + 'locale=en_US ', + 'kbd-chooser/method=us ', + 'netcfg/get_hostname=systemvm ', + 'netcfg/get_domain=apache.org ', + 'fb=false ', + 'debconf/frontend=noninteractive ', + 'console-setup/ask_detect=false ', + 'console-keymaps-at/keymap=us ', + 'keyboard-configuration/xkb-keymap=us ', + '' + ], + :kickstart_port => "7122", + :kickstart_timeout => "10000", + :kickstart_file => "preseed.cfg", + :ssh_login_timeout => "10000", + :ssh_user => "root", + :ssh_password => "password", + :ssh_key => "", + :ssh_host_port => "7222", + :ssh_guest_port => "22", + :sudo_cmd => "echo '%p'|sudo -S sh '%f'", + :shutdown_cmd => "halt -p", + :postinstall_files => [ + "base.sh", + "postinstall.sh", + "cleanup.sh", + "zerodisk.sh" + ], + :postinstall_timeout => "10000" +}) diff --git a/tools/appliance/definitions/systemvmtemplate64/postinstall.sh b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh new file mode 100644 index 00000000000..8e745eb1ba9 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh @@ -0,0 +1,220 @@ +# 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. + +set -x + +ROOTPW=password +HOSTNAME=systemvm +CLOUDSTACK_RELEASE=4.2.0 + +install_packages() { + DEBIAN_FRONTEND=noninteractive + DEBIAN_PRIORITY=critical + + # Basic packages + apt-get --no-install-recommends -q -y --force-yes install rsyslog logrotate cron chkconfig insserv net-tools ifupdown vim-tiny netbase iptables + apt-get --no-install-recommends -q -y --force-yes install openssh-server openssl e2fsprogs dhcp3-client tcpdump socat wget + # apt-get --no-install-recommends -q -y --force-yes install grub-legacy + apt-get --no-install-recommends -q -y --force-yes install python bzip2 sed gawk diffutils grep gzip less tar telnet ftp rsync traceroute psmisc lsof procps monit inetutils-ping iputils-arping httping + apt-get --no-install-recommends -q -y --force-yes install dnsutils zip unzip ethtool uuid file iproute acpid virt-what sudo + + # sysstat + echo 'sysstat sysstat/enable boolean true' | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install sysstat + # apache + apt-get --no-install-recommends -q -y --force-yes install apache2 ssl-cert + # haproxy + apt-get --no-install-recommends -q -y --force-yes install haproxy + # dnsmasq + apt-get --no-install-recommends -q -y --force-yes install dnsmasq + # nfs client + apt-get --no-install-recommends -q -y --force-yes install nfs-common + + # vpn stuff + apt-get --no-install-recommends -q -y --force-yes install xl2tpd bcrelay ppp ipsec-tools tdb-tools + echo "openswan openswan/install_x509_certificate boolean false" | debconf-set-selections + echo "openswan openswan/install_x509_certificate seen true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install openswan + + # vmware tools + apt-get --no-install-recommends -q -y --force-yes install open-vm-tools + # xenstore utils + apt-get --no-install-recommends -q -y --force-yes install xenstore-utils libxenstore3.0 + # keepalived and conntrackd for redundant router + apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 + # ipcalc + apt-get --no-install-recommends -q -y --force-yes install ipcalc + # java + apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + + echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections + echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install iptables-persistent +} + +setup_accounts() { + # Setup sudo to allow no-password sudo for "admin" + groupadd -r admin + # Create a 'cloud' user if it's not there + id cloud + if [[ $? -ne 0 ]] + then + useradd -G admin cloud + else + usermod -a -G admin cloud + fi + echo "root:$ROOTPW" | chpasswd + echo "cloud:`openssl rand -base64 32`" | chpasswd + sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers + sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers + # Disable password based authentication via ssh, this will take effect on next reboot + sed -i -e 's/^.*PasswordAuthentication .*$/PasswordAuthentication no/g' /etc/ssh/sshd_config + # Secure ~/.ssh + mkdir -p /home/cloud/.ssh + chmod 700 /home/cloud/.ssh +} + +fix_nameserver() { + # Replace /etc/resolv.conf also + cat > /etc/resolv.conf << EOF +nameserver 8.8.8.8 +nameserver 4.4.4.4 +EOF +} + +fix_inittab() { + # Fix inittab + cat >> /etc/inittab << EOF + +vc:2345:respawn:/sbin/getty 38400 hvc0 +EOF +} + +fix_acpid() { + # Fix acpid + mkdir -p /etc/acpi/events + cat >> /etc/acpi/events/power << EOF +event=button/power.* +action=/usr/local/sbin/power.sh "%e" +EOF + cat >> /usr/local/sbin/power.sh << EOF +#!/bin/bash +/sbin/poweroff +EOF + chmod a+x /usr/local/sbin/power.sh +} + +fix_hostname() { + # Fix hostname in openssh-server generated keys + sed -i "s/root@\(.*\)$/root@$HOSTNAME/g" /etc/ssh/ssh_host_*.pub + # Fix hostname to override one provided by dhcp during vm build + echo "$HOSTNAME" > /etc/hostname + hostname $HOSTNAME + # Delete entry in /etc/hosts derived from dhcp + sed -i '/127.0.1.1/d' /etc/hosts +} + +fix_locale() { + cat >> /etc/default/locale << EOF +LANG=en_US.UTF-8 +LC_ALL=en_US.UTF-8 +EOF + cat >> /etc/locale.gen << EOF +en_US.UTF-8 UTF-8 +EOF + + locale-gen en_US.UTF-8 +} + +do_fixes() { + fix_nameserver + fix_inittab + fix_acpid + fix_hostname + fix_locale +} + +configure_apache2() { + # Enable ssl, rewrite and auth + a2enmod ssl rewrite auth_basic auth_digest + a2ensite default-ssl + # Backup stock apache configuration since we may modify it in Secondary Storage VM + cp /etc/apache2/sites-available/default /etc/apache2/sites-available/default.orig + cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/default-ssl.orig +} + +configure_services() { + mkdir -p /var/www/html + mkdir -p /opt/cloud/bin + mkdir -p /var/cache/cloud + mkdir -p /usr/share/cloud + mkdir -p /usr/local/cloud + mkdir -p /root/.ssh + # Fix haproxy directory issue + mkdir -p /var/lib/haproxy + + # Get config files from master + snapshot_url="https://git-wip-us.apache.org/repos/asf?p=incubator-cloudstack.git;a=snapshot;h=HEAD;sf=tgz" + snapshot_dir="/opt/incubator-cloudstack*" + cd /opt + wget $snapshot_url -O cloudstack.tar.gz + tar -zxvf cloudstack.tar.gz + cp -rv $snapshot_dir/patches/systemvm/debian/config/* / + cp -rv $snapshot_dir/patches/systemvm/debian/vpn/* / + mkdir -p /usr/share/cloud/ + cd $snapshot_dir/patches/systemvm/debian/config + tar -cvf /usr/share/cloud/cloud-scripts.tar * + cd $snapshot_dir/patches/systemvm/debian/vpn + tar -rvf /usr/share/cloud/cloud-scripts.tar * + cd /opt + rm -fr $snapshot_dir cloudstack.tar.gz + + chkconfig --add cloud-early-config + chkconfig cloud-early-config on + chkconfig --add cloud-passwd-srvr + chkconfig cloud-passwd-srvr off + chkconfig --add cloud + chkconfig cloud off + chkconfig monit off + chkconfig xl2tpd off +} + +do_signature() { + mkdir -p /var/cache/cloud/ + gzip -c /usr/share/cloud/cloud-scripts.tar > /usr/share/cloud/cloud-scripts.tgz + md5sum /usr/share/cloud/cloud-scripts.tgz | awk '{print $1}' > /var/cache/cloud/cloud-scripts-signature + echo "Cloudstack Release $CLOUDSTACK_RELEASE $(date)" > /etc/cloudstack-release +} + +begin=$(date +%s) + +echo "*************INSTALLING PACKAGES********************" +install_packages +echo "*************DONE INSTALLING PACKAGES********************" +setup_accounts +echo "*************DONE ACCOUNT SETUP********************" +configure_services +configure_apache2 +echo "*************DONE SETTING UP SERVICES********************" +do_fixes +echo "*************DONE FIXING CONFIGURATION********************" +do_signature + +fin=$(date +%s) +t=$((fin-begin)) + +echo "Signed systemvm build, finished building systemvm appliance in $t seconds" diff --git a/tools/appliance/definitions/systemvmtemplate64/preseed.cfg b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg new file mode 100644 index 00000000000..ac9edd31213 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg @@ -0,0 +1,357 @@ +#### Contents of the preconfiguration file (for squeeze) +### Localization +# Locale sets language and country. +d-i debian-installer/locale string en_US + +# Keyboard selection. +#d-i console-tools/archs select at +d-i console-keymaps-at/keymap select us +# Example for a different keyboard architecture +#d-i console-keymaps-usb/keymap select mac-usb-us + +### Network configuration +# netcfg will choose an interface that has link if possible. This makes it +# skip displaying a list if there is more than one interface. +d-i netcfg/choose_interface select auto + +# To pick a particular interface instead: +#d-i netcfg/choose_interface select eth1 + +# If you have a slow dhcp server and the installer times out waiting for +# it, this might be useful. +#d-i netcfg/dhcp_timeout string 60 + +# If you prefer to configure the network manually, uncomment this line and +# the static network configuration below. +#d-i netcfg/disable_dhcp boolean true + +# If you want the preconfiguration file to work on systems both with and +# without a dhcp server, uncomment these lines and the static network +# configuration below. +#d-i netcfg/dhcp_failed note +#d-i netcfg/dhcp_options select Configure network manually + +# Static network configuration. +#d-i netcfg/get_nameservers string 192.168.1.1 +#d-i netcfg/get_ipaddress string 192.168.1.42 +#d-i netcfg/get_netmask string 255.255.255.0 +#d-i netcfg/get_gateway string 192.168.1.1 +#d-i netcfg/confirm_static boolean true + +# Any hostname and domain names assigned from dhcp take precedence over +# values set here. However, setting the values still prevents the questions +# from being shown, even if values come from dhcp. +d-i netcfg/get_hostname string systemvm +d-i netcfg/get_domain string cloudstack.org + +# Disable that annoying WEP key dialog. +d-i netcfg/wireless_wep string +# The wacky dhcp hostname that some ISPs use as a password of sorts. +#d-i netcfg/dhcp_hostname string radish + +# If non-free firmware is needed for the network or other hardware, you can +# configure the installer to always try to load it, without prompting. Or +# change to false to disable asking. +#d-i hw-detect/load_firmware boolean true + +### Network console +# Use the following settings if you wish to make use of the network-console +# component for remote installation over SSH. This only makes sense if you +# intend to perform the remainder of the installation manually. +#d-i anna/choose_modules string network-console +#d-i network-console/password password r00tme +#d-i network-console/password-again password r00tme + +### Mirror settings +# If you select ftp, the mirror/country string does not need to be set. +#d-i mirror/protocol string ftp +d-i mirror/country string manual +d-i mirror/http/hostname string http.us.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +# Suite to install. +#d-i mirror/suite string testing +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string testing + +### Clock and time zone setup +# Controls whether or not the hardware clock is set to UTC. +d-i clock-setup/utc boolean true + +# You may set this to any valid setting for $TZ; see the contents of +# /usr/share/zoneinfo/ for valid values. +d-i time/zone string UTC + +# Controls whether to use NTP to set the clock during the install +d-i clock-setup/ntp boolean true +# NTP server to use. The default is almost always fine here. +#d-i clock-setup/ntp-server string ntp.example.com + +### Partitioning +# If the system has free space you can choose to only partition that space. +#d-i partman-auto/init_automatically_partition select biggest_free + +# Alternatively, you can specify a disk to partition. The device name must +# be given in traditional non-devfs format. +# Note: A disk must be specified, unless the system has only one disk. +# For example, to use the first SCSI/SATA hard disk: +d-i partman-auto/disk string /dev/sda +# In addition, you'll need to specify the method to use. +# The presently available methods are: "regular", "lvm" and "crypto" +d-i partman-auto/method string regular + +# If one of the disks that are going to be automatically partitioned +# contains an old LVM configuration, the user will normally receive a +# warning. This can be preseeded away... +#d-i partman-lvm/device_remove_lvm boolean true +# The same applies to pre-existing software RAID array: +#d-i partman-md/device_remove_md boolean true + +# And the same goes for the confirmation to write the lvm partitions. +#d-i partman-lvm/confirm boolean true +#d-i partman-lvm/confirm_nooverwrite boolean true + +#d-i partman/choose_partition select finish +#d-i partman-auto-lvm/guided_size string max + +# You can choose one of the three predefined partitioning recipes: +# - atomic: all files in one partition +# - home: separate /home partition +# - multi: separate /home, /usr, /var, and /tmp partitions +d-i partman-auto/choose_recipe select atomic +#d-i partman/default_filesystem string ext3 + +# Or provide a recipe of your own... +# The recipe format is documented in the file devel/partman-auto-recipe.txt. +# If you have a way to get a recipe file into the d-i environment, you can +# just point at it. +#d-i partman-auto/expert_recipe_file string /hd-media/recipe + +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 40 50 100 ext4 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 60 100 200 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /home } \ + . \ + 500 30 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /usr } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /opt } \ + . \ + 500 60 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /var } \ + . \ + 100 70 400 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /tmp } \ + . \ + 64 512 300% linux-swap \ + method{ swap } format{ } \ + . + +# If not, you can put an entire recipe into the preconfiguration file in one +# (logical) line. This example creates a small /boot partition, suitable +# swap, and uses the rest of the space for the root partition: +#d-i partman-auto/expert_recipe string \ +# boot-root :: \ +# 40 50 100 ext3 \ +# $primary{ } $bootable{ } \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ /boot } \ +# . \ +# 500 10000 1000000000 ext3 \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ / } \ +# . \ +# 64 512 300% linux-swap \ +# method{ swap } format{ } \ +# . + +#The preseed line that "selects finish" needs to be in a certain order in your preseed, the example-preseed does not follow this. +#http://ubuntuforums.org/archive/index.php/t-1504045.html + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. +#d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +### Base system installation +# Select the initramfs generator used to generate the initrd for 2.6 kernels. +#d-i base-installer/kernel/linux/initramfs-generators string yaird + +# The kernel image (meta) package to be installed; "none" can be used if no +# kernel is to be installed. +#d-i base-installer/kernel/image string linux-image-2.6-486 + +### Account setup +# Skip creation of a root account (normal user account will be able to +# use sudo). +d-i passwd/root-login boolean true +# Alternatively, to skip creation of a normal user account. +#d-i passwd/make-user boolean false + +# Root password, either in clear text +d-i passwd/root-password password password +d-i passwd/root-password-again password password +# or encrypted using an MD5 hash. +#d-i passwd/root-password-crypted password [MD5 hash] + +# To create a normal user account. +d-i passwd/user-fullname string Cloud Stack +d-i passwd/username string cloud +# Normal user's password, either in clear text +d-i passwd/user-password password cloud +d-i passwd/user-password-again password cloud +# or encrypted using an MD5 hash. +#d-i passwd/user-password-crypted password [MD5 hash] +# Create the first user with the specified UID instead of the default. +#d-i passwd/user-uid string 1010 +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# The user account will be added to some standard initial groups. To +# override that, use this. +d-i passwd/user-default-groups string audio cdrom video admin + +### Apt setup +# You can choose to install non-free and contrib software. +#d-i apt-setup/non-free boolean true +#d-i apt-setup/contrib boolean true +# Uncomment this if you don't want to use a network mirror. +#d-i apt-setup/use_mirror boolean false +# Select which update services to use; define the mirrors to be used. +# Values shown below are the normal defaults. +#d-i apt-setup/services-select multiselect security, volatile +#d-i apt-setup/security_host string security.debian.org +#d-i apt-setup/volatile_host string volatile.debian.org + + +# By default the installer requires that repositories be authenticated +# using a known gpg key. This setting can be used to disable that +# authentication. Warning: Insecure, not recommended. +#d-i debian-installer/allow_unauthenticated string true + +### Package selection +tasksel tasksel/first multiselect ssh-server +# If the desktop task is selected, install the kde and xfce desktops +# instead of the default gnome desktop. +#tasksel tasksel/desktop multiselect kde, xfce + +# Individual additional packages to install +d-i pkgsel/include string openssh-server ntp acpid sudo bzip2 + +# Whether to upgrade packages after debootstrap. +# Allowed values: none, safe-upgrade, full-upgrade +d-i pkgsel/upgrade select none + +# Some versions of the installer can report back on what software you have +# installed, and what software you use. The default is not to report back, +# but sending reports helps the project determine what software is most +# popular and include it on CDs. +popularity-contest popularity-contest/participate boolean false + +### Boot loader installation +# Grub is the default boot loader (for x86). If you want lilo installed +# instead, uncomment this: +#d-i grub-installer/skip boolean true +# To also skip installing lilo, and install no bootloader, uncomment this +# too: +#d-i lilo-installer/skip boolean true + +# This is fairly safe to set, it makes grub install automatically to the MBR +# if no other operating system is detected on the machine. +d-i grub-installer/only_debian boolean true + +# This one makes grub-installer install to the MBR if it also finds some other +# OS, which is less safe as it might not be able to boot that other OS. +#d-i grub-installer/with_other_os boolean true + +# Alternatively, if you want to install to a location other than the mbr, +# uncomment and edit these lines: +#d-i grub-installer/only_debian boolean false +#d-i grub-installer/with_other_os boolean false +#d-i grub-installer/bootdev string (hd0,0) +# To install grub to multiple disks: +#d-i grub-installer/bootdev string (hd0,0) (hd1,0) (hd2,0) + +# Optional password for grub, either in clear text +#d-i grub-installer/password password r00tme +#d-i grub-installer/password-again password r00tme +# or encrypted using an MD5 hash, see grub-md5-crypt(8). +#d-i grub-installer/password-crypted password [MD5 hash] + +### Finishing up the installation +# During installations from serial console, the regular virtual consoles +# (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next +# line to prevent this. +#d-i finish-install/keep-consoles boolean true + +# Avoid that last message about the install being complete. +d-i finish-install/reboot_in_progress note + +# This will prevent the installer from ejecting the CD during the reboot, +# which is useful in some situations. +#d-i cdrom-detect/eject boolean false + +# This is how to make the installer shutdown when finished, but not +# reboot into the installed system. +#d-i debian-installer/exit/halt boolean true +# This will power off the machine instead of just halting it. +#d-i debian-installer/exit/poweroff boolean true + +### Preseeding other packages +# Depending on what software you choose to install, or if things go wrong +# during the installation process, it's possible that other questions may +# be asked. You can preseed those too, of course. To get a list of every +# possible question that could be asked during an install, do an +# installation, and then run these commands: +# debconf-get-selections --installer > file +# debconf-get-selections >> file + + +#### Advanced options +### Running custom commands during the installation +# d-i preseeding is inherently not secure. Nothing in the installer checks +# for attempts at buffer overflows or other exploits of the values of a +# preconfiguration file like this one. Only use preconfiguration files from +# trusted locations! To drive that home, and because it's generally useful, +# here's a way to run any shell command you'd like inside the installer, +# automatically. + +# This first command is run as early as possible, just after +# preseeding is read. +# Prevent packaged version of VirtualBox Guest Additions being installed: +d-i preseed/early_command string sed -i \ + '/in-target/idiscover(){/sbin/discover|grep -v VirtualBox;}' \ + /usr/lib/pre-pkgsel.d/20install-hwpackages + +# This command is run just before the install finishes, but when there is +# still a usable /target directory. You can chroot to /target and use it +# directly, or use the apt-install and in-target commands to easily install +# packages and run commands in the target system. diff --git a/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh new file mode 100644 index 00000000000..25bd8c4af2d --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh @@ -0,0 +1,15 @@ +# Clean up stuff copied in by veewee +rm -fv /root/*.iso +rm -fv /root/base.sh /root/cleanup.sh /root/postinstall.sh /root/zerodisk.sh +rm -fv .veewee_version .veewee_params .vbox_version + +echo "Cleaning up" + +# Zero out the free space to save space in the final image: +for path in / /boot /usr /var /opt /tmp +do + dd if=/dev/zero of=$path/zero bs=1M + sync + rm -f $path/zero + echo "Completed zero-ing out disk on $path" +done diff --git a/tools/eclipse/set-eclipse-profile.sh b/tools/eclipse/set-eclipse-profile.sh new file mode 100644 index 00000000000..1abc662e6d3 --- /dev/null +++ b/tools/eclipse/set-eclipse-profile.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# 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. + +for file in `find . -name org.eclipse.m2e.core.prefs | xargs`; do + if grep -q activeProfiles=eclipse $file; then + echo Skipping $file; + else + echo Replacing $file; + sed -i s/activeProfiles=/activeProfiles=eclipse/g $file; + fi; +done \ No newline at end of file diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index cb1debc27cf..e1dd02d4126 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -1737,16 +1737,64 @@ div.list-view td.state.off span { text-indent: 0; } -.detail-group .main-groups table td.value span { +.detail-group .main-groups table td.value > span { display: block; height: 30px; overflow: auto; position: relative; top: 9px; + float: left; + width: 245px; } -.detail-group .main-groups table td.value span { - width: 355px; +.detail-group .main-groups table td.value .view-all { + cursor: pointer; + /*[empty]height:;*/ + border-left: 1px solid #9FA2A5; + /*+border-radius:4px 0 0 4px;*/ + -moz-border-radius: 4px 0 0 4px; + -webkit-border-radius: 4px 0 0 4px; + -khtml-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; + background: url(../images/sprites.png) no-repeat 100% -398px; + float: right; + margin: 1px 0 0; + padding: 8px 33px 6px 15px; +} + +.detail-group .main-groups table td.value .view-all:hover { + background-position: 100% -431px; +} + +/*List-view: subselect dropdown*/ +.list-view .subselect { + width: 116px; + display: block; + float: left; + background: url(../images/bg-gradients.png) 0px -42px; + padding: 0; + margin: 8px 0 1px 7px; + clear: both; + border: 1px solid #A8A7A7; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} + +.list-view .subselect span { + margin: 4px 0 0 12px; +} + +.list-view .subselect select { + width: 85%; + margin: 5px 0 4px; + font-size: 10px; +} + +.detail-group .main-groups table td.value .view-all:hover { + background-position: 100% -431px; } .panel.always-maximized .detail-group .main-groups table td.value span { @@ -3666,6 +3714,21 @@ Dialogs*/ float: left; } +.ui-dialog div.form-container div.value input.hasDatepicker { + color: #2F5D86; + cursor: pointer; + font-size: 13px; + text-indent: 3px; +} + +.ui-dialog div.form-container div.value input.hasDatepicker:hover { + /*+box-shadow:inset 0px 0px 3px;*/ + -moz-box-shadow: inset 0px 0px 3px; + -webkit-box-shadow: inset 0px 0px 3px; + -o-box-shadow: inset 0px 0px 3px; + box-shadow: inset 0px 0px 3px; +} + .ui-dialog div.form-container div.value .range-edit { width: 249px; height: 33px; @@ -7294,6 +7357,33 @@ div.panel.ui-dialog div.list-view div.fixed-header { background: #C3E0FC; } +/*List-view: subselect dropdown*/ +.list-view .subselect { + width: 116px; + display: block; + float: left; + background: url(../images/bg-gradients.png) 0px -42px; + padding: 0; + margin: 8px 0 1px 7px; + clear: both; + border: 1px solid #A8A7A7; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} + +.list-view .subselect span { + margin: 4px 0 0 12px; +} + +.list-view .subselect select { + width: 85%; + margin: 5px 0 4px; + font-size: 10px; +} + /*Multi-edit*/ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBalancer div.multi-edit form table.multi-edit thead tr th, div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBalancer div.multi-edit form table.multi-edit tbody tr td { @@ -7684,6 +7774,23 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t margin: 0 22px 0 0; } +/** Fix long table overflow*/ +.detail-view .multi-edit { + width: 100%; +} + +.detail-view .multi-edit table { + width: 97%; + max-width: inherit; +} + +.detail-view .multi-edit table tr th, +.detail-view .multi-edit table tr td { + width: 87px !important; + min-width: 87px !important; + max-width: 87px !important; +} + /** Header fields*/ .multi-edit .header-fields { position: relative; @@ -10502,6 +10609,37 @@ div.ui-dialog div.acl div.multi-edit div.data div.data-body div.data-item table width: 65px; } +/*HEALTH CHECK*/ +.ui-dialog .health-check { + height: 295px !important; + padding-bottom: 93px; +} + +div.ui-dialog div.health-check div.health-check-description { + color: #808080; +} + +div.ui-dialog div.health-check div.form-container form div.form-item { + width: 58% margin-left:116px; + margin-top: -16px; + margin-bottom: 30px; +} + +div.ui-dialog div.health-check div.health-check-config-title { + float: left; + color: #808080; + font-size: 17px; + margin-left: 15px; +} + +div.ui-dialog div.health-check div.health-check-advanced-title { + float: left; + color: #808080; + font-size: 17px; + margin-left: 15px; + margin-top: -70px; +} + /*Autoscaler*/ .ui-dialog div.autoscaler { overflow: auto; @@ -11004,6 +11142,144 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it font-size: 11px; } +/*UI datepicker*/ +.ui-datepicker { + background: #FFFFFF 0px -2470px; + width: 300px; + height: auto; + overflow: hidden; + padding: 4px 0 0; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + /*+box-shadow:0px 3px 8px #000000;*/ + -moz-box-shadow: 0px 3px 8px #000000; + -webkit-box-shadow: 0px 3px 8px #000000; + -o-box-shadow: 0px 3px 8px #000000; + box-shadow: 0px 3px 8px #000000; + display: none; +} + +.ui-datepicker .ui-datepicker-title { + width: 100%; + margin: auto; +} + +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + font-size: 13px; + color: #FFFFFF; + /*+box-shadow:0px 1px 5px #444444;*/ + -moz-box-shadow: 0px 1px 5px #444444; + -webkit-box-shadow: 0px 1px 5px #444444; + -o-box-shadow: 0px 1px 5px #444444; + box-shadow: 0px 1px 5px #444444; + /*+text-shadow:0px -1px 1px #050505;*/ + -moz-text-shadow: 0px -1px 1px #050505; + -webkit-text-shadow: 0px -1px 1px #050505; + -o-text-shadow: 0px -1px 1px #050505; + text-shadow: 0px -1px 1px #050505; + padding: 6px; + margin: 6px 13px 6px 14px; + font-size: 12px; + background: url(../images/bg-gradients.png) 0px -182px; + cursor: pointer; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} + +.ui-datepicker .ui-datepicker-prev:hover, +.ui-datepicker .ui-datepicker-next:hover { + /*+box-shadow:inset 0px 0px 10px #000000;*/ + -moz-box-shadow: inset 0px 0px 10px #000000; + -webkit-box-shadow: inset 0px 0px 10px #000000; + -o-box-shadow: inset 0px 0px 10px #000000; + box-shadow: inset 0px 0px 10px #000000; +} + +.ui-datepicker .ui-datepicker-prev { + float: left; +} + +.ui-datepicker .ui-datepicker-next { + float: right; +} + +.ui-datepicker .ui-datepicker-title .ui-datepicker-month { + width: 85px; + font-size: 16px; + color: #2C363F; +} + +.ui-datepicker .ui-datepicker-title .ui-datepicker-year { +} + +.ui-datepicker .ui-datepicker-title { + text-align: center; + width: 188px; + height: 19px; + padding: 3px 0 0; + /*+placement:shift 0px 6px;*/ + position: relative; + left: 0px; + top: 6px; +} + +.ui-datepicker table { + width: 277px; + height: 9px; +} + +.ui-datepicker table th, +.ui-datepicker table td { + min-width: 24px; + text-align: center; + border: 1px solid #B9B6B6; + text-indent: 0px; + padding: 7px 0; + /*[empty]+placement:;*/ +} + +.ui-datepicker table td { + cursor: pointer; +} + +.ui-datepicker table td.ui-state-disabled, +.ui-datepicker table td.ui-state-disabled:hover { + background-color: #DCDCDC; + /*+box-shadow:none;*/ + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + cursor: default; +} + +.ui-datepicker table td a { + text-decoration: none; + color: #485867; + font-size: 12px; +} + +.ui-datepicker table td:hover { + background-color: #6A839A; + /*+box-shadow:inset 0px 0px 4px #6B6B6B;*/ + -moz-box-shadow: inset 0px 0px 4px #6B6B6B; + -webkit-box-shadow: inset 0px 0px 4px #6B6B6B; + -o-box-shadow: inset 0px 0px 4px #6B6B6B; + box-shadow: inset 0px 0px 4px #6B6B6B; +} + +.ui-datepicker table td:hover a { + color: #FFFFFF; + text-shadow: 0px -1px #000000; +} + /*Plugins listing*/ .plugins-listing { } diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index 3aecaaa0aba..6c06a10ed98 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -25,6 +25,7 @@ under the License. <% long now = System.currentTimeMillis(); %> + diff --git a/ui/scripts/dashboard.js b/ui/scripts/dashboard.js index 5f49e616b65..845ae52259b 100644 --- a/ui/scripts/dashboard.js +++ b/ui/scripts/dashboard.js @@ -91,7 +91,7 @@ var netTotal = json.listnetworksresponse.count ? json.listnetworksresponse.count : 0; - $.ajax({ + $.ajax({ url: createURL('listPublicIpAddresses'), success: function(json) { var ipTotal = json.listpublicipaddressesresponse.count ? @@ -102,7 +102,7 @@ ipTotal: ipTotal })); } - }); + }); } }); } @@ -128,7 +128,7 @@ } } }, - + dataProvider: function(args) { var dataFns = { zones: function(data) { @@ -142,71 +142,24 @@ }); }, capacity: function(data) { - var latestData =null; - if(window.fetchLatestflag == 1) - { + var latestData =null; + if(window.fetchLatestflag == 1) + { latestData = { - fetchLatest:true - } + fetchLatest:true + } } - else + else { latestData = { fetchLatest:false - } + } } - window.fetchLatestflag = 0; - if (data.zones) { - $.ajax({ - url: createURL('listCapacity'), - data: latestData, - success: function(json) { - var capacities = json.listcapacityresponse.capacity; - var capacity = function(id, converter) { - var result = $.grep(capacities, function(capacity) { - return capacity.type == id; - }); - return result[0] ? result[0] : { - capacityused: 0, - capacitytotal: 0, - percentused: 0 - }; - }; + window.fetchLatestflag = 0; - dataFns.alerts($.extend(data, { - publicIPAllocated: capacity(8).capacityused, - publicIPTotal: capacity(8).capacitytotal, - publicIPPercentage: parseInt(capacity(8).percentused), - privateIPAllocated: capacity(5).capacityused, - privateIPTotal: capacity(5).capacitytotal, - privateIPPercentage: parseInt(capacity(8).percentused), - memoryAllocated: cloudStack.converters.convertBytes(capacity(0).capacityused), - memoryTotal: cloudStack.converters.convertBytes(capacity(0).capacitytotal), - memoryPercentage: parseInt(capacity(0).percentused), - cpuAllocated: cloudStack.converters.convertHz(capacity(1).capacityused), - cpuTotal: cloudStack.converters.convertHz(capacity(1).capacitytotal), - cpuPercentage: parseInt(capacity(1).percentused) - })); - } - }); - } else { - dataFns.alerts($.extend(data, { - publicIPAllocated: 0, - publicIPTotal: 0, - publicIPPercentage: 0, - privateIPAllocated: 0, - privateIPTotal: 0, - privateIPPercentage: 0, - memoryAllocated: 0, - memoryTotal: 0, - memoryPercentage: 0, - cpuAllocated: 0, - cpuTotal: 0, - cpuPercentage: 0 - })); - } + dataFns.alerts(data); }, alerts: function(data) { @@ -273,11 +226,11 @@ complete($.extend(data, { zoneCapacities: $.map(capacities, function(capacity) { if (capacity.podname) { - capacity.zonename = capacity.zonename.concat('
' + _l('label.pod') + ': ' + capacity.podname); + capacity.zonename = capacity.zonename.concat(', ' + _l('label.pod') + ': ' + capacity.podname); } if (capacity.clustername) { - capacity.zonename = capacity.zonename.concat('
' + _l('label.cluster') + ': ' + capacity.clustername); + capacity.zonename = capacity.zonename.concat(', ' + _l('label.cluster') + ': ' + capacity.clustername); } capacity.zonename.replace('Zone:', _l('label.zone') + ':'); diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 34835d6fc95..4a70ca1df7f 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -16,6 +16,59 @@ // under the License. cloudStack.docs = { + //Delete/archive events + helpEventsDeleteType:{ + + desc:'Delete all the events by specifying its TYPE eg . USER.LOGIN', + externalLink:'' + + }, + + helpEventsDeleteDate:{ + + desc:'Delete all the events which have been created after this date ', + externalLink:'' + }, + + helpEventsArchiveType:{ + + desc:'Archive all the events by specifying its TYPE (integer number)', + externalLink:'' + }, + + helpEventsArchiveDate:{ + + desc:'Archive all the events which have been created after this date', + externalLink:'' + }, + + //Delete/archive Alerts + helpAlertsDeleteType:{ + + desc:'Delete all the alerts by specifying its TYPE eg . USER.LOGIN', + externalLink:'' + + }, + + helpAlertsDeleteDate:{ + + desc:'Delete all the alerts which have been created after this date ', + externalLink:'' + }, + + helpAlertsArchiveType:{ + + desc:'Archive all the alerts by specifying its TYPE (integer number)', + externalLink:'' + }, + + helpAlertsArchiveDate:{ + + desc:'Archive all the alerts which have been created after this date', + externalLink:'' + }, + + //Ldap helpLdapQueryFilter: { diff --git a/ui/scripts/events.js b/ui/scripts/events.js index 38f77284de1..1c89b58346c 100644 --- a/ui/scripts/events.js +++ b/ui/scripts/events.js @@ -41,6 +41,107 @@ account: { label: 'label.account' }, created: { label: 'label.date', converter: cloudStack.converters.toLocalDate } }, + + actions: { + // Remove multiple events + remove: { + label: 'Delete Events', + isHeader: true, + addRow: false, + messages: { + notification: function(args) { + return 'Events Deleted'; + } + }, + createForm: { + title:'Delete Events', + desc: '', + fields: { + type: { label: 'By event type' , docID:'helpEventsDeleteType'}, + date: { + label: 'By date (older than)', + docID:'helpEventsDeleteDate', + isDatepicker: true + } + } + }, + action: function(args) { + + var data={}; + + if(args.data.type != "") + $.extend(data, { type:args.data.type }); + + if(args.data.date != "") + $.extend(data, {date:args.data.date }); + + $.ajax({ + + url:createURL("deleteEvents"), + data:data, + dataType:'json', + async: false, + + success:function(data){ + + args.response.success(); + + } + }); + // Reloads window with events removed + $(window).trigger('cloudStack.fullRefresh'); + } + }, + + // Archive multiple events + archive: { + label: 'Archive Events', + isHeader: true, + addRow: false, + messages: { + notification: function(args) { + return 'Archive events'; + } + }, + createForm: { + title:'Archive Events', + desc: '', + fields: { + type: { label: 'By event type' , docID:'helpEventsArchiveType'}, + date: { label: 'By date (older than)' , docID:'helpEventsArchiveDate', isDatepicker: true }, + } + }, + action: function(args) { + var data={}; + + if(args.data.type != "") + $.extend(data, { type:args.data.type }); + + if(args.data.date != "") + $.extend(data, {date:args.data.date }); + + $.ajax({ + + url:createURL("archiveEvents"), + data:data, + dataType:'json', + async: false, + + success:function(data){ + + args.response.success(); + + } + }); + + // Reloads window with events removed + $(window).trigger('cloudStack.fullRefresh'); + } + } + + }, + + advSearchFields: { level: { @@ -132,6 +233,64 @@ }, detailView: { name: 'label.details', + actions: { + + // Remove single event + remove: { + label: 'Delete', + messages: { + notification: function(args) { + return 'Event Deleted'; + }, + confirm: function() { + return 'Are you sure you want to remove this event?'; + } + }, + action: function(args) { + + $.ajax({ + url:createURL("deleteEvents&ids=" +args.context.events[0].id), + success:function(json){ + + args.response.success(); + + } + + }); + $(window).trigger('cloudStack.fullRefresh'); + + } + }, + + // Archive single event + archive: { + label: 'Archive', + messages: { + notification: function(args) { + return 'Event Archived'; + }, + confirm: function() { + return 'Please confirm that you want to archive this event.'; + } + }, + action: function(args) { + + $.ajax({ + url:createURL("archiveEvents&ids=" +args.context.events[0].id), + success:function(json){ + + args.response.success(); + + } + + }); + + + // Reloads window with item archived + $(window).trigger('cloudStack.fullRefresh'); + } + } + }, tabs: { details: { title: 'label.details', @@ -174,6 +333,102 @@ description: { label: 'label.description' }, sent: { label: 'label.date', converter: cloudStack.converters.toLocalDate } }, + + actions: { + // Remove multiple Alerts + remove: { + label: 'Delete Alerts', + isHeader: true, + addRow: false, + messages: { + notification: function(args) { + return 'Alerts Deleted'; + } + }, + createForm: { + title:'Delete Alerts', + desc: '', + fields: { + type: { label: 'By event type' , docID:'helpAlertsDeleteType'}, + date: { label: 'By date (older than)' ,docID:'helpAlertsDeleteDate', isDatepicker: true } + } + }, + action: function(args) { + + var data={}; + + if(args.data.type != "") + $.extend(data, { type:args.data.type }); + + if(args.data.date != "") + $.extend(data, {date:args.data.date }); + + $.ajax({ + + url:createURL("deleteAlerts"), + data:data, + dataType:'json', + async: false, + + success:function(data){ + + args.response.success(); + + } + }); + // Reloads window with events removed + $(window).trigger('cloudStack.fullRefresh'); + } + }, + + // Archive multiple Alerts + archive: { + label: 'Archive Alerts', + isHeader: true, + addRow: false, + messages: { + notification: function(args) { + return 'Alerts Archived'; + } + }, + createForm: { + title:'Archive Alerts', + desc: '', + fields: { + type: { label: 'By event type', docID:'helpAlertsArchiveType' }, + date: { label: 'By date (older than)' , docID:'helpAlertsArchiveDate', isDatepicker: true } + } + }, + action: function(args) { + var data={}; + + if(args.data.type != "") + $.extend(data, { type:args.data.type }); + + if(args.data.date != "") + $.extend(data, {date:args.data.date }); + + $.ajax({ + + url:createURL("archiveAlerts"), + data:data, + dataType:'json', + async: false, + + success:function(data){ + + args.response.success(); + + } + }); + + // Reloads window with events removed + $(window).trigger('cloudStack.fullRefresh'); + } + } + + }, + dataProvider: function(args) { var data = {}; listViewDataProvider(args, data); @@ -190,6 +445,65 @@ }, detailView: { name: 'Alert details', + actions: { + + // Remove single Alert + remove: { + label: 'Delete', + messages: { + notification: function(args) { + return 'Alert Deleted'; + }, + confirm: function() { + return 'Are you sure you want to delete this alert ?'; + } + }, + action: function(args) { + + $.ajax({ + url:createURL("deleteAlerts&ids=" +args.context.alerts[0].id), + success:function(json){ + + args.response.success(); + + } + + }); + $(window).trigger('cloudStack.fullRefresh'); + + } + }, + + archive: { + label: 'Archive', + messages: { + notification: function(args) { + return 'Alert Archived'; + }, + confirm: function() { + return 'Please confirm that you want to archive this alert.'; + } + }, + action: function(args) { + + $.ajax({ + url:createURL("archiveAlerts&ids=" +args.context.alerts[0].id), + success:function(json){ + + args.response.success(); + + } + + }); + + + // Reloads window with item archived + $(window).trigger('cloudStack.fullRefresh'); + } + } + + }, + tabs: { details: { title: 'label.details', diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index d9260b0b2de..75d45aad9c4 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -33,11 +33,10 @@ // Called in networks list, when VPC drop-down is changed // -- if vpcID given, return true if in network specified by vpcID - // -- if vpcID == -1, return true if network is not associated with a VPC + // -- if vpcID == -1, always show all networks vpcFilter: function(data, vpcID) { - return vpcID != -1? - data.vpcid == vpcID : - !data.vpcid; + return vpcID != -1 ? + data.vpcid == vpcID : true; }, // Runs when advanced SG-enabled zone is run, before @@ -401,7 +400,12 @@ includingSecurityGroup = true; break; } - } + } + + if (networkObj.vpcid) { + networkObj._singleSelect = true; + } + //for Advanced SG-enabled zone, list only SG network offerings if(selectedZoneObj.networktype == 'Advanced' && selectedZoneObj.securitygroupsenabled == true) { if(includingSecurityGroup == false) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 8a7c7ad3af1..787239d9528 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -1242,6 +1242,15 @@ } } ], + viewAll: { + path: 'network.secondaryNicIps', + attachTo: 'ipaddress', + title: function(args) { + var title = _l('label.menu.ipaddresses') + ' - ' + args.context.nics[0].name; + + return title; + } + }, dataProvider: function(args) { $.ajax({ url:createURL("listVirtualMachines&details=nics&id=" + args.context.instances[0].id), diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 6fcd46040ef..65be302c0c9 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -34,6 +34,44 @@ return elemData; }; + + var instanceSecondaryIPSubselect = function(args) { + var instance = args.context.instances[0]; + var network = args.context.networks[0]; + var nic = $.grep(instance.nic, function(nic) { + return nic.networkid == network.id; + })[0]; + + // Get NIC IPs + $.ajax({ + url: createURL('listNics'), + data: { + virtualmachineid: instance.id, + nicId: nic.id + }, + success: function(json) { + var nic = json.listnics.nic[0]; + var ips = nic.secondaryip ? nic.secondaryip : []; + var ipSelection = []; + + // Add primary IP as default + ipSelection.push({ id: -1, description: nic.ipaddress + ' (Primary)' }); + + // Add secondary IPs + $(ips).map(function(index, ip) { + ipSelection.push({ + id: ip.ipaddress, + description: ip.ipaddress + }); + }); + + + args.response.success({ + data: ipSelection + }); + } + }) + }; var ipChangeNotice = function() { cloudStack.dialog.confirm({ @@ -620,21 +658,33 @@ var data = { id: args.context.networks[0].id, name: args.data.name, - displaytext: args.data.displaytext, + displaytext: args.data.displaytext }; - + //args.data.networkdomain is null when networkdomain field is hidden if(args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) { $.extend(data, { networkdomain: args.data.networkdomain }); } + + var oldcidr; + $.ajax({ + url: createURL("listNetworks&id=" + args.context.networks[0].id ), + dataType: "json", + async: false, + success: function(json) { + oldcidr = json.listnetworksresponse.network[0].cidr; + + } + }); - if(args.data.cidr !="" ){ - $.extend(data, { - guestvmcidr: args.data.cidr - }); - } + + if(args.data.cidr !="" && args.data.cidr != oldcidr ){ + $.extend(data, { + guestvmcidr: args.data.cidr + }); + } //args.data.networkofferingid is null when networkofferingid field is hidden if(args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) { @@ -1058,400 +1108,164 @@ } }); } + } + } + } + } + }, + secondaryNicIps: { + title: 'label.menu.ipaddresses', + listView: { + id: 'secondaryNicIps', + label: 'label.ips', + fields: { + virtualmachinedisplayname: { label: 'label.vm.name' }, + ipaddress: { + label: 'label.ips', + converter: function(text, item) { + if (item.issourcenat) { + return text + ' [' + _l('label.source.nat') + ']'; + } + + return text; + } + } + }, + actions: { + add: { + label: 'label.acquire.new.ip', + addRow: 'true', + messages: { + confirm: function(args) { + return 'message.acquire.new.ip'; + }, + notification: function(args) { + return 'label.acquire.new.ip'; + } + }, + action: function(args) { + var dataObj = {}; + + $.ajax({ + url: createURL('addIpToNic'), + data: { + nicId: args.context.nics[0].id + }, + success: function(json) { + args.response.success({ + _custom: { + getUpdatedItem: function(data) { + return $.extend( + data.queryasyncjobresultresponse.jobresult.nicsecondaryip, + { + zoneid: args.context.instances[0].zoneid, + virtualmachinedisplayname: args.context.instances[0].displayname + } + ); + }, + jobId: json.addiptovmnicresponse.jobid + } + }); + } + }); }, - egressRules: { - title: 'label.egress.rules', - custom: function(args) { - var context = args.context; + notification: { + poll: pollAsyncJobResult + } + } + }, - return $('
').multiEdit({ - context: context, - noSelect: true, - noHeaderActionsColumn: true, - fields: { - 'cidrlist': { edit: true, label: 'label.cidr.list', isOptional: true }, - 'protocol': { - label: 'label.protocol', - select: function(args) { - args.$select.change(function() { - var $inputs = args.$form.find('th, td'); - var $icmpFields = $inputs.filter(function() { - var name = $(this).attr('rel'); + dataProvider: function(args) { + var data = {}; - return $.inArray(name, [ - 'icmptype', - 'icmpcode' - ]) > -1; - }); - var $otherFields = $inputs.filter(function() { - var name = $(this).attr('rel'); + $.ajax({ + url: createURL('listNics'), + data: { + nicId: args.context.nics[0].id, + virtualmachineid: args.context.instances[0].id + }, + success: function(json) { + var ips = json.listnics.nic ? json.listnics.nic[0].secondaryip : []; - return name != 'cidrlist' && - name != 'icmptype' && - name != 'icmpcode' && - name != 'protocol' && - name != 'add-rule'; - }); + args.response.success({ + data: $(ips).map(function(index, ip) { + return $.extend(ip, { + zoneid: args.context.instances[0].zoneid, + virtualmachinedisplayname: args.context.instances[0].displayname + }); + }) + }); + } + }); + }, - if ($(this).val() == 'icmp') { - $icmpFields.show(); - $otherFields.hide(); - } else if ($(this).val() == 'all') { - $icmpFields.hide(); - $otherFields.hide(); - } else { - $icmpFields.hide(); - $otherFields.show(); - } - }); - - args.response.success({ - data: [ - { name: 'tcp', description: 'TCP' }, - { name: 'udp', description: 'UDP' }, - { name: 'icmp', description: 'ICMP' }, - { name: 'all', description: 'All' } - ] - }); - } - }, - 'startport': { edit: true, label: 'label.start.port', isOptional: true }, - 'endport': { edit: true, label: 'label.end.port', isOptional: true }, - 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true, isOptional: true }, - 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true, isOptional: true }, - 'add-rule': { - label: 'label.add', - addButton: true - } + // Detail view + detailView: { + name: 'Secondary IP address detail', + actions: { + remove: { + label: 'label.action.release.ip', + action: function(args) { + $.ajax({ + url: createURL('removeIpFromNic'), + data: { + id: args.context.secondaryNicIps[0].id }, - add: { - label: 'label.add', - action: function(args) { - var data = { - protocol: args.data.protocol, - cidrlist: args.data.cidrlist, - networkid: args.context.networks[0].id - }; - - if (args.data.icmptype && args.data.icmpcode) { // ICMP - $.extend(data, { - icmptype: args.data.icmptype, - icmpcode: args.data.icmpcode - }); - } else { // TCP/UDP - $.extend(data, { - startport: args.data.startport, - endport: args.data.endport - }); - } - - $.ajax({ - url: createURL('createEgressFirewallRule'), - data: data, - dataType: 'json', - async: true, - success: function(json) { - var jobId = json.createegressfirewallruleresponse.jobid; - - args.response.success({ - _custom: { - jobId: jobId - }, - notification: { - label: 'label.add.egress.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - } - }, - actions: { - destroy: { - label: 'label.remove.rule', - action: function(args) { - $.ajax({ - url: createURL('deleteEgressFirewallRule'), - data: { - id: args.context.multiRule[0].id - }, - dataType: 'json', - async: true, - success: function(data) { - var jobID = data.deleteegressfirewallruleresponse.jobid; - - args.response.success({ - _custom: { - jobId: jobID - }, - notification: { - label: 'label.remove.egress.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - } - } - }, - ignoreEmptyFields: true, - dataProvider: function(args) { - $.ajax({ - url: createURL('listEgressFirewallRules'), - data: { - listAll: true, - networkid: args.context.networks[0].id - }, - dataType: 'json', - async: true, - success: function(json) { - var response = json.listegressfirewallrulesresponse.firewallrule ? - json.listegressfirewallrulesresponse.firewallrule : []; - - args.response.success({ - data: $.map(response, function(rule) { - if (rule.protocol == 'all') { - $.extend(rule, { - startport: 'All', - endport: 'All' - }); - } else if (rule.protocol == 'tcp' || rule.protocol == 'udp') { - if (!rule.startport) { - rule.startport = ' '; - } - - if (!rule.endport) { - rule.endport = ' '; - } - } - - return rule; - }) - }); - } + success: function(json) { + args.response.success({ + _custom: { jobId: json.removeipfromnicresponse.jobid } }); } }); - } - }, + }, + messages: { + confirm: function(args) { + return 'message.action.release.ip'; + }, + notification: function(args) { + return 'label.action.release.ip'; + } + }, + notification: { poll: pollAsyncJobResult } + } + }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + ipaddress: { label: 'label.ip' } + }, + { + id: { label: 'label.id' }, + virtualmachinedisplayname: { label: 'label.vm.name' }, + zonename: { label: 'label.zone.name' } + } + ], - addloadBalancer: { // EIP/ELB Basic zone: Add Load Balancer tab in network detailView - title: 'label.add.load.balancer', - custom: function(args) { - var context = args.context; + dataProvider: function(args) { + $.ajax({ + url: createURL('listNics'), + data: { + nicId: args.context.nics[0].id, + virtualmachineid: args.context.instances[0].id + }, + success: function(json) { + var ips = json.listnics.nic[0].secondaryip - return $('
').addClass('loadBalancer').multiEdit( - { - context: context, - listView: $.extend(true, {}, cloudStack.sections.instances, { - listView: { - filters: false, - - dataProvider: function(args) { - var data = { - page: args.page, - pageSize: pageSize, - domainid: g_domainid, - account: g_account, - networkid: args.context.networks[0].id, - listAll: true - }; - - $.ajax({ - url: createURL('listVirtualMachines'), - data: data, - dataType: 'json', - async: true, - success: function(data) { - args.response.success({ - data: $.grep( - data.listvirtualmachinesresponse.virtualmachine ? - data.listvirtualmachinesresponse.virtualmachine : [], - function(instance) { - var nonAutoScale=0; - if(instance.displayname == null) - nonAutoScale = 1; - else{ - if( instance.displayname.match(/AutoScale-LB-/)==null) - nonAutoScale =1; - else { - if(instance.displayname.match(/AutoScale-LB-/).length) - nonAutoScale =0; - } - } - var isActiveState= $.inArray(instance.state, ['Destroyed','Expunging']) == -1; - return nonAutoScale && isActiveState; - } - ) - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - } - } - }), - multipleAdd: true, - fields: { - 'name': { edit: true, label: 'label.name' }, - 'publicport': { edit: true, label: 'label.public.port' }, - 'privateport': { edit: true, label: 'label.private.port' }, - 'algorithm': { - label: 'label.algorithm', - select: function(args) { - args.response.success({ - data: [ - { name: 'roundrobin', description: _l('label.round.robin') }, - { name: 'leastconn', description: _l('label.least.connections') }, - { name: 'source', description: _l('label.source') } - ] - }); - } - }, - 'sticky': { - label: 'label.stickiness', - custom: { - buttonLabel: 'label.configure', - action: cloudStack.lbStickyPolicy.dialog() - } - }, - 'autoScale': { - label: 'AutoScale', - custom: { - requireValidation: true, - buttonLabel: 'label.configure', - action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler) - } - }, - 'add-vm': { - label: 'label.add.vms', - addButton: true - } - }, - - add: { //basic zone - elastic IP - Add Load Balancer tab - Add VMs button - label: 'label.add.vms', - action: function(args) { - var data = { - algorithm: args.data.algorithm, - name: args.data.name, - privateport: args.data.privateport, - publicport: args.data.publicport, - openfirewall: false, - domainid: g_domainid, - account: g_account - }; - - if('vpc' in args.context) { //from VPC section - if(args.data.tier == null) { - args.response.error('Tier is required'); - return; - } - $.extend(data, { - networkid: args.data.tier - }); - } - else { //from Guest Network section - $.extend(data, { - networkid: args.context.networks[0].id - }); - } - - var stickyData = $.extend(true, {}, args.data.sticky); - - $.ajax({ - url: createURL('createLoadBalancerRule'), - data: data, - dataType: 'json', - async: true, - success: function(data) { - var itemData = args.itemData; - //var jobID = data.createloadbalancerruleresponse.jobid; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule - - $.ajax({ - url: createURL('assignToLoadBalancerRule'), - data: { - id: data.createloadbalancerruleresponse.id, - virtualmachineids: $.map(itemData, function(elem) { - return elem.id; - }).join(',') - }, - dataType: 'json', - async: true, - success: function(data) { - var jobID = data.assigntoloadbalancerruleresponse.jobid; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule - var lbCreationComplete = false; - - args.response.success({ - _custom: { - jobId: jobID - }, - notification: { - label: 'label.add.load.balancer', - poll: function(args) { - var complete = args.complete; - var error = args.error; - - pollAsyncJobResult({ - _custom: args._custom, - complete: function(args) { - if (lbCreationComplete) { - return; - } - - lbCreationComplete = true; - cloudStack.dialog.notice({ - message: _l('message.add.load.balancer.under.ip') + - args.data.loadbalancer.publicip - }); - - if (stickyData && - stickyData.methodname && - stickyData.methodname != 'None') { - cloudStack.lbStickyPolicy.actions.add( - args.data.loadbalancer.id, - stickyData, - complete, // Complete - complete // Error - ); - } else { - complete(); - } - }, - error: error - }); - } - } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } + args.response.success({ + data: $.grep($(ips).map(function(index, ip) { + return $.extend(ip, { + zonename: args.context.instances[0].zonename, + virtualmachinedisplayname: args.context.instances[0].displayname }); - } - }, - - - dataProvider: function(args) { - args.response.success({ //no LB listing in AddLoadBalancer tab - data: [] - }); - } + }), function(ip) { + return ip.ipaddress == args.context.secondaryNicIps[0].ipaddress; + })[0] + }); } - ); + }); } } } @@ -1595,10 +1409,11 @@ account: g_account }); } - } + } + $.ajax({ url: createURL('associateIpAddress'), - data: dataObj, + data: dataObj, success: function(data) { args.response.success({ _custom: { @@ -1661,10 +1476,10 @@ async: true, success: function(json) { var items = json.listpublicipaddressesresponse.publicipaddress; - - $(items).each(function() { - getExtaPropertiesForIpObj(this, args); - }); + + $(items).each(function() { + getExtaPropertiesForIpObj(this, args); + }); args.response.success({ actionFilter: actionFilters.ipAddress, @@ -1864,6 +1679,10 @@ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { filters: false, + subselect: { + label: 'label.use.vm.ip', + dataProvider: instanceSecondaryIPSubselect + }, dataProvider: function(args) { var data = { page: args.page, @@ -1878,7 +1697,7 @@ args.response.success({ data: null }); return; } - + if('vpc' in args.context) { if($tierSelect.size() && $tierSelect.val() != '-1' ){ data.networkid = $tierSelect.val(); @@ -1930,6 +1749,10 @@ ipaddressid: args.context.ipAddresses[0].id, virtualmachineid: args.context.instances[0].id }; + + if (args._subselect && args._subselect != -1) { + data.vmguestip = args._subselect; + } if('vpc' in args.context) { if(args.tierID == '-1') { @@ -2124,19 +1947,17 @@ dataProvider: function(args) { var items = args.context.ipAddresses; - // Get network data $.ajax({ url: createURL('listPublicIpAddresses'), - data: { - id: args.context.ipAddresses[0].id, - listAll: true + data: { + id: args.context.ipAddresses[0].id }, dataType: "json", async: true, success: function(json) { var ipObj = json.listpublicipaddressesresponse.publicipaddress[0]; getExtaPropertiesForIpObj(ipObj, args); - + var network = $.grep( args.context.vpc ? args.context.vpc[0].network : args.context.networks, @@ -2607,6 +2428,20 @@ loadBalancing: { listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { + fields: { + name: { label: 'label.name' }, + displayname: { label: 'label.display.name' }, + zonename: { label: 'label.zone.name' }, + state: { + label: 'label.state', + indicator: { + 'Running': 'on', + 'Stopped': 'off', + 'Destroyed': 'off', + 'Error': 'off' + } + } + }, filters: false, dataProvider: function(args) { var itemData = $.isArray(args.context.multiRule) && args.context.multiRule[0]['_itemData'] ? @@ -2774,6 +2609,17 @@ action: cloudStack.lbStickyPolicy.dialog() } }, + + 'health-check':{ + label:'Health Check', + custom:{ + requireValidation: true , + buttonLabel:'Configure', + action:cloudStack.uiCustom.healthCheck() + + } + }, + 'autoScale': { label: 'AutoScale', custom: { @@ -3190,6 +3036,10 @@ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { filters: false, + subselect: { + label: 'label.use.vm.ip', + dataProvider: instanceSecondaryIPSubselect + }, dataProvider: function(args) { var networkid; if('vpc' in args.context) @@ -3285,6 +3135,10 @@ openfirewall: false }; + if (args.itemData[0]._subselect && args.itemData[0]._subselect != -1) { + data.vmguestip = args.itemData[0]._subselect; + } + if('vpc' in args.context) { //from VPC section if(args.data.tier == null) { args.response.error('Tier is required'); diff --git a/ui/scripts/ui-custom/dashboard.js b/ui/scripts/ui-custom/dashboard.js index 960d100d100..6d923187c1b 100644 --- a/ui/scripts/ui-custom/dashboard.js +++ b/ui/scripts/ui-custom/dashboard.js @@ -80,15 +80,15 @@ }); } else { if ($li.attr('concat-value')) { - var val = $(_l(arrayValue).toString().split('
')).map(function() { - var val = this.toString(); + var val = $(_l(arrayValue).toString().split(', ')).map(function() { + var val = _s(this.toString()); var concatValue = parseInt($li.attr('concat-value')); return val.length >= concatValue ? val.substring(0, concatValue).concat('...') : val; - }).toArray().join('
'); + }).toArray().join('
'); - $arrayElem.html(_s(val)); + $arrayElem.html(val); } else { $arrayElem.html(_s(_l(arrayValue))); } diff --git a/ui/scripts/ui-custom/enableStaticNAT.js b/ui/scripts/ui-custom/enableStaticNAT.js index 47d5dd298db..1b2bf7bab2e 100644 --- a/ui/scripts/ui-custom/enableStaticNAT.js +++ b/ui/scripts/ui-custom/enableStaticNAT.js @@ -92,9 +92,10 @@ var start = args.start; start(); - $dataList.fadeOut(function() { + $dataList.fadeOut(function() { action({ tierID: $dataList.find('.tier-select select').val(), + _subselect: $dataList.find('tr.multi-edit-selected .subselect select').val(), context: $.extend(true, {}, context, { instances: [ $dataList.find('tr.multi-edit-selected').data('json-obj') diff --git a/ui/scripts/ui-custom/healthCheck.js b/ui/scripts/ui-custom/healthCheck.js new file mode 100644 index 00000000000..c4c84e5236b --- /dev/null +++ b/ui/scripts/ui-custom/healthCheck.js @@ -0,0 +1,342 @@ +// 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. + +(function($, cloudStack) { + + cloudStack.uiCustom.healthCheck = function(args) { + + // Place outer args here as local variables + // i.e, -- var dataProvider = args.dataProvider + + return function(args){ + if(args.context.multiRules == undefined) { //LB rule is not created yet + cloudStack.dialog.notice({ message: _l('Health Check can only be configured on a created LB rule') }); + return; + } + + var formData = args.formData; + var forms = $.extend(true, {}, args.forms); + var topFieldForm, bottomFieldForm , $topFieldForm , $bottomFieldForm; + var topfields = forms.topFields; + + var $healthCheckDesc = $('
Your load balancer will automatically perform health checks on your cloudstack instances and only route traffic to instances that pass the health check
').addClass('health-check-description'); + var $healthCheckConfigTitle = $('


Configuration Options :
').addClass('health-check-config-title'); + var $healthCheckAdvancedTitle = $('


Advanced Options :
').addClass('health-check-advanced-title'); + + var $healthCheckDialog = $('
').addClass('health-check'); + $healthCheckDialog.append($healthCheckDesc); + $healthCheckDialog.append($healthCheckConfigTitle); + var $loadingOnDialog = $('
').addClass('loading-overlay'); + + var policyObj = null; + var pingpath1 = '/'; + var responsetimeout1 = '2'; + var healthinterval1 = '5'; + var healthythreshold1 = '2'; + var unhealthythreshold1 = '1'; + + $.ajax({ + url: createURL('listLBHealthCheckPolicies'), + data: { + lbruleid: args.context.multiRules[0].id + }, + async: false, + success: function(json) { + if(json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) { + policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0]; + pingpath1 = policyObj.pingpath; //API bug: API doesn't return it + responsetimeout1 = policyObj.responsetime; + healthinterval1 = policyObj.healthcheckinterval; + healthythreshold1 = policyObj.healthcheckthresshold; + unhealthythreshold1 = policyObj.unhealthcheckthresshold; + } + } + }); + + topFieldForm = cloudStack.dialog.createForm({ + context: args.context, + noDialog: true, // Don't render a dialog, just return $formContainer + form: { + title: '', + fields:{ + pingpath: {label: 'Ping Path', docID:'helpAccountUsername' , validation: {required: false}, defaultValue: pingpath1} + } + } + }); + + $topFieldForm = topFieldForm.$formContainer; + $topFieldForm.appendTo($healthCheckDialog); + + $healthCheckDialog.append($healthCheckAdvancedTitle); + + bottomFieldForm = cloudStack.dialog.createForm ({ + context:args.context, + noDialog:true, + form:{ + title:'', + fields:{ + responsetimeout: {label: 'Response Timeout (in sec)' , validation:{required:false}, defaultValue: responsetimeout1}, + healthinterval: {label: 'Health Check Interval (in sec)', validation:{required:false}, defaultValue: healthinterval1}, + healthythreshold: {label: 'Healthy Threshold', validation: {required:false}, defaultValue: healthythreshold1}, + unhealthythreshold: {label: 'Unhealthy Threshold' , validation: { required:false}, defaultValue: unhealthythreshold1} + } + } + }); + + $bottomFieldForm = bottomFieldForm.$formContainer; + $bottomFieldForm.appendTo($healthCheckDialog); + + + var buttons = [ + { + text: _l('label.cancel'), + 'class': 'cancel', + click: function() { + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + } + ]; + + if(policyObj == null) { //policy is not created yet + buttons.push( + { + text: _l('Create'), + 'class': 'ok', + click: function() { + $loadingOnDialog.appendTo($healthCheckDialog); + var formData = cloudStack.serializeForm($healthCheckDialog.find('form')); + var data = { + lbruleid: args.context.multiRules[0].id, + pingpath: formData.pingpath, + responsetimeout: formData.responsetimeout, + intervaltime: formData.healthinterval, + healthythreshold: formData.healthythreshold, + unhealthythreshold: formData.unhealthythreshold + }; + + $.ajax({ + url: createURL('createLBHealthCheckPolicy'), + data: data, + success: function(json) { + var jobId = json.createlbhealthcheckpolicyresponse.jobid; + var createLBHealthCheckPolicyIntervalId = setInterval(function(){ + $.ajax({ + url: createURL('queryAsyncJobResult'), + data: { + jobid: jobId + }, + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(createLBHealthCheckPolicyIntervalId); + + if (result.jobstatus == 1) { + cloudStack.dialog.notice({ message: _l('Health Check Policy has been created') }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + else if (result.jobstatus == 2) { + cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + } + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + } + ); + } + else { //policy exists already + buttons.push( + //Update Button (begin) - call delete API first, then create API + { + text: _l('Update'), + 'class': 'ok', + click: function() { + $loadingOnDialog.appendTo($healthCheckDialog); + + $.ajax({ + url: createURL('deleteLBHealthCheckPolicy'), + data: { + id : policyObj.id + }, + success: function(json) { + var jobId = json.deletelbhealthcheckpolicyresponse.jobid; + var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){ + $.ajax({ + url: createURL('queryAsyncJobResult'), + data: { + jobid: jobId + }, + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(deleteLBHealthCheckPolicyIntervalId); + + if (result.jobstatus == 1) { + var formData = cloudStack.serializeForm($healthCheckDialog.find('form')); + var data = { + lbruleid: args.context.multiRules[0].id, + pingpath: formData.pingpath, + responsetimeout: formData.responsetimeout, + intervaltime: formData.healthinterval, + healthythreshold: formData.healthythreshold, + unhealthythreshold: formData.unhealthythreshold + }; + + $.ajax({ + url: createURL('createLBHealthCheckPolicy'), + data: data, + success: function(json) { + var jobId = json.createlbhealthcheckpolicyresponse.jobid; + var createLBHealthCheckPolicyIntervalId = setInterval(function(){ + $.ajax({ + url: createURL('queryAsyncJobResult'), + data: { + jobid: jobId + }, + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(createLBHealthCheckPolicyIntervalId); + + if (result.jobstatus == 1) { + cloudStack.dialog.notice({ message: _l('Health Check Policy has been updated') }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + else if (result.jobstatus == 2) { + cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + } + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else if (result.jobstatus == 2) { + cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + } + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + } + //Update Button (end) + , + //Delete Button (begin) - call delete API + { + text: _l('Delete'), + 'class': 'delete', + click: function() { + $loadingOnDialog.appendTo($healthCheckDialog); + + $.ajax({ + url: createURL('deleteLBHealthCheckPolicy'), + data: { + id : policyObj.id + }, + success: function(json) { + var jobId = json.deletelbhealthcheckpolicyresponse.jobid; + var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){ + $.ajax({ + url: createURL('queryAsyncJobResult'), + data: { + jobid: jobId + }, + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(deleteLBHealthCheckPolicyIntervalId); + + if (result.jobstatus == 1) { + cloudStack.dialog.notice({ message: _l('Health Check Policy has been deleted') }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + else if (result.jobstatus == 2) { + cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) }); + $loadingOnDialog.remove(); + $healthCheckDialog.dialog('destroy'); + $('.overlay').remove(); + } + } + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + } + //Delete Button (end) + ); + } + + $healthCheckDialog.dialog({ + title: 'Health Check Wizard', + width: 600, + height: 600, + draggable: true, + closeonEscape: false, + overflow:'auto', + open:function() { + $("button").each(function(){ + $(this).attr("style", "left: 400px; position: relative; margin-right: 5px; "); + }); + + $('.ui-dialog .delete').css('left','140px'); + + }, + buttons: buttons + }).closest('.ui-dialog').overlay(); + + } + } + }(jQuery, cloudStack)); + + diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index 8e4ed7e010a..b55df79e7be 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -91,7 +91,8 @@ options = options ? options : {}; $(data).each(function() { - var id = this[fields.id]; + var item = this; + var id = item[fields.id]; var $select = $('
') .addClass('select') @@ -107,17 +108,22 @@ .val(id) .click(function() { var $select = $(this).closest('.select'); + var isSingleSelect = $select.hasClass('single-select'); var $radio = $select.find('input[type=radio]'); var $newNetwork = $(this).closest('.content').find('.select.new-network'); var $otherSelects = $select.siblings().filter(':visible'); var isCheckbox = $(this).attr('type') == 'checkbox'; - var isSingleSelect = $(this).closest('.select-container').hasClass('single-select'); if (isCheckbox) { - if ((isSingleSelect || !$otherSelects.size()) && - $newNetwork.find('input[type=checkbox]').is(':unchecked')) { - $otherSelects.find('input[type=checkbox]').attr('checked', false); + if (isSingleSelect) { + $select.siblings('.single-select:visible').find('input[type=checkbox]') + .attr('checked', false); + + $(this).closest('.select').find('input[type=radio]').click(); + } + if ((!$otherSelects.size()) && + $newNetwork.find('input[type=checkbox]').is(':unchecked')) { // Set as default $(this).closest('.select').find('input[type=radio]').click(); } @@ -144,6 +150,10 @@ $selects.append($select); + if (item._singleSelect) { + $select.addClass('single-select'); + } + if (options.secondary) { var $secondary = $('
').addClass('secondary-input').append( $('') @@ -164,6 +174,11 @@ $(this).closest('.select').siblings().find('input[type=checkbox]') .attr('checked', false); } + + if ($select.hasClass('single-select')) { + $select.siblings('.single-select:visible').find('input[type=checkbox]') + .attr('checked', false); + } }) .after( $('
').addClass('name').html(options.secondary.desc) @@ -614,7 +629,7 @@ }); // 'No VPC' option - $('