diff --git a/agent-simulator/tomcatconf/components-simulator.xml.in b/agent-simulator/tomcatconf/components-simulator.xml.in
deleted file mode 100755
index 1b7df46ad2b..00000000000
--- a/agent-simulator/tomcatconf/components-simulator.xml.in
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
-
diff --git a/api/src/com/cloud/agent/api/to/DnsmasqTO.java b/api/src/com/cloud/agent/api/to/DnsmasqTO.java
index f99878c2fed..c7be04d4900 100644
--- a/api/src/com/cloud/agent/api/to/DnsmasqTO.java
+++ b/api/src/com/cloud/agent/api/to/DnsmasqTO.java
@@ -20,11 +20,14 @@ public class DnsmasqTO {
String routerIp;
String gateway;
String netmask;
+ String startIpOfSubnet;
- public DnsmasqTO(String routerIp, String gateway, String netmask) {
+ public DnsmasqTO(String routerIp, String gateway, String netmask, String StartIpOfSubnet) {
this.routerIp = routerIp;
+ this.startIpOfSubnet = StartIpOfSubnet;
this.gateway = gateway;
this.netmask =netmask;
+
}
public void setRouterIp(String routerIp){
@@ -39,6 +42,10 @@ public class DnsmasqTO {
this.netmask = netmask ;
}
+ public void setStartIpOfSubnet( String ipOfSubNet) {
+ startIpOfSubnet = ipOfSubNet;
+ }
+
public String getRouterIp() {
return routerIp;
}
@@ -50,4 +57,8 @@ public class DnsmasqTO {
public String getNetmask() {
return netmask;
}
+ public String getStartIpOfSubnet() {
+ return startIpOfSubnet;
+ }
+
}
diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
index b84d20a9239..46ee01bc8a3 100644
--- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
+++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
@@ -52,6 +52,7 @@ public class VirtualMachineTO {
boolean rebootOnCrash;
boolean enableHA;
boolean limitCpuUse;
+ boolean enableDynamicallyScaleVm;
String vncPassword;
String vncAddr;
Map params;
@@ -102,6 +103,14 @@ public class VirtualMachineTO {
this.id = id;
}
+ public boolean isEnableDynamicallyScaleVm() {
+ return enableDynamicallyScaleVm;
+ }
+
+ public void setEnableDynamicallyScaleVm(boolean enableDynamicallyScaleVm) {
+ this.enableDynamicallyScaleVm = enableDynamicallyScaleVm;
+ }
+
public String getName() {
return name;
}
diff --git a/api/src/com/cloud/dc/DedicatedResources.java b/api/src/com/cloud/dc/DedicatedResources.java
new file mode 100755
index 00000000000..e8e5ab3dffc
--- /dev/null
+++ b/api/src/com/cloud/dc/DedicatedResources.java
@@ -0,0 +1,33 @@
+// 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.dc;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface DedicatedResources extends InfrastructureEntity, InternalIdentity, Identity{
+ long getId();
+ Long getDataCenterId();
+ Long getPodId();
+ Long getClusterId();
+ Long getHostId();
+ Long getDomainId();
+ Long getAccountId();
+ String getUuid();
+
+}
diff --git a/api/src/com/cloud/deploy/DeploymentClusterPlanner.java b/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
index 1a19c71dbfa..8b15ea56e8f 100644
--- a/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
+++ b/api/src/com/cloud/deploy/DeploymentClusterPlanner.java
@@ -18,6 +18,7 @@ package com.cloud.deploy;
import java.util.List;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
@@ -40,6 +41,7 @@ public interface DeploymentClusterPlanner extends DeploymentPlanner {
List orderClusters(VirtualMachineProfile extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid)
throws InsufficientServerCapacityException;
- PlannerResourceUsage getResourceUsage();
+ PlannerResourceUsage getResourceUsage(VirtualMachineProfile extends VirtualMachine> vmProfile,
+ DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException;
}
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 6dfb1ab57b6..ed4ba1254f0 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -438,6 +438,10 @@ public class EventTypes {
public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
public static final String EVENT_PORTABLE_IP_TRANSFER = "PORTABLE.IP.TRANSFER";
+ // Dedicated Resources
+ public static final String EVENT_DEDICATE_RESOURCE = "DEDICATE.RESOURCE";
+ public static final String EVENT_DEDICATE_RESOURCE_RELEASE = "DEDICATE.RESOURCE.RELEASE";
+
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
diff --git a/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java b/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
index 186faf75f78..9375544ac28 100644
--- a/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
+++ b/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
@@ -33,6 +33,9 @@ public interface GlobalLoadBalancingRulesService {
GlobalLoadBalancerRule updateGlobalLoadBalancerRule(UpdateGlobalLoadBalancerRuleCmd updateGslbCmd);
+ boolean revokeAllGslbRulesForAccount(com.cloud.user.Account caller, long accountId)
+ throws com.cloud.exception.ResourceUnavailableException;
+
/*
* methods for managing sites participating in global load balancing
*/
diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java
index 903eebc5bf8..8153a3f1af6 100755
--- a/api/src/com/cloud/user/AccountService.java
+++ b/api/src/com/cloud/user/AccountService.java
@@ -16,22 +16,15 @@
// under the License.
package com.cloud.user;
-import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
import com.cloud.domain.Domain;
import com.cloud.exception.PermissionDeniedException;
-import com.cloud.utils.Pair;
public interface AccountService {
@@ -83,13 +76,11 @@ public interface AccountService {
Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId);
- Pair, Long> finalizeAccountDomainForList(Account caller, String accountName, Long domainId, Long projectId);
-
Account getActiveAccountByName(String accountName, Long domainId);
- Account getActiveAccountById(Long accountId);
+ Account getActiveAccountById(long accountId);
- Account getAccount(Long accountId);
+ Account getAccount(long accountId);
User getActiveUser(long userId);
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupService.java b/api/src/org/apache/cloudstack/affinity/AffinityGroupService.java
index 26c32c89c1f..7423c4864d5 100644
--- a/api/src/org/apache/cloudstack/affinity/AffinityGroupService.java
+++ b/api/src/org/apache/cloudstack/affinity/AffinityGroupService.java
@@ -18,7 +18,6 @@ package org.apache.cloudstack.affinity;
import java.util.List;
-import com.cloud.exception.ResourceInUseException;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
@@ -45,10 +44,8 @@ public interface AffinityGroupService {
* @param account
* @param domainId
* @param affinityGroupName
- * @throws ResourceInUseException
*/
- boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName)
- throws ResourceInUseException;
+ boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName);
/** Lists Affinity Groups in your account
* @param account
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 1e9435f6a8e..ab1402ccde9 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -206,6 +206,7 @@ public class ApiConstants {
public static final String STATE = "state";
public static final String STATUS = "status";
public static final String STORAGE_TYPE = "storagetype";
+ public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
public static final String SYSTEM_VM_TYPE = "systemvmtype";
public static final String TAGS = "tags";
public static final String TARGET_IQN = "targetiqn";
@@ -304,6 +305,8 @@ public class ApiConstants {
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 MAX_DATA_VOLUMES_LIMIT = "maxdatavolumeslimit";
+ public static final String MAX_HOSTS_PER_CLUSTER = "maxhostspercluster";
public static final String PROJECT_ID = "projectid";
public static final String PROJECT_IDS = "projectids";
public static final String PROJECT = "project";
@@ -402,6 +405,7 @@ public class ApiConstants {
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 VCENTER = "vcenter";
public static final String ADD_VSM_FLAG = "addvsmflag";
public static final String END_POINT = "endpoint";
public static final String REGION_ID = "regionid";
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 0732e77a781..096bf26c196 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -16,113 +16,6 @@
// under the License.
package org.apache.cloudstack.api;
-import java.text.DecimalFormat;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-import com.cloud.vm.NicSecondaryIp;
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcOffering;
-import org.apache.cloudstack.api.ApiConstants.HostDetails;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
-import org.apache.cloudstack.api.response.CapacityResponse;
-import org.apache.cloudstack.api.response.ClusterResponse;
-import org.apache.cloudstack.api.response.ConditionResponse;
-import org.apache.cloudstack.api.response.ConfigurationResponse;
-import org.apache.cloudstack.api.response.CounterResponse;
-import org.apache.cloudstack.api.response.CreateCmdResponse;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.EventResponse;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.api.response.FirewallResponse;
-import org.apache.cloudstack.api.response.FirewallRuleResponse;
-import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
-import org.apache.cloudstack.api.response.HostForMigrationResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-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.InternalLoadBalancerElementResponse;
-import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
-import org.apache.cloudstack.api.response.IsolationMethodResponse;
-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;
-import org.apache.cloudstack.api.response.NetworkACLResponse;
-import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.PodResponse;
-import org.apache.cloudstack.api.response.PrivateGatewayResponse;
-import org.apache.cloudstack.api.response.ProjectAccountResponse;
-import org.apache.cloudstack.api.response.ProjectInvitationResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.ProviderResponse;
-import org.apache.cloudstack.api.response.RegionResponse;
-import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
-import org.apache.cloudstack.api.response.ResourceCountResponse;
-import org.apache.cloudstack.api.response.ResourceLimitResponse;
-import org.apache.cloudstack.api.response.ResourceTagResponse;
-import org.apache.cloudstack.api.response.S3Response;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.ServiceResponse;
-import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
-import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
-import org.apache.cloudstack.api.response.StaticRouteResponse;
-import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
-import org.apache.cloudstack.api.response.StoragePoolForMigrationResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.SwiftResponse;
-import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.TrafficMonitorResponse;
-import org.apache.cloudstack.api.response.TrafficTypeResponse;
-import org.apache.cloudstack.api.response.UsageRecordResponse;
-import org.apache.cloudstack.api.response.UserResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
-import org.apache.cloudstack.api.response.VlanIpRangeResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.VpcOfferingResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.VpnUsersResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.api.response.*;
-import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
-import org.apache.cloudstack.region.Region;
-import org.apache.cloudstack.region.PortableIp;
-import org.apache.cloudstack.region.PortableIpRange;
-import org.apache.cloudstack.usage.Usage;
-
import com.cloud.async.AsyncJob;
import com.cloud.capacity.Capacity;
import com.cloud.configuration.Configuration;
@@ -164,6 +57,12 @@ 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.NetworkACL;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcOffering;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
@@ -192,6 +91,106 @@ import com.cloud.vm.Nic;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.ApiConstants.HostDetails;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
+import org.apache.cloudstack.api.response.CapacityResponse;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.ConditionResponse;
+import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.CounterResponse;
+import org.apache.cloudstack.api.response.CreateCmdResponse;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.EventResponse;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.FirewallResponse;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
+import org.apache.cloudstack.api.response.HostForMigrationResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+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.InternalLoadBalancerElementResponse;
+import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
+import org.apache.cloudstack.api.response.IsolationMethodResponse;
+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;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.api.response.NetworkACLResponse;
+import org.apache.cloudstack.api.response.NetworkOfferingResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.PortableIpRangeResponse;
+import org.apache.cloudstack.api.response.PortableIpResponse;
+import org.apache.cloudstack.api.response.PrivateGatewayResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import org.apache.cloudstack.api.response.ProjectInvitationResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ProviderResponse;
+import org.apache.cloudstack.api.response.RegionResponse;
+import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
+import org.apache.cloudstack.api.response.ResourceCountResponse;
+import org.apache.cloudstack.api.response.ResourceLimitResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
+import org.apache.cloudstack.api.response.S3Response;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.ServiceResponse;
+import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
+import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
+import org.apache.cloudstack.api.response.StaticRouteResponse;
+import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.SwiftResponse;
+import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.TrafficMonitorResponse;
+import org.apache.cloudstack.api.response.TrafficTypeResponse;
+import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
+import org.apache.cloudstack.api.response.VlanIpRangeResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.VpcOfferingResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.VpnUsersResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpRange;
+import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.usage.Usage;
+
+import java.text.DecimalFormat;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
public interface ResponseGenerator {
UserResponse createUserResponse(UserAccount user);
@@ -259,7 +258,7 @@ public interface ResponseGenerator {
StoragePoolResponse createStoragePoolResponse(StoragePool pool);
- StoragePoolForMigrationResponse createStoragePoolForMigrationResponse(StoragePool pool);
+ StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool);
ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities);
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
index 7c3d1e95e57..86f30067b18 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
@@ -17,10 +17,13 @@
package org.apache.cloudstack.api.command.admin.internallb;
-import java.util.List;
-
-import javax.inject.Inject;
-
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@@ -31,13 +34,8 @@ import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
import org.apache.log4j.Logger;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.user.Account;
-import com.cloud.user.UserContext;
+import javax.inject.Inject;
+import java.util.List;
@APICommand(name = "configureInternalLoadBalancerElement", responseObject=InternalLoadBalancerElementResponse.class,
description="Configures an Internal Load Balancer element.", since="4.2.0")
@@ -98,11 +96,8 @@ public class ConfigureInternalLoadBalancerElementCmd extends BaseAsyncCmd {
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{
- s_logger.debug("hello alena");
UserContext.current().setEventDetails("Internal load balancer element: " + id);
- s_logger.debug("hello alena");
VirtualRouterProvider result = _service.get(0).configureInternalLoadBalancerElement(getId(), getEnabled());
- s_logger.debug("hello alena");
if (result != null){
InternalLoadBalancerElementResponse routerResponse = _responseGenerator.createInternalLbElementResponse(result);
routerResponse.setResponseName(getCommandName());
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
index 5178d685889..74eb2b9bf8f 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
@@ -71,15 +71,19 @@ public class CreateStoragePoolCmd extends BaseCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
required=true, description="the Zone ID for the storage pool")
private Long zoneId;
-
+
@Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
required=false, description="the storage provider name")
private String storageProviderName;
-
+
@Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING,
required=false, description="the scope of the storage: cluster or zone")
private String scope;
+ @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=false,
+ description="hypervisor type of the hosts in zone that will be attached to this storage pool. KVM, VMware supported as of now.")
+ private String hypervisor;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -111,18 +115,18 @@ public class CreateStoragePoolCmd extends BaseCmd {
public Long getZoneId() {
return zoneId;
}
-
+
public String getStorageProviderName() {
return this.storageProviderName;
}
-
+
public String getScope() {
- return this.scope;
+ return this.scope;
}
- /////////////////////////////////////////////////////
- /////////////// API Implementation///////////////////
- /////////////////////////////////////////////////////
+ public String getHypervisor() {
+ return hypervisor;
+ }
@Override
public String getCommandName() {
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
index 37d007c0376..ed6ca04c16f 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
@@ -16,24 +16,23 @@
// under the License.
package org.apache.cloudstack.api.command.admin.storage;
-import java.util.ArrayList;
-import java.util.List;
-
+import com.cloud.async.AsyncJob;
+import com.cloud.storage.StoragePool;
+import com.cloud.utils.Pair;
import org.apache.cloudstack.api.APICommand;
-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.ListResponse;
-import org.apache.cloudstack.api.response.StoragePoolForMigrationResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
-import com.cloud.async.AsyncJob;
-import com.cloud.storage.StoragePool;
-import com.cloud.utils.Pair;
+import org.apache.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
@APICommand(name = "findStoragePoolsForMigration", description="Lists storage pools available for migration of a volume.",
- responseObject=StoragePoolForMigrationResponse.class)
+ responseObject=StoragePoolResponse.class)
public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(FindStoragePoolsForMigrationCmd.class.getName());
@@ -72,13 +71,13 @@ public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
public void execute() {
Pair, List extends StoragePool>> pools =
_mgr.listStoragePoolsForMigrationOfVolume(getId());
- ListResponse response = new ListResponse();
- List poolResponses = new ArrayList();
+ ListResponse response = new ListResponse();
+ List poolResponses = new ArrayList();
List extends StoragePool> allPools = pools.first();
List extends StoragePool> suitablePoolList = pools.second();
for (StoragePool pool : allPools) {
- StoragePoolForMigrationResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
+ StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
Boolean suitableForMigration = false;
for (StoragePool suitablePool : suitablePoolList) {
if (suitablePool.getId() == pool.getId()) {
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
index 9bbae064376..6eaac38d29a 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
@@ -38,7 +38,7 @@ public class UpdateVPCOfferingCmd extends BaseAsyncCmd{
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = VpcOfferingResponse.class,
+ @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = VpcOfferingResponse.class, required=true,
description="the id of the VPC offering")
private Long id;
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
index ea4a010ab93..f80e17626fd 100644
--- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
@@ -30,7 +30,6 @@ import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceInUseException;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@@ -123,17 +122,12 @@ public class DeleteAffinityGroupCmd extends BaseAsyncCmd {
@Override
public void execute(){
- try{
- boolean result = _affinityGroupService.deleteAffinityGroup(id, accountName, domainId, name);
- if (result) {
- SuccessResponse response = new SuccessResponse(getCommandName());
- this.setResponseObject(response);
- } else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete affinity group");
- }
- } catch (ResourceInUseException ex) {
- s_logger.warn("Exception: ", ex);
- throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, ex.getMessage());
+ boolean result = _affinityGroupService.deleteAffinityGroup(id, accountName, domainId, name);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete affinity group");
}
}
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
index fe5decdf5fc..77ec4e7609f 100644
--- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
@@ -87,13 +87,19 @@ public class DeleteGlobalLoadBalancerRuleCmd extends BaseAsyncCmd {
@Override
public void execute(){
- _gslbService.deleteGlobalLoadBalancerRule(this);
- UserContext.current().setEventDetails("Deleting global Load balancer Id: " + getGlobalLoadBalancerId());
+ UserContext.current().setEventDetails("Deleting global Load balancer rule Id: " + getGlobalLoadBalancerId());
+ boolean result = _gslbService.deleteGlobalLoadBalancerRule(this);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Global Load Balancer rule.");
+ }
}
@Override
public String getSyncObjType() {
- return BaseAsyncCmd.networkSyncObject;
+ return BaseAsyncCmd.gslbSyncObject;
}
@Override
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
index bd56c744a2f..714e9e79926 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
@@ -42,7 +42,7 @@ public class RestartVPCCmd extends BaseAsyncCmd{
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VpcResponse.class,
+ @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VpcResponse.class, required=true,
description="the id of the VPC")
private Long id;
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
index 2cc3c98b087..a6410214cc3 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
@@ -38,11 +38,11 @@ public class UpdateVPCCmd extends BaseAsyncCmd{
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VpcResponse.class,
+ @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VpcResponse.class, required=true,
description="the id of the VPC")
private Long id;
- @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC")
+ @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC", required=true)
private String vpcName;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC")
diff --git a/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java b/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
index 36021876184..2d37add5eb4 100644
--- a/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
@@ -42,6 +42,14 @@ public class HypervisorCapabilitiesResponse extends BaseResponse {
@SerializedName(ApiConstants.SECURITY_GROUP_EANBLED) @Param(description="true if security group is supported")
private boolean isSecurityGroupEnabled;
+ @SerializedName(ApiConstants.MAX_DATA_VOLUMES_LIMIT) @Param(description="the maximum number of Data Volumes that can be attached for this hypervisor")
+ private Integer maxDataVolumesLimit;
+
+ @SerializedName(ApiConstants.MAX_HOSTS_PER_CLUSTER) @Param(description="the maximum number of Hosts per cluster for this hypervisor")
+ private Integer maxHostsPerCluster;
+
+ @SerializedName(ApiConstants.STORAGE_MOTION_ENABLED) @Param(description="true if storage motion is supported")
+ private boolean isStorageMotionSupported;
public String getId() {
return id;
@@ -83,4 +91,28 @@ public class HypervisorCapabilitiesResponse extends BaseResponse {
public void setIsSecurityGroupEnabled(Boolean sgEnabled) {
this.isSecurityGroupEnabled = sgEnabled;
}
+
+ public Boolean getIsStorageMotionSupported() {
+ return this.isStorageMotionSupported;
+ }
+
+ public void setIsStorageMotionSupported(Boolean smSupported) {
+ this.isStorageMotionSupported = smSupported;
+ }
+
+ public Integer getMaxDataVolumesLimit() {
+ return maxDataVolumesLimit;
+ }
+
+ public void setMaxDataVolumesLimit(Integer maxDataVolumesLimit) {
+ this.maxDataVolumesLimit = maxDataVolumesLimit;
+ }
+
+ public Integer getMaxHostsPerCluster() {
+ return maxHostsPerCluster;
+ }
+
+ public void setMaxHostsPerCluster(Integer maxHostsPerCluster) {
+ this.maxHostsPerCluster = maxHostsPerCluster;
+ }
}
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
index d6847d55846..70c3d79c4c0 100644
--- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
@@ -166,6 +166,10 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
@SerializedName(ApiConstants.DISPLAY_NETWORK) @Param(description="an optional field, whether to the display the network to the end user or not.")
private Boolean displayNetwork;
+ @SerializedName(ApiConstants.ACL_ID) @Param(description="ACL Id associated with the VPC network")
+ private String aclId;
+
+
public Boolean getDisplayNetwork() {
return displayNetwork;
}
@@ -352,4 +356,12 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
public void setIp6Cidr(String ip6Cidr) {
this.ip6Cidr = ip6Cidr;
}
+
+ public String getAclId() {
+ return aclId;
+ }
+
+ public void setAclId(String aclId) {
+ this.aclId = aclId;
+ }
}
diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolForMigrationResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolForMigrationResponse.java
deleted file mode 100644
index f0bbcb19136..00000000000
--- a/api/src/org/apache/cloudstack/api/response/StoragePoolForMigrationResponse.java
+++ /dev/null
@@ -1,248 +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.response;
-
-import java.util.Date;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
-import com.cloud.serializer.Param;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
-import com.google.gson.annotations.SerializedName;
-
-@EntityReference(value=StoragePool.class)
-public class StoragePoolForMigrationResponse extends BaseResponse {
- @SerializedName("id") @Param(description="the ID of the storage pool")
- private String id;
-
- @SerializedName("zoneid") @Param(description="the Zone ID of the storage pool")
- private String zoneId;
-
- @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the storage pool")
- private String zoneName;
-
- @SerializedName("podid") @Param(description="the Pod ID of the storage pool")
- private String podId;
-
- @SerializedName("podname") @Param(description="the Pod name of the storage pool")
- private String podName;
-
- @SerializedName("name") @Param(description="the name of the storage pool")
- private String name;
-
- @SerializedName("ipaddress") @Param(description="the IP address of the storage pool")
- private String ipAddress;
-
- @SerializedName("path") @Param(description="the storage pool path")
- private String path;
-
- @SerializedName("created") @Param(description="the date and time the storage pool was created")
- private Date created;
-
- @SerializedName("type") @Param(description="the storage pool type")
- private String type;
-
- @SerializedName("clusterid") @Param(description="the ID of the cluster for the storage pool")
- private String clusterId;
-
- @SerializedName("clustername") @Param(description="the name of the cluster for the storage pool")
- private String clusterName;
-
- @SerializedName("disksizetotal") @Param(description="the total disk size of the storage pool")
- private Long diskSizeTotal;
-
- @SerializedName("disksizeallocated") @Param(description="the host's currently allocated disk size")
- private Long diskSizeAllocated;
-
- @SerializedName("disksizeused") @Param(description="the host's currently used disk size")
- private Long diskSizeUsed;
-
- @SerializedName("tags") @Param(description="the tags for the storage pool")
- private String tags;
-
- @SerializedName(ApiConstants.STATE) @Param(description="the state of the storage pool")
- private StoragePoolStatus state;
-
- @SerializedName(ApiConstants.SCOPE) @Param(description="the scope of the storage pool")
- private String scope;
-
- @SerializedName("suitableformigration") @Param(description="true if this pool is suitable to migrate a volume," +
- " false otherwise")
- private Boolean suitableForMigration;
-
- /**
- * @return the scope
- */
- public String getScope() {
- return scope;
- }
-
- /**
- * @param scope the scope to set
- */
- public void setScope(String scope) {
- this.scope = scope;
- }
-
- @Override
- public String getObjectId() {
- return this.getId();
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getZoneId() {
- return zoneId;
- }
-
- public void setZoneId(String zoneId) {
- this.zoneId = zoneId;
- }
-
- public String getZoneName() {
- return zoneName;
- }
-
- public void setZoneName(String zoneName) {
- this.zoneName = zoneName;
- }
-
- public String getPodId() {
- return podId;
- }
-
- public void setPodId(String podId) {
- this.podId = podId;
- }
-
- public String getPodName() {
- return podName;
- }
-
- public void setPodName(String podName) {
- this.podName = podName;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getIpAddress() {
- return ipAddress;
- }
-
- public void setIpAddress(String ipAddress) {
- this.ipAddress = ipAddress;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public String getClusterId() {
- return clusterId;
- }
-
- public void setClusterId(String clusterId) {
- this.clusterId = clusterId;
- }
-
- public String getClusterName() {
- return clusterName;
- }
-
- public void setClusterName(String clusterName) {
- this.clusterName = clusterName;
- }
-
- public Long getDiskSizeTotal() {
- return diskSizeTotal;
- }
-
- public void setDiskSizeTotal(Long diskSizeTotal) {
- this.diskSizeTotal = diskSizeTotal;
- }
-
- public Long getDiskSizeAllocated() {
- return diskSizeAllocated;
- }
-
- public void setDiskSizeAllocated(Long diskSizeAllocated) {
- this.diskSizeAllocated = diskSizeAllocated;
- }
-
- public Long getDiskSizeUsed() {
- return diskSizeUsed;
- }
-
- public void setDiskSizeUsed(Long diskSizeUsed) {
- this.diskSizeUsed = diskSizeUsed;
- }
-
- public String getTags() {
- return tags;
- }
-
- public void setTags(String tags) {
- this.tags = tags;
- }
-
- public StoragePoolStatus getState() {
- return state;
- }
-
- public void setState(StoragePoolStatus state) {
- this.state = state;
- }
-
- public void setSuitableForMigration(Boolean suitableForMigration) {
- this.suitableForMigration = suitableForMigration;
- }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
index 4411ddcb112..965407d9952 100644
--- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
@@ -16,16 +16,15 @@
// under the License.
package org.apache.cloudstack.api.response;
-import java.util.Date;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
import com.cloud.serializer.Param;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import java.util.Date;
@EntityReference(value=StoragePool.class)
public class StoragePoolResponse extends BaseResponse {
@@ -40,13 +39,13 @@ public class StoragePoolResponse extends BaseResponse {
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
-
+
@SerializedName("podid") @Param(description="the Pod ID of the storage pool")
private String podId;
@SerializedName("podname") @Param(description="the Pod name of the storage pool")
private String podName;
-
+
@SerializedName("name") @Param(description="the name of the storage pool")
private String name;
@@ -82,10 +81,17 @@ public class StoragePoolResponse extends BaseResponse {
@SerializedName(ApiConstants.STATE) @Param(description="the state of the storage pool")
private StoragePoolStatus state;
-
+
@SerializedName(ApiConstants.SCOPE) @Param(description="the scope of the storage pool")
private String scope;
+ @SerializedName(ApiConstants.HYPERVISOR) @Param(description="the hypervisor type of the storage pool")
+ private String hypervisor;
+
+ @SerializedName("suitableformigration") @Param(description="true if this pool is suitable to migrate a volume," +
+ " false otherwise")
+ private Boolean suitableForMigration;
+
/**
* @return the scope
*/
@@ -100,6 +106,14 @@ public class StoragePoolResponse extends BaseResponse {
this.scope = scope;
}
+ public String getHypervisor() {
+ return hypervisor;
+ }
+
+ public void setHypervisor(String hypervisor) {
+ this.hypervisor = hypervisor;
+ }
+
@Override
public String getObjectId() {
return this.getId();
@@ -132,11 +146,11 @@ public class StoragePoolResponse extends BaseResponse {
public String getZoneType() {
return zoneType;
}
-
+
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
-
+
public String getPodId() {
return podId;
}
@@ -248,4 +262,8 @@ public class StoragePoolResponse extends BaseResponse {
public void setState(StoragePoolStatus state) {
this.state = state;
}
+
+ public void setSuitableForMigration(Boolean suitableForMigration) {
+ this.suitableForMigration = suitableForMigration;
+ }
}
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index fc7715dd4c9..d0ead0e8f10 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+label.view.secondary.ips=View secondary IPs
+message.acquire.ip.nic=Please confirm that you would like to acquire a new secondary IP for this NIC.
NOTE: You need to manually configure the newly-acquired secondary IP inside the virtual machine.
message.select.affinity.groups=Please select any affinity groups you want this VM to belong to:
message.no.affinity.groups=You do not have any affinity groups. Please continue to the next step.
label.action.delete.nic=Remove NIC
@@ -53,6 +55,7 @@ label.account.specific=Account-Specific
label.account=Account
label.accounts=Accounts
label.acquire.new.ip=Acquire New IP
+label.acquire.new.secondary.ip=Acquire new secondary IP
label.action.attach.disk.processing=Attaching Disk....
label.action.attach.disk=Attach Disk
label.action.attach.iso.processing=Attaching ISO....
diff --git a/client/pom.xml b/client/pom.xml
index 0c38ecb65d2..ab758eb2a67 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -29,6 +29,11 @@
org.apache.cloudstack
cloud-plugin-acl-static-role-based
${project.version}
+
+
+ org.apache.cloudstack
+ cloud-plugin-dedicated-resources
+ ${project.version}
org.apache.cloudstack
@@ -136,6 +141,11 @@
cloud-plugin-planner-implicit-dedication
${project.version}
+
+ org.apache.cloudstack
+ cloud-plugin-explicit-dedication
+ ${project.version}
+
org.apache.cloudstack
cloud-plugin-host-allocator-random
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index a10b9db7501..049e483bf5e 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -93,7 +93,7 @@
-
+
@@ -156,9 +156,17 @@
-
+
-
+
+
+
+
+
+
@@ -673,7 +681,6 @@
-
@@ -796,6 +803,7 @@
+
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index fd5479f44b4..5eccf366c66 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -265,6 +265,10 @@ addSecondaryStorage=1
updateHostPassword=1
releaseHostReservation=1
+#### VmWare DC
+addVmwareDc=1
+removeVmwareDc=1
+
#### volume commands
attachVolume=15
uploadVolume=15
@@ -276,10 +280,6 @@ extractVolume=15
migrateVolume=15
resizeVolume=15
updateVolume=1
-addVolumeDetail=1
-updateVolumeDetail=1
-removeVolumeDetail=1
-listVolumeDetails=1
#### registration command: FIXME -- this really should be something in management server that
#### generates a new key for the user and they just have to
@@ -350,10 +350,6 @@ updateNetwork=15
addNicToVirtualMachine=15
removeNicFromVirtualMachine=15
updateDefaultNicForVirtualMachine=15
-addNicDetail=1
-updateNicDetail=1
-removeNicDetail=1
-listNicDetails=1
####
addIpToNic=15
@@ -641,3 +637,16 @@ listInternalLoadBalancerVMs=1
### Network Isolation methods listing
listNetworkIsolationMethods=1
+#### Dedicated Resource commands
+dedicateZone=1
+dedicatePod=1
+dedicateCluster=1
+dedicateHost=1
+releaseDedicatedZone=1
+releaseDedicatedPod=1
+releaseDedicatedCluster=1
+releaseDedicatedHost=1
+listDedicatedZones=1
+listDedicatedPods=1
+listDedicatedClusters=1
+listDedicatedHosts=1
diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in
index e946f448d90..93ef21f679b 100644
--- a/client/tomcatconf/componentContext.xml.in
+++ b/client/tomcatconf/componentContext.xml.in
@@ -24,28 +24,27 @@
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-
@@ -171,7 +170,7 @@
-
+
@@ -260,13 +259,22 @@
-
+
+
-
+
+
+
+
+
+
+
diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in
index 6fa9d38baa4..16fd88337fb 100644
--- a/client/tomcatconf/nonossComponentContext.xml.in
+++ b/client/tomcatconf/nonossComponentContext.xml.in
@@ -77,6 +77,10 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/tomcatconf/simulatorComponentContext.xml.in b/client/tomcatconf/simulatorComponentContext.xml.in
index 652c4c824ff..d71cf162569 100644
--- a/client/tomcatconf/simulatorComponentContext.xml.in
+++ b/client/tomcatconf/simulatorComponentContext.xml.in
@@ -234,4 +234,10 @@
+
+
+
+
+
+
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java
index 058aa15338e..a108a2a7bed 100644
--- a/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java
+++ b/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java
@@ -24,10 +24,18 @@ import com.cloud.agent.api.to.StorageFilerTO;
public class MigrateWithStorageCommand extends Command {
VirtualMachineTO vm;
Map volumeToFiler;
+ String tgtHost;
public MigrateWithStorageCommand(VirtualMachineTO vm, Map volumeToFiler) {
this.vm = vm;
this.volumeToFiler = volumeToFiler;
+ this.tgtHost = null;
+ }
+
+ public MigrateWithStorageCommand(VirtualMachineTO vm, Map volumeToFiler, String tgtHost) {
+ this.vm = vm;
+ this.volumeToFiler = volumeToFiler;
+ this.tgtHost = tgtHost;
}
public VirtualMachineTO getVirtualMachine() {
@@ -38,6 +46,10 @@ public class MigrateWithStorageCommand extends Command {
return volumeToFiler;
}
+ public String getTargetHost() {
+ return tgtHost;
+ }
+
@Override
public boolean executeInSequence() {
return true;
diff --git a/core/src/com/cloud/agent/api/UnPlugNicCommand.java b/core/src/com/cloud/agent/api/UnPlugNicCommand.java
index b6cab8872f5..b964292f1a2 100644
--- a/core/src/com/cloud/agent/api/UnPlugNicCommand.java
+++ b/core/src/com/cloud/agent/api/UnPlugNicCommand.java
@@ -39,7 +39,7 @@ public class UnPlugNicCommand extends Command{
this.instanceName = instanceName;
}
- public String getInstanceName() {
+ public String getVmName() {
return instanceName;
}
}
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 8b996d1bfed..9e40eefc11a 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -642,7 +642,7 @@ public class VirtualRoutingResource implements Manager {
for (IpAliasTO ipAliasTO : revokedIpAliasTOs) {
args = args + ipAliasTO.getAlias_count()+":"+ipAliasTO.getRouterip()+":"+ipAliasTO.getNetmask()+"-";
}
- args = args + " " ;
+ args = args + "- " ;
List activeIpAliasTOs = cmd.getCreateIpAliasTos();
for (IpAliasTO ipAliasTO : activeIpAliasTOs) {
args = args + ipAliasTO.getAlias_count()+":"+ipAliasTO.getRouterip()+":"+ipAliasTO.getNetmask()+"-";
diff --git a/core/src/com/cloud/network/DnsMasqConfigurator.java b/core/src/com/cloud/network/DnsMasqConfigurator.java
index ee8e5fc2e13..dd349263c0c 100644
--- a/core/src/com/cloud/network/DnsMasqConfigurator.java
+++ b/core/src/com/cloud/network/DnsMasqConfigurator.java
@@ -71,7 +71,7 @@ import java.util.List;
"conf-dir=/etc/dnsmasq.d\n",
"dhcp-option=tag:net1,3,ipaddress\n",
"dhcp-option=tag:net1,1,netmask\n",
- "dhcp-option=6,10.147.28.149,8.8.8.8\n",
+ "dhcp-option=6,router_ip,external_dns\n",
"dhcp-optsfile=/etc/dhcpopts.txt\n",
@@ -85,11 +85,21 @@ import java.util.List;
String netmask="";
String domain= dnsMasqconfigcmd.getDomain();
String dnsServers="";
+ String dns_external="";
+ if (dnsMasqconfigcmd.getDns1()!= null) {
+ dns_external = dnsMasqconfigcmd.getDns1()+",";
+ }
+ if (dnsMasqconfigcmd.getDns2() != null) {
+ dns_external = dns_external+dnsMasqconfigcmd.getDns2()+",";
+ }
+ dns_external = dns_external + "*";
+ dns_external = dns_external.replace(",*","");
int i=0;
for (; i< dnsmasqTOs.size(); i++) {
- range=range + "dhcp-range=set:range"+i+","+dnsmasqTOs.get(i).getRouterIp()+",static\n";
+ range=range + "dhcp-range=set:range"+i+","+dnsmasqTOs.get(i).getStartIpOfSubnet()+",static\n";
gateway=gateway +"dhcp-option=tag:range"+i+",3,"+dnsmasqTOs.get(i).getGateway()+"\n";
netmask=netmask +"dhcp-option=tag:range"+i+",1,"+dnsmasqTOs.get(i).getNetmask()+"\n";
+ dnsServers=dnsServers+"dhcp-option=tag:range"+i+",6,"+dnsmasqTOs.get(i).getRouterIp()+","+dns_external+"\n";
}
dnsMasqconf.set(12, "domain="+domain+"\n");
dnsMasqconf.set(14, "domain="+domain+"\n");
@@ -97,21 +107,7 @@ import java.util.List;
dnsMasqconf.set(18, range);
dnsMasqconf.set(22, gateway);
dnsMasqconf.set(23, netmask);
- if (dnsMasqconfigcmd.getInternal_dns1() != null) {
- dnsServers = dnsServers+dnsMasqconfigcmd.getInternal_dns1()+",";
- }
- if (dnsMasqconfigcmd.getInternal_dns2() != null) {
- dnsServers = dnsServers+dnsMasqconfigcmd.getInternal_dns2()+",";
- }
- if (dnsMasqconfigcmd.getDns1() != null) {
- dnsServers = dnsServers+dnsMasqconfigcmd.getDns1()+",";
- }
- if (dnsMasqconfigcmd.getDns2() != null) {
- dnsServers = dnsServers+dnsMasqconfigcmd.getDns2()+",";
- }
- dnsServers = dnsServers +"*";
- dnsServers = dnsServers.replace(",*", "");
- dnsMasqconf.set(24,"dhcp-option=6,"+dnsServers);
+ dnsMasqconf.set(24,dnsServers);
return dnsMasqconf.toArray( new String[dnsMasqconf.size()]);
}
diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
index 628ad64c0dc..c8aac27da8c 100644
--- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
+++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java
@@ -250,6 +250,13 @@ public class HttpTemplateDownloader implements TemplateDownloader {
}
} else {
remoteSize2 = Long.parseLong(contentLengthHeader.getValue());
+ if ( remoteSize2 == 0 ) {
+ status = TemplateDownloader.Status.DOWNLOAD_FINISHED;
+ String downloaded = "(download complete remote=" + remoteSize + "bytes)";
+ errorString = "Downloaded " + totalBytes + " bytes " + downloaded;
+ downloadTime = 0;
+ return 0;
+ }
}
if (remoteSize == 0) {
diff --git a/developer/pom.xml b/developer/pom.xml
index 3dc276adc23..9bfb79294fd 100644
--- a/developer/pom.xml
+++ b/developer/pom.xml
@@ -13,7 +13,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
cloud-developer
- Apache CloudStack Developer Tools
+ Apache CloudStack Developer Mode
pom
org.apache.cloudstack
diff --git a/docs/en-US/CloudStack_GSoC_Guide.ent b/docs/en-US/CloudStack_GSoC_Guide.ent
new file mode 100644
index 00000000000..17415873334
--- /dev/null
+++ b/docs/en-US/CloudStack_GSoC_Guide.ent
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/docs/en-US/CloudStack_GSoC_Guide.xml b/docs/en-US/CloudStack_GSoC_Guide.xml
new file mode 100644
index 00000000000..91c2967fc45
--- /dev/null
+++ b/docs/en-US/CloudStack_GSoC_Guide.xml
@@ -0,0 +1,52 @@
+
+
+%BOOK_ENTITIES;
+
+%xinclude;
+]>
+
+
+
+
+
+ &PRODUCT; Guide for the 2013 Google Summer of Code
+ Apache CloudStack
+ 4.3.0
+ 1
+
+
+
+ Guide for 2013 Google Summer of Code Projects.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/en-US/acquire-new-ip-for-vpc.xml b/docs/en-US/acquire-new-ip-for-vpc.xml
index 785e80bb874..c0cb876d483 100644
--- a/docs/en-US/acquire-new-ip-for-vpc.xml
+++ b/docs/en-US/acquire-new-ip-for-vpc.xml
@@ -39,28 +39,43 @@
Click the Configure button of the VPC to which you want to deploy the VMs.
The VPC page is displayed where all the tiers you created are listed in a
diagram.
-
-
- Click the Settings icon.
The following options are displayed.
- IP Addresses
+ Internal LB
- Gateways
+ Public LB IP
- Site-to-Site VPN
+ Static NAT
- Network ACLs
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
Select IP Addresses.
- The IP Addresses page is displayed.
+ The Public IP Addresses page is displayed.
Click Acquire New IP, and click Yes in the confirmation dialog.
@@ -70,4 +85,4 @@
rules.
-
\ No newline at end of file
+
diff --git a/docs/en-US/add-gateway-vpc.xml b/docs/en-US/add-gateway-vpc.xml
index 616794a51d1..a081faf7768 100644
--- a/docs/en-US/add-gateway-vpc.xml
+++ b/docs/en-US/add-gateway-vpc.xml
@@ -21,8 +21,8 @@
Adding a Private Gateway to a VPC
A private gateway can be added by the root admin only. The VPC private network has 1:1
- relationship with the NIC of the physical network. No gateways with duplicated VLAN and IP are
- allowed in the same data center.
+ relationship with the NIC of the physical network. You can configure multiple private gateways
+ to a single VPC. No gateways with duplicated VLAN and IP are allowed in the same data center.
Log in to the &PRODUCT; UI as an administrator or end user.
@@ -45,16 +45,34 @@
The following options are displayed.
- IP Addresses
+ Internal LB
+
+ Public LB IP
+
+
+ Static NAT
+
+
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
Private Gateways
- Site-to-Site VPN
+ Public IP Addresses
- Network ACLs
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
@@ -96,9 +114,38 @@
VLAN: The VLAN associated with the VPC
gateway.
+
+ Source NAT: Select this option to enable the source
+ NAT service on the VPC private gateway.
+ See .
+
+
+ ACL: Controls both ingress and egress traffic on a
+ VPC private gateway. By default, all the traffic is blocked.
+ See .
+
The new gateway appears in the list. You can repeat these steps to add more gateway for
this VPC.
+
+ Source NAT on Private Gateway
+ You might want to deploy multiple VPCs with the same super CIDR and guest tier CIDR.
+ Therefore, multiple guest VMs from different VPCs can have the same IPs to reach a enterprise
+ data center through the private gateway. In such cases, a NAT service need to be configured on
+ the private gateway. If Source NAT is enabled, the guest VMs in VPC reaches the enterprise
+ network via private gateway IP address by using the NAT service.
+ The Source NAT service on a private gateway can be enabled while adding the private
+ gateway. On deletion of a private gateway, source NAT rules specific to the private gateway
+ are deleted.
+
+
+ ACL on Private Gateway
+ The traffic on the VPC private gateway is controlled by creating both ingress and egress
+ network ACL rules. The ACLs contains both allow and deny rules. As per the rule, all the
+ ingress traffic to the private gateway interface and all the egress traffic out from the
+ private gateway interface are blocked. You can change this default behaviour while creating a
+ private gateway.
+
diff --git a/docs/en-US/add-loadbalancer-rule-vpc.xml b/docs/en-US/add-loadbalancer-rule-vpc.xml
index bba3e5ad134..b7b9e3e7613 100644
--- a/docs/en-US/add-loadbalancer-rule-vpc.xml
+++ b/docs/en-US/add-loadbalancer-rule-vpc.xml
@@ -21,103 +21,310 @@
-->
Adding Load Balancing Rules on a VPC
- A &PRODUCT; user or administrator may create load balancing rules that balance traffic
- received at a public IP to one or more VMs that belong to a network tier that provides load
- balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the rule
- to a set of VMs within a VPC.
-
-
- Log in to the &PRODUCT; UI as an administrator or end user.
-
-
- In the left navigation, choose Network.
-
-
- In the Select view, select VPC.
- All the VPCs that you have created for the account is listed in the page.
-
-
- Click the Configure button of the VPC to which you want to configure load balancing
- rules.
- The VPC page is displayed where all the tiers you created are listed in a
- diagram.
-
-
- Click the Settings icon.
- The following options are displayed.
-
+ In a VPC, you can configure two types of load balancing—external LB and internal LB.
+ External LB is nothing but a LB rule created to redirect the traffic received at a public IP of
+ the VPC virtual router. The traffic is load balanced within a tier based on your configuration.
+ Citrix NetScaler and VPC virtual router are supported for external LB. When you use internal LB
+ service, traffic received at a tier is load balanced across different tiers within the VPC. For
+ example, traffic reached at Web tier is redirected to Application tier. External load balancing
+ devices are not supported for internal LB. The service is provided by a internal LB VM
+ configured on the target tier.
+
+ Load Balancing Within a Tier (External LB)
+ A &PRODUCT; user or administrator may create load balancing rules that balance traffic
+ received at a public IP to one or more VMs that belong to a network tier that provides load
+ balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the
+ rule to a set of VMs within a VPC.
+
+
+ Log in to the &PRODUCT; UI as an administrator or end user.
+
+
+ In the left navigation, choose Network.
+
+
+ In the Select view, select VPC.
+ All the VPCs that you have created for the account is listed in the page.
+
+
+ Click the Configure button of the VPC, for which you want to configure load balancing
+ rules.
+ The VPC page is displayed where all the tiers you created listed in a diagram.
+ For each tier, the following options are displayed:
+
+
+ Internal LB
+
+
+ Public LB IP
+
+
+ Static NAT
+
+
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
+
+
+
+
+ In the Router node, select Public IP Addresses.
+ The IP Addresses page is displayed.
+
+
+ Click the IP address for which you want to create the rule, then click the
+ Configuration tab.
+
+
+ In the Load Balancing node of the diagram, click View All.
+
+
+ Select the tier to which you want to apply the rule.
+
+
+ Specify the following:
+
+
+ Name: A name for the load balancer rule.
+
+
+ Public Port: The port that receives the incoming
+ traffic to be balanced.
+
+
+ Private Port: The port that the VMs will use to
+ receive the traffic.
+
+
+ Algorithm. Choose the load balancing algorithm
+ you want &PRODUCT; to use. &PRODUCT; supports the following well-known
+ algorithms:
+
+
+ Round-robin
+
+
+ Least connections
+
+
+ Source
+
+
+
+
+ Stickiness. (Optional) Click Configure and choose
+ the algorithm for the stickiness policy. See Sticky Session Policies for Load Balancer
+ Rules.
+
+
+ Add VMs: Click Add VMs, then select two or more
+ VMs that will divide the load of incoming traffic, and click Apply.
+
+
+
+
+ The new load balancing rule appears in the list. You can repeat these steps to add more
+ load balancing rules for this IP address.
+
+
+ Load Balancing Across Tiers
+ &PRODUCT; supports sharing workload across different tiers within your VPC. Assume that
+ multiple tiers are set up in your environment, such as Web tier and Application tier. Traffic
+ to each tier is balanced on the VPC virtual router on the public side, as explained in . If you want the traffic coming from the Web tier to
+ the Application tier to be balanced, use the internal load balancing feature offered by
+ &PRODUCT;.
+
+ How Does Internal LB Work in VPC?
+ In this figure, a public LB rule is created for the public IP 72.52.125.10 with public
+ port 80 and private port 81. The LB rule, created on the VPC virtual router, is applied on
+ the traffic coming from the Internet to the VMs on the Web tier. On the Application tier two
+ internal load balancing rules are created. An internal LB rule for the guest IP 10.10.10.4
+ with load balancer port 23 and instance port 25 is configured on the VM, InternalLBVM1.
+ Another internal LB rule for the guest IP 10.10.10.4 with load balancer port 45 and instance
+ port 46 is configured on the VM, InternalLBVM1. Another internal LB rule for the guest IP
+ 10.10.10.6, with load balancer port 23 and instance port 25 is configured on the VM,
+ InternalLBVM2.
+
+
+
+
+
+ vpc-lb.png: Configuring internal LB for VPC
+
+
+
+
+ Enabling Internal LB on a VPC Tier
+
- IP Addresses
+ Create a network offering, as given in .
- Gateways
+ Create an internal load balancing rule and apply, as given in .
+
+
+
+
+ Creating a Network Offering for Internal LB
+ To have internal LB support on VPC, create a network offering as follows:
+
+
+ Log in to the &PRODUCT; UI as a user or admin.
- Site-to-Site VPN
+ From the Select Offering drop-down, choose Network Offering.
- Network ACLs
-
-
-
-
- Select IP Addresses.
- The IP Addresses page is displayed.
-
-
- Click the IP address for which you want to create the rule, then click the Configuration
- tab.
-
-
- In the Load Balancing node of the diagram, click View All.
-
-
- Select the tier to which you want to apply the rule.
-
- In a VPC, the load balancing service is supported only on a single tier.
-
-
-
- Specify the following:
-
-
- Name: A name for the load balancer rule.
+ Click Add Network Offering.
- Public Port: The port that receives the incoming
- traffic to be balanced.
-
-
- Private Port: The port that the VMs will use to
- receive the traffic.
-
-
- Algorithm. Choose the load balancing algorithm you
- want &PRODUCT; to use. &PRODUCT; supports the following well-known algorithms:
+ In the dialog, make the following choices:
- Round-robin
+ Name: Any desired name for the network
+ offering.
- Least connections
+ Description: A short description of the
+ offering that can be displayed to users.
- Source
+ Network Rate: Allowed data transfer rate in MB
+ per second.
+
+
+ Traffic Type: The type of network traffic that
+ will be carried on the network.
+
+
+ Guest Type: Choose whether the guest network is
+ isolated or shared.
+
+
+ Persistent: Indicate whether the guest network
+ is persistent or not. The network that you can provision without having to deploy a
+ VM on it is termed persistent network.
+
+
+ VPC: This option indicate whether the guest
+ network is Virtual Private Cloud-enabled. A Virtual Private Cloud (VPC) is a
+ private, isolated part of &PRODUCT;. A VPC can have its own virtual network topology
+ that resembles a traditional physical network. For more information on VPCs, see
+ .
+
+
+ Specify VLAN: (Isolated guest networks only)
+ Indicate whether a VLAN should be specified when this offering is used.
+
+
+ Supported Services: Select Load Balancer.
+ Select InternalLbVM from the provider list.
+
+
+ Load Balancer Type: Select Internal LB from the
+ drop-down.
+
+
+ System Offering: Choose the system service
+ offering that you want virtual routers to use in this network.
+
+
+ Conserve mode: Indicate whether to use conserve
+ mode. In this mode, network resources are allocated only when the first virtual
+ machine starts in the network.
- Stickiness. (Optional) Click Configure and choose
- the algorithm for the stickiness policy. See Sticky Session Policies for Load Balancer
- Rules.
+ Click OK and the network offering is created.
+
+
+
+
+ Creating an Internal LB Rule
+
+
+ Log in to the &PRODUCT; UI as an administrator or end user.
- Add VMs: Click Add VMs, then select two or more VMs
- that will divide the load of incoming traffic, and click Apply.
+ In the left navigation, choose Network.
-
-
-
- The new load balancing rule appears in the list. You can repeat these steps to add more load
- balancing rules for this IP address.
-
\ No newline at end of file
+
+ In the Select view, select VPC.
+ All the VPCs that you have created for the account is listed in the page.
+
+
+ Locate the VPC for which you want to configure internal LB, then click
+ Configure.
+ The VPC page is displayed where all the tiers you created listed in a
+ diagram.
+
+
+ Locate the Tier for which you want to configure an internal LB rule, click Internal
+ LB.
+ In the Internal LB page, click Add Internal LB.
+
+
+ In the dialog, specify the following:
+
+
+ Name: A name for the load balancer rule.
+
+
+ Description: A short description of the rule
+ that can be displayed to users.
+
+
+ Source IP Address: The source IP from which
+ traffic originates. Typically, this is the IP of an instance on another tier within
+ your VPC.
+
+
+ Source Port: The port associated with the
+ source IP. Traffic on this port is load balanced.
+
+
+ Instance Port: The port of the internal LB
+ VM.
+
+
+ Algorithm. Choose the load balancing algorithm
+ you want &PRODUCT; to use. &PRODUCT; supports the following well-known
+ algorithms:
+
+
+ Round-robin
+
+
+ Least connections
+
+
+ Source
+
+
+
+
+
+
+
+
+
diff --git a/docs/en-US/add-portforward-rule-vpc.xml b/docs/en-US/add-portforward-rule-vpc.xml
index c3dbc39bb19..5b1bb49a0a3 100644
--- a/docs/en-US/add-portforward-rule-vpc.xml
+++ b/docs/en-US/add-portforward-rule-vpc.xml
@@ -35,28 +35,42 @@
Click the Configure button of the VPC to which you want to deploy the VMs.
The VPC page is displayed where all the tiers you created are listed in a
diagram.
-
-
- Click the Settings icon.
- The following options are displayed.
+ For each tier, the following options are displayed:
- IP Addresses
+ Internal LB
- Gateways
+ Public LB IP
- Site-to-Site VPN
+ Static NAT
- Network ACLs
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
- Choose an existing IP address or acquire a new IP address. Click the name of the IP
- address in the list.
+ In the Router node, select Public IP Addresses.
The IP Addresses page is displayed.
@@ -95,7 +109,7 @@
Add VM: Click Add VM. Select the name of the
instance to which this rule applies, and click Apply.
- You can test the rule by opening an ssh session to the instance.
+ You can test the rule by opening an SSH session to the instance.
diff --git a/docs/en-US/add-tier.xml b/docs/en-US/add-tier.xml
index 6beaab2a151..e5334d39ca6 100644
--- a/docs/en-US/add-tier.xml
+++ b/docs/en-US/add-tier.xml
@@ -41,6 +41,9 @@
Click the Configure button of the VPC for which you want to set up tiers.
+
+
+ Click Create network.
The Add new tier dialog is displayed, as follows:
@@ -62,7 +65,7 @@
Network Offering: The following default network
- offerings are listed: DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
+ offerings are listed: Internal LB, DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
DefaultIsolatedNetworkOfferingForVpcNetworks
In a VPC, only one tier can be created by using LB-enabled network offering.
diff --git a/docs/en-US/add-vm-to-tier.xml b/docs/en-US/add-vm-to-tier.xml
index e401eed2656..c7d769d9d11 100644
--- a/docs/en-US/add-vm-to-tier.xml
+++ b/docs/en-US/add-vm-to-tier.xml
@@ -33,13 +33,21 @@
Click the Configure button of the VPC to which you want to deploy the VMs.
- The VPC page is displayed where all the tiers you created are listed.
+ The VPC page is displayed where all the tiers you have created are listed.
- Click the Add VM button of the tier for which you want to add a VM.
+ Click Virtual Machines tab of the tier to which you want to add a VM.
+
+
+
+
+
+ add-vm-vpc.png: adding a VM to a vpc.
+
+
The Add Instance page is displayed.
Follow the on-screen instruction to add an instance. For information on adding an
- instance, see Adding Instances section in the Installation Guide.
+ instance, see the Installation Guide.
diff --git a/docs/en-US/configure-acl.xml b/docs/en-US/configure-acl.xml
index 299196c5502..e7459e68dbf 100644
--- a/docs/en-US/configure-acl.xml
+++ b/docs/en-US/configure-acl.xml
@@ -37,31 +37,66 @@
All the VPCs that you have created for the account is listed in the page.
- Click the Settings icon.
- The following options are displayed.
+ Click the Configure button of the VPC, for which you want to configure load balancing
+ rules.
+ For each tier, the following options are displayed:
- IP Addresses
+ Internal LB
- Gateways
+ Public LB IP
- Site-to-Site VPN
+ Static NAT
- Network ACLs
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
- Select Network ACLs.
- The Network ACLs page is displayed.
+ Select Network ACL Lists.
+ The following default rules are displayed in the Network ACLs page: default_allow,
+ default_deny.
- Click Add Network ACLs.
+ Click Add ACL Lists, and specify the following:
+
+
+ ACL List Name: A name for the ACL list.
+
+
+ Description: A short description of the ACL list
+ that can be displayed to users.
+
+
+
+
+ Select the ACL list.
+
+
+ Select the ACL List Rules tab.
To add an ACL rule, fill in the following fields to specify what kind of network traffic
- is allowed in this tier.
+ is allowed in the VPC.
CIDR: The CIDR acts as the Source CIDR for the
@@ -74,7 +109,8 @@
Protocol: The networking protocol that sources use
to send traffic to the tier. The TCP and UDP protocols are typically used for data
exchange and end-user communications. The ICMP protocol is typically used to send error
- messages or network monitoring data.
+ messages or network monitoring data. All supports all the traffic. Other option is
+ Protocol Number.
Start Port, End
@@ -83,8 +119,10 @@
fields.
- Select Tier: Select the tier for which you want to
- add this ACL rule.
+ Protocol Number: The protocol number associated
+ with IPv4 or IPv6. For more information, see Protocol
+ Numbers.
ICMP Type, ICMP
@@ -92,48 +130,14 @@
sent.
- Traffic Type: Select the traffic type you want to
- apply.
-
-
- Egress: To add an egress rule, select Egress
- from the Traffic type drop-down box and click Add. This specifies what type of
- traffic is allowed to be sent out of VM instances in this tier. If no egress rules
- are specified, all traffic from the tier is allowed out at the VPC virtual router.
- Once egress rules are specified, only the traffic specified in egress rules and the
- responses to any traffic that has been allowed in through an ingress rule are
- allowed out. No egress rule is required for the VMs in a tier to communicate with
- each other.
-
-
- Ingress: To add an ingress rule, select Ingress
- from the Traffic type drop-down box and click Add. This specifies what network
- traffic is allowed into the VM instances in this tier. If no ingress rules are
- specified, then no traffic will be allowed in, except for responses to any traffic
- that has been allowed out through an egress rule.
-
-
-
- By default, all incoming and outgoing traffic to the guest networks is blocked. To
- open the ports, create a new network ACL.
-
+ Action: What action to be taken.
Click Add. The ACL rule is added.
- To view the list of ACL rules you have added, click the desired tier from the Network
- ACLs page, then select the Network ACL tab.
-
-
-
-
-
- network-acl.png: adding, editing, deleting an ACL rule.
-
-
You can edit the tags assigned to the ACL rules and delete the ACL rules you have
- created. Click the appropriate button in the Actions column.
+ created. Click the appropriate button in the Details tab.
diff --git a/docs/en-US/enable-disable-static-nat-vpc.xml b/docs/en-US/enable-disable-static-nat-vpc.xml
index 17f0c10540f..467a304915d 100644
--- a/docs/en-US/enable-disable-static-nat-vpc.xml
+++ b/docs/en-US/enable-disable-static-nat-vpc.xml
@@ -42,27 +42,42 @@
Click the Configure button of the VPC to which you want to deploy the VMs.
The VPC page is displayed where all the tiers you created are listed in a
diagram.
-
-
- Click the Settings icon.
- The following options are displayed.
+ For each tier, the following options are displayed.
- IP Addresses
+ Internal LB
- Gateways
+ Public LB IP
- Site-to-Site VPN
+ Static NAT
- Network ACLs
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
- Select IP Addresses.
+ In the Router node, select Public IP Addresses.
The IP Addresses page is displayed.
@@ -74,7 +89,7 @@
- enable-disable.png: button to enable Statid NAT.
+ enable-disable.png: button to enable Static NAT.
The button toggles between Enable and Disable, depending on whether
static NAT is currently enabled for the IP address.
diff --git a/docs/en-US/gsoc-tuna.xml b/docs/en-US/gsoc-tuna.xml
new file mode 100644
index 00000000000..68032a8d46d
--- /dev/null
+++ b/docs/en-US/gsoc-tuna.xml
@@ -0,0 +1,28 @@
+
+
+%BOOK_ENTITIES;
+]>
+
+
+
+
+ Nguyen's 2013 GSoC Proposal
+ This chapter describes Nguyen 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal.
+
diff --git a/docs/en-US/guest-ip-ranges.xml b/docs/en-US/guest-ip-ranges.xml
index b3ebd761394..c49dc6a76f8 100644
--- a/docs/en-US/guest-ip-ranges.xml
+++ b/docs/en-US/guest-ip-ranges.xml
@@ -28,5 +28,5 @@
their guest network and their clients.
In shared networks in Basic zone and Security Group-enabled Advanced networks, you will have
the flexibility to add multiple guest IP ranges from different subnets. You can add or remove
- one IP range at a time.
+ one IP range at a time. For more information, see .
diff --git a/docs/en-US/images/add-new-gateway-vpc.png b/docs/en-US/images/add-new-gateway-vpc.png
index f15b778e0f2..5145622a2f4 100644
Binary files a/docs/en-US/images/add-new-gateway-vpc.png and b/docs/en-US/images/add-new-gateway-vpc.png differ
diff --git a/docs/en-US/images/add-vm-vpc.png b/docs/en-US/images/add-vm-vpc.png
new file mode 100644
index 00000000000..b2821a69156
Binary files /dev/null and b/docs/en-US/images/add-vm-vpc.png differ
diff --git a/docs/en-US/images/del-tier.png b/docs/en-US/images/del-tier.png
new file mode 100644
index 00000000000..aa9846cfd9b
Binary files /dev/null and b/docs/en-US/images/del-tier.png differ
diff --git a/docs/en-US/images/vpc-lb.png b/docs/en-US/images/vpc-lb.png
new file mode 100644
index 00000000000..4269e8b9f9e
Binary files /dev/null and b/docs/en-US/images/vpc-lb.png differ
diff --git a/docs/en-US/ip-vlan-tenant.xml b/docs/en-US/ip-vlan-tenant.xml
new file mode 100644
index 00000000000..42124f0f446
--- /dev/null
+++ b/docs/en-US/ip-vlan-tenant.xml
@@ -0,0 +1,205 @@
+
+
+%BOOK_ENTITIES;
+]>
+
+
+ Dedicated Resources: Public IP Addresses and VLANs Per Account
+ &PRODUCT; provides you the ability to reserve a set of public IP addresses and VLANs
+ exclusively for an account. During zone creation, you can continue to define a set of VLANs and
+ multiple public IP ranges. This feature extends the functionality to enable you to dedicate a
+ fixed set of VLANs and guest IP addresses for a tenant.
+ This feature provides you the following capabilities:
+
+
+ Reserve a VLAN range and public IP address range from an Advanced zone and assign it to
+ a domain or account
+
+
+ Disassociate a VLAN and public IP address range from an domain or account
+
+
+ View the number of public IP addresses allocated to an account
+
+
+ Check whether the required range is available and is conforms to account limits.
+ The maximum IPs per account limit cannot be superseded.
+
+
+
+ Dedicating IP Address Ranges to an Account
+
+
+ Log in to the &PRODUCT; UI as administrator.
+
+
+ In the left navigation bar, click Infrastructure.
+
+
+ In Zones, click View All.
+
+
+ Choose the zone you want to work with.
+
+
+ Click the Physical Network tab.
+
+
+ In the Public node of the diagram, click Configure.
+
+
+ Click the IP Ranges tab.
+ You can either assign an existing IP range to an account, or create a new IP range and
+ assign to an account.
+
+
+ To assign an existing IP range to an account, perform the following:
+
+
+ Locate the IP range you want to work with.
+
+
+ Click Add Account
+
+
+
+
+ addAccount-icon.png: button to assign an IP range to an account.
+
+ button.
+ The Add Account dialog is displayed.
+
+
+ Specify the following:
+
+
+ Account: The account to which you want to
+ assign the IP address range.
+
+
+ Domain: The domain associated with the
+ account.
+
+
+ To create a new IP range and assign an account, perform the following:
+
+
+ Specify the following:
+
+
+ Gateway
+
+
+ Netmask
+
+
+ VLAN
+
+
+ Start IP
+
+
+ End IP
+
+
+ Account: Perform the following:
+
+
+ Click Account.
+ The Add Account page is displayed.
+
+
+ Specify the following:
+
+
+ Account: The account to which you want to
+ assign an IP address range.
+
+
+ Domain: The domain associated with the
+ account.
+
+
+
+
+ Click OK.
+
+
+
+
+
+
+ Click Add.
+
+
+
+
+
+
+
+
+ Dedicating VLAN Ranges to an Account
+
+
+ After the &PRODUCT; Management Server is installed, log in to the &PRODUCT; UI as
+ administrator.
+
+
+ In the left navigation bar, click Infrastructure.
+
+
+ In Zones, click View All.
+
+
+ Choose the zone you want to work with.
+
+
+ Click the Physical Network tab.
+
+
+ In the Guest node of the diagram, click Configure.
+
+
+ Select the Dedicated VLAN Ranges tab.
+
+
+ Click Dedicate VLAN Range.
+ The Dedicate VLAN Range dialog is displayed.
+
+
+ Specify the following:
+
+
+ VLAN Range: The
+ VLAN range that you want to assign to an account.
+
+
+ Account: The
+ account to which you want to assign the selected VLAN range.
+
+
+ Domain: The
+ domain associated with the account.
+
+
+
+
+
+
diff --git a/docs/en-US/multiple-ip-range.xml b/docs/en-US/multiple-ip-range.xml
new file mode 100644
index 00000000000..42e0c2a9555
--- /dev/null
+++ b/docs/en-US/multiple-ip-range.xml
@@ -0,0 +1,42 @@
+
+
+%BOOK_ENTITIES;
+]>
+
+
+ About Multiple IP Ranges
+
+ The feature can only be implemented on IPv4 addresses.
+
+ &PRODUCT; provides you with the flexibility to add guest IP ranges from different subnets in
+ Basic zones and security groups-enabled Advanced zones. For security groups-enabled Advanced
+ zones, it implies multiple subnets can be added to the same VLAN. With the addition of this
+ feature, you will be able to add IP address ranges from the same subnet or from a different one
+ when IP address are exhausted. This would in turn allows you to employ higher number of subnets
+ and thus reduce the address management overhead. To support this feature, the capability of
+ createVlanIpRange API is extended to add IP ranges also from a different
+ subnet.
+ Ensure that you manually configure the gateway of the new subnet before adding the IP range.
+ Note that &PRODUCT; supports only one gateway for a subnet; overlapping subnets are not
+ currently supported.
+ Use the deleteVlanRange API to delete IP ranges. This operation fails if an IP
+ from the remove range is in use. If the remove range contains the IP address on which the DHCP
+ server is running, &PRODUCT; acquires a new IP from the same subnet. If no IP is available in
+ the subnet, the remove operation fails.
+ This feature is supported on KVM, xenServer, and VMware hypervisors.
+
diff --git a/docs/en-US/networks.xml b/docs/en-US/networks.xml
index 8a7405a63ac..b557088273f 100644
--- a/docs/en-US/networks.xml
+++ b/docs/en-US/networks.xml
@@ -33,6 +33,7 @@
+
diff --git a/docs/en-US/pvlan.xml b/docs/en-US/pvlan.xml
new file mode 100644
index 00000000000..96c1a78a85d
--- /dev/null
+++ b/docs/en-US/pvlan.xml
@@ -0,0 +1,57 @@
+
+
+%BOOK_ENTITIES;
+]>
+
+
+
+ Isolation in Advanced Zone Using Private VLAN
+
+
+ About Private VLAN
+ In an Ethernet switch, a VLAN is a broadcast domain in which hosts can establish direct
+ communication with each another at Layer 2. Private VLAN is designed as an extension of VLAN
+ standard to add further segmentation of the logical broadcast domain. A regular VLAN is a
+ single broadcast domain, whereas a private VLAN partitions a larger VLAN broadcast domain into
+ smaller sub-domains. A sub-domain is represented by a pair of VLANs: a Primary VLAN and a
+ Secondary VLAN. The original VLAN that is being divided into smaller groups is called
+ Primary, That implies all VLAN pairs in a private VLAN share the same Primary VLAN. All the
+ secondary VLANs exist only inside the Primary. Each Secondary VLAN has a specific VLAN ID
+ associated to it, which differentiates one sub-domain from another.
+ For further reading:
+
+
+ Understanding Private VLANs
+
+
+ Cisco Systems' Private VLANs: Scalable
+ Security in a Multi-Client Environment
+
+
+ Private VLAN (PVLAN) on vNetwork Distributed Switch
+ - Concept Overview (1010691)
+
+
+
+
+ Prerequisites
+ Ensure that you configure private VLAN on your physical switches out-of-band.
+
+
diff --git a/docs/en-US/release-ip-for-vpc.xml b/docs/en-US/release-ip-for-vpc.xml
index 466ec663a17..f827b671c03 100644
--- a/docs/en-US/release-ip-for-vpc.xml
+++ b/docs/en-US/release-ip-for-vpc.xml
@@ -40,27 +40,42 @@
Click the Configure button of the VPC whose IP you want to release.
The VPC page is displayed where all the tiers you created are listed in a
diagram.
-
-
- Click the Settings icon.
The following options are displayed.
- IP Addresses
+ Internal LB
- Gateways
+ Public LB IP
- Site-to-Site VPN
+ Static NAT
- Network ACLs
+ Virtual Machines
+
+
+ CIDR
+
+
+ The following router information is displayed:
+
+
+ Private Gateways
+
+
+ Public IP Addresses
+
+
+ Site-to-Site VPNs
+
+
+ Network ACL Lists
- Select IP Addresses.
+ Select Public IP Addresses.
The IP Addresses page is displayed.
diff --git a/docs/en-US/remove-tier.xml b/docs/en-US/remove-tier.xml
index b5996eb2de3..701645cc4ed 100644
--- a/docs/en-US/remove-tier.xml
+++ b/docs/en-US/remove-tier.xml
@@ -40,16 +40,18 @@
The Configure VPC page is displayed. Locate the tier you want to work with.
- Click the Remove VPC button:
-
-
-
-
-
- remove-tier.png: removing a tier from a vpc.
-
-
- Wait for some time for the tier to be removed.
+ Select the tier you want to remove.
+
+
+ In the Network Details tab, click the Delete Network button.
+
+
+
+
+ del-tier.png: button to remove a tier
+
+
+ Click Yes to confirm. Wait for some time for the tier to be removed.
diff --git a/docs/en-US/remove-vpc.xml b/docs/en-US/remove-vpc.xml
index c5eff850fd3..b373f1a52c3 100644
--- a/docs/en-US/remove-vpc.xml
+++ b/docs/en-US/remove-vpc.xml
@@ -38,14 +38,15 @@
Select the VPC you want to work with.
- To remove, click the Remove VPC button
+ In the Details tab, click the Remove VPC button
remove-vpc.png: button to remove a VPC
-
+
+ You can remove the VPC by also using the remove button in the Quick View.
You can edit the name and description of a VPC. To do that, select the VPC, then click
the Edit button.
diff --git a/docs/en-US/vpc.xml b/docs/en-US/vpc.xml
index 0665d372b4e..7c94f0d6dd1 100644
--- a/docs/en-US/vpc.xml
+++ b/docs/en-US/vpc.xml
@@ -151,8 +151,8 @@
cannot be used for StaticNAT or port forwarding.
- The instances only have a private IP address that you provision. To communicate with the
- Internet, enable NAT to an instance that you launch in your VPC.
+ The instances can only have a private IP address that you provision. To communicate with
+ the Internet, enable NAT to an instance that you launch in your VPC.
Only new networks can be added to a VPC. The maximum number of networks per VPC is
diff --git a/docs/publican-gsoc-2013.cfg b/docs/publican-gsoc-2013.cfg
new file mode 100644
index 00000000000..35dc517be12
--- /dev/null
+++ b/docs/publican-gsoc-2013.cfg
@@ -0,0 +1,27 @@
+# Publican configuration file for CloudStack Complete Documentation Set
+# Contains all technical docs except release notes
+# Config::Simple 4.58
+# Tue May 29 00:57:27 2012
+#
+# 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.
+
+xml_lang: en-US
+type: Book
+docname: CloudStack_GSoC_Guide
+brand: cloudstack
+chunk_first: 1
+chunk_section_depth: 1
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
index 280e02e2a32..cb467093955 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
@@ -21,6 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
import java.util.Map;
import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
public interface DataStoreLifeCycle {
@@ -28,8 +29,8 @@ public interface DataStoreLifeCycle {
public boolean attachCluster(DataStore store, ClusterScope scope);
public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo);
- boolean attachZone(DataStore dataStore, ZoneScope scope);
-
+ boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType);
+
public boolean dettach();
public boolean unmanaged();
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
index 4d845252f57..d436762c25a 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -22,6 +22,7 @@ import java.util.Map;
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.utils.db.GenericDao;
/**
@@ -109,4 +110,6 @@ public interface PrimaryDataStoreDao extends GenericDao {
Long clusterId, String[] tags);
List findZoneWideStoragePoolsByTags(long dcId, String[] tags);
+
+ List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType);
}
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
index 7fcddf1940f..d461d58ddfc 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -32,6 +32,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
import org.springframework.stereotype.Component;
import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.StoragePoolStatus;
@@ -427,4 +428,14 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase
return listBy(sc);
}
+
+ @Override
+ public List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType) {
+ SearchCriteriaService sc = SearchCriteria2.create(StoragePoolVO.class);
+ sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dataCenterId);
+ sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up);
+ sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE);
+ sc.addAnd(sc.getEntity().getHypervisor(), Op.EQ, hypervisorType);
+ return sc.list();
+ }
}
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
index 55b2314f0fd..0262f65af0a 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
@@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
@@ -102,6 +103,10 @@ public class StoragePoolVO implements StoragePool{
@Enumerated(value = EnumType.STRING)
private ScopeType scope;
+ @Column(name = "hypervisor")
+ @Enumerated(value = EnumType.STRING)
+ private HypervisorType hypervisor;
+
public long getId() {
return id;
}
@@ -276,6 +281,14 @@ public class StoragePoolVO implements StoragePool{
return this.scope;
}
+ public HypervisorType getHypervisor() {
+ return hypervisor;
+ }
+
+ public void setHypervisor(HypervisorType hypervisor) {
+ this.hypervisor = hypervisor;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof StoragePoolVO) || obj == null) {
diff --git a/engine/orchestration/src/org/apache/cloudstack/platform/orchestration/CloudOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/platform/orchestration/CloudOrchestrator.java
index 963e4d7d967..ca299ea45bc 100755
--- a/engine/orchestration/src/org/apache/cloudstack/platform/orchestration/CloudOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/platform/orchestration/CloudOrchestrator.java
@@ -89,10 +89,9 @@ public class CloudOrchestrator implements OrchestrationService {
public CloudOrchestrator() {
}
-
+
public VirtualMachineEntity createFromScratch(String uuid, String iso, String os, String hypervisor, String hostName, int cpu, int speed, long memory, List networks, List computeTags,
Map details, String owner) {
- // TODO Auto-generated method stub
return null;
}
diff --git a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java
index 01a560a129a..18115a5e499 100755
--- a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java
+++ b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java
@@ -156,7 +156,7 @@ public class AlertDaoImpl extends GenericDaoBase implements Alert
public List listOlderAlerts(Date oldTime) {
if (oldTime == null) return null;
SearchCriteria sc = createSearchCriteria();
- sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime);
+ sc.addAnd("createdDate", SearchCriteria.Op.LT, oldTime);
sc.addAnd("archived", SearchCriteria.Op.EQ, false);
return listIncludingRemovedBy(sc, null);
}
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
index 3ce0798a8a2..673888bc2ab 100644
--- a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
@@ -34,4 +34,5 @@ public interface ClusterDao extends GenericDao {
Map> getPodClusterIdMap(List clusterIds);
List listDisabledClusters(long zoneId, Long podId);
List listClustersWithDisabledPods(long zoneId);
+ List listClustersByDcId(long zoneId);
}
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
index 86dc65e05bd..ba2686a4004 100644
--- a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
@@ -52,6 +52,7 @@ public class ClusterDaoImpl extends GenericDaoBase implements C
protected final SearchBuilder AvailHyperSearch;
protected final SearchBuilder ZoneSearch;
protected final SearchBuilder ZoneHyTypeSearch;
+ protected final SearchBuilder ZoneClusterSearch;
private static final String GET_POD_CLUSTER_MAP_PREFIX = "SELECT pod_id, id FROM cloud.cluster WHERE cluster.id IN( ";
private static final String GET_POD_CLUSTER_MAP_SUFFIX = " )";
@@ -85,12 +86,16 @@ public class ClusterDaoImpl extends GenericDaoBase implements C
AvailHyperSearch.and("zoneId", AvailHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
AvailHyperSearch.select(null, Func.DISTINCT, AvailHyperSearch.entity().getHypervisorType());
AvailHyperSearch.done();
+
+ ZoneClusterSearch = createSearchBuilder();
+ ZoneClusterSearch.and("dataCenterId", ZoneClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ ZoneClusterSearch.done();
}
@Override
public List listByZoneId(long zoneId) {
SearchCriteria sc = ZoneSearch.create();
- sc.setParameters("dataCenterId", zoneId);
+ sc.setParameters("dataCenterId", zoneId);
return listBy(sc);
}
@@ -223,6 +228,13 @@ public class ClusterDaoImpl extends GenericDaoBase implements C
return customSearch(sc, null);
}
+ @Override
+ public List listClustersByDcId(long zoneId) {
+ SearchCriteria sc = ZoneClusterSearch.create();
+ sc.setParameters("dataCenterId", zoneId);
+ return listBy(sc);
+ }
+
@Override
public boolean remove(Long id) {
Transaction txn = Transaction.currentTxn();
diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java
index 9460a73dc57..c84aa60897c 100644
--- a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java
+++ b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java
@@ -288,5 +288,5 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom
return parentDomains;
}
-
+
}
diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java
index 98bdcb470e1..8ceb8f23132 100755
--- a/engine/schema/src/com/cloud/host/dao/HostDao.java
+++ b/engine/schema/src/com/cloud/host/dao/HostDao.java
@@ -80,4 +80,10 @@ public interface HostDao extends GenericDao, StateDao listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag);
+
+ List findByPodId(Long podId);
+
+ List findByClusterId(Long clusterId);
+
+ List listByDataCenterId(long id);
}
diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
index 07a42322ce3..810b973e296 100755
--- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
+++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
@@ -37,6 +37,7 @@ import com.cloud.cluster.agentlb.HostTransferMapVO;
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
import com.cloud.dc.ClusterVO;
+import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.ClusterDaoImpl;
import com.cloud.host.Host;
@@ -86,6 +87,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao
protected SearchBuilder GuidSearch;
protected SearchBuilder DcSearch;
protected SearchBuilder PodSearch;
+ protected SearchBuilder ClusterSearch;
protected SearchBuilder TypeSearch;
protected SearchBuilder StatusSearch;
protected SearchBuilder ResourceStateSearch;
@@ -201,6 +203,9 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao
DcSearch = createSearchBuilder();
DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ DcSearch.and("type", DcSearch.entity().getType(), Op.EQ);
+ DcSearch.and("status", DcSearch.entity().getStatus(), Op.EQ);
+ DcSearch.and("resourceState", DcSearch.entity().getResourceState(), Op.EQ);
DcSearch.done();
ClusterStatusSearch = createSearchBuilder();
@@ -215,9 +220,13 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao
TypeNameZoneSearch.done();
PodSearch = createSearchBuilder();
- PodSearch.and("pod", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+ PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
PodSearch.done();
+ ClusterSearch = createSearchBuilder();
+ ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+ ClusterSearch.done();
+
TypeSearch = createSearchBuilder();
TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
TypeSearch.done();
@@ -373,7 +382,17 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao
List hosts = listBy(sc);
return hosts.size();
}
-
+
+ @Override
+ public List listByDataCenterId(long id) {
+ SearchCriteria sc = DcSearch.create();
+ sc.setParameters("dcId", id);
+ sc.setParameters("status", Status.Up);
+ sc.setParameters("type", Host.Type.Routing);
+ sc.setParameters("resourceState", ResourceState.Enabled);
+
+ return listBy(sc);
+ }
@Override
public HostVO findByGuid(String guid) {
@@ -906,6 +925,20 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao
return findOneBy(sc);
}
+ @Override
+ public List findByPodId(Long podId) {
+ SearchCriteria sc = PodSearch.create();
+ sc.setParameters("podId", podId);
+ return listBy(sc);
+ }
+
+ @Override
+ public List findByClusterId(Long clusterId) {
+ SearchCriteria sc = ClusterSearch.create();
+ sc.setParameters("clusterId", clusterId);
+ return listBy(sc);
+ }
+
@Override
public List findHypervisorHostInCluster(long clusterId) {
SearchCriteria sc = TypeClusterStatusSearch.create();
diff --git a/engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java
index bad32536955..b035c10f13c 100755
--- a/engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java
+++ b/engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java
@@ -18,9 +18,6 @@ package com.cloud.upgrade;
import javax.ejb.Local;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
-
import com.cloud.upgrade.dao.DbUpgrade;
import com.cloud.upgrade.dao.Upgrade217to218;
import com.cloud.upgrade.dao.Upgrade218to224DomainVlans;
@@ -43,7 +40,6 @@ import com.cloud.upgrade.dao.Upgrade30to301;
import com.cloud.upgrade.dao.Upgrade40to41;
import com.cloud.upgrade.dao.UpgradeSnapshot217to224;
import com.cloud.upgrade.dao.UpgradeSnapshot223to224;
-import com.cloud.upgrade.dao.VersionDaoImpl;
import com.cloud.utils.component.SystemIntegrityChecker;
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
index 16ab05cea06..d8f90adfe39 100644
--- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
+++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
@@ -18,6 +18,7 @@
package com.cloud.upgrade.dao;
import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import org.apache.log4j.Logger;
@@ -64,6 +65,7 @@ public class Upgrade410to420 implements DbUpgrade {
@Override
public void performDataMigration(Connection conn) {
upgradeVmwareLabels(conn);
+ persistLegacyZones(conn);
createPlaceHolderNics(conn);
updateRemoteAccessVpn(conn);
updateSystemVmTemplates(conn);
@@ -77,6 +79,7 @@ public class Upgrade410to420 implements DbUpgrade {
updateNetworkACLs(conn);
addHostDetailsIndex(conn);
updateNetworksForPrivateGateways(conn);
+ correctExternalNetworkDevicesSetup(conn);
removeFirewallServiceFromSharedNetworkOfferingWithSGService(conn);
fix22xKVMSnapshots(conn);
addIndexForAlert(conn);
@@ -110,16 +113,215 @@ public class Upgrade410to420 implements DbUpgrade {
}
private void updateSystemVmTemplates(Connection conn) {
- PreparedStatement sql = null;
+
+ PreparedStatement pstmt = null;
+ ResultSet rs = null;
+ boolean xenserver = false;
+ boolean kvm = false;
+ boolean VMware = false;
+ boolean Hyperv = false;
+ boolean LXC = false;
+ s_logger.debug("Updating System Vm template IDs");
+ try{
+ //Get all hypervisors in use
+ try {
+ pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null");
+ rs = pstmt.executeQuery();
+ while(rs.next()){
+ if("XenServer".equals(rs.getString(1))){
+ xenserver = true;
+ } else if("KVM".equals(rs.getString(1))){
+ kvm = true;
+ } else if("VMware".equals(rs.getString(1))){
+ VMware = true;
+ } else if("Hyperv".equals(rs.getString(1))) {
+ Hyperv = true;
+ } else if("LXC".equals(rs.getString(1))) {
+ LXC = true;
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while listing hypervisors in use", e);
+ }
+
+ s_logger.debug("Updating XenSever System Vms");
+ //XenServer
+ try {
+ //Get 4.2.0 xenserer system Vm template Id
+ pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name like 'systemvm-xenserver-4.2' and removed is null order by id desc limit 1");
+ rs = pstmt.executeQuery();
+ if(rs.next()){
+ long templateId = rs.getLong(1);
+ rs.close();
+ pstmt.close();
+ // change template type to SYSTEM
+ pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ // update templete ID of system Vms
+ pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'XenServer'");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ } else {
+ if (xenserver){
+ throw new CloudRuntimeException("4.2.0 XenServer SystemVm template not found. Cannot upgrade system Vms");
+ } else {
+ s_logger.warn("4.2.0 XenServer SystemVm template not found. XenServer hypervisor is not used, so not failing upgrade");
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while updating XenServer systemVm template", e);
+ }
+
+ //KVM
+ s_logger.debug("Updating KVM System Vms");
+ try {
+ //Get 4.2.0 KVM system Vm template Id
+ pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-kvm-4.2' and removed is null order by id desc limit 1");
+ rs = pstmt.executeQuery();
+ if(rs.next()){
+ long templateId = rs.getLong(1);
+ rs.close();
+ pstmt.close();
+ // change template type to SYSTEM
+ pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ // update templete ID of system Vms
+ pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'KVM'");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ } else {
+ if (kvm){
+ throw new CloudRuntimeException("4.2.0 KVM SystemVm template not found. Cannot upgrade system Vms");
+ } else {
+ s_logger.warn("4.2.0 KVM SystemVm template not found. KVM hypervisor is not used, so not failing upgrade");
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while updating KVM systemVm template", e);
+ }
+
+ //VMware
+ s_logger.debug("Updating VMware System Vms");
+ try {
+ //Get 4.2.0 VMware system Vm template Id
+ pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-vmware-4.2' and removed is null order by id desc limit 1");
+ rs = pstmt.executeQuery();
+ if(rs.next()){
+ long templateId = rs.getLong(1);
+ rs.close();
+ pstmt.close();
+ // change template type to SYSTEM
+ pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ // update templete ID of system Vms
+ pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'VMware'");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ } else {
+ if (VMware){
+ throw new CloudRuntimeException("4.2.0 VMware SystemVm template not found. Cannot upgrade system Vms");
+ } else {
+ s_logger.warn("4.2.0 VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade");
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while updating VMware systemVm template", e);
+ }
+
+ //Hyperv
+ s_logger.debug("Updating Hyperv System Vms");
+ try {
+ //Get 4.2.0 Hyperv system Vm template Id
+ pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-hyperv-4.2' and removed is null order by id desc limit 1");
+ rs = pstmt.executeQuery();
+ if(rs.next()){
+ long templateId = rs.getLong(1);
+ rs.close();
+ pstmt.close();
+ // change template type to SYSTEM
+ pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ // update templete ID of system Vms
+ pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'Hyperv'");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ } else {
+ if (Hyperv){
+ throw new CloudRuntimeException("4.2.0 HyperV SystemVm template not found. Cannot upgrade system Vms");
+ } else {
+ s_logger.warn("4.2.0 Hyperv SystemVm template not found. Hyperv hypervisor is not used, so not failing upgrade");
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while updating Hyperv systemVm template", e);
+ }
+
+ //LXC
+ s_logger.debug("Updating LXC System Vms");
+ try {
+ //Get 4.2.0 LXC system Vm template Id
+ pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-lxc-4.2' and removed is null order by id desc limit 1");
+ rs = pstmt.executeQuery();
+ if(rs.next()){
+ long templateId = rs.getLong(1);
+ rs.close();
+ pstmt.close();
+ // change template type to SYSTEM
+ pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ // update templete ID of system Vms
+ pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'LXC'");
+ pstmt.setLong(1, templateId);
+ pstmt.executeUpdate();
+ pstmt.close();
+ } else {
+ if (LXC){
+ throw new CloudRuntimeException("4.2.0 LXC SystemVm template not found. Cannot upgrade system Vms");
+ } else {
+ s_logger.warn("4.2.0 LXC SystemVm template not found. LXC hypervisor is not used, so not failing upgrade");
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Error while updating LXC systemVm template", e);
+ }
+ s_logger.debug("Updating System Vm Template IDs Complete");
+ }
+ finally {
+ try {
+ if (rs != null) {
+ rs.close();
+ }
+
+ if (pstmt != null) {
+ pstmt.close();
+ }
+ } catch (SQLException e) {
+ }
+ }
+ pstmt = null;
try {
- sql = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'");
- sql.executeUpdate();
+ pstmt = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'");
+ pstmt.executeUpdate();
} catch (SQLException e) {
throw new CloudRuntimeException("Failed to upgrade vm template data store uuid: " + e.toString());
} finally {
- if (sql != null) {
+ if (pstmt != null) {
try {
- sql.close();
+ pstmt.close();
} catch (SQLException e) {
}
}
@@ -277,6 +479,180 @@ public class Upgrade410to420 implements DbUpgrade {
}
}
+ private void persistLegacyZones(Connection conn) {
+ List listOfLegacyZones = new ArrayList();
+ PreparedStatement pstmt = null;
+ PreparedStatement clustersQuery = null;
+ PreparedStatement clusterDetailsQuery = null;
+ ResultSet rs = null;
+ ResultSet clusters = null;
+ ResultSet clusterDetails = null;
+ ResultSet dcInfo = null;
+ Long vmwareDcId = 1L;
+ Long zoneId;
+ Long clusterId;
+ String clusterHypervisorType;
+ boolean legacyZone;
+ boolean ignoreZone;
+ Long count;
+ String dcOfPreviousCluster = null;
+ String dcOfCurrentCluster = null;
+ String[] tokens;
+ String url;
+ String user = "";
+ String password = "";
+ String vc = "";
+ String dcName = "";
+ String guid;
+ String key;
+ String value;
+
+ try {
+ clustersQuery = conn.prepareStatement("select id, hypervisor_type from `cloud`.`cluster` where removed is NULL");
+ pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where removed is NULL");
+ rs = pstmt.executeQuery();
+
+ while (rs.next()) {
+ zoneId = rs.getLong("id");
+ legacyZone = false;
+ ignoreZone = true;
+ count = 0L;
+ // Legacy zone term is meant only for VMware
+ // Legacy zone is a zone with atleast 2 clusters & with multiple DCs or VCs
+ clusters = clustersQuery.executeQuery();
+ if (!clusters.next()) {
+ continue; // Ignore the zone without any clusters
+ } else {
+ dcOfPreviousCluster = null;
+ dcOfCurrentCluster = null;
+ do {
+ clusterHypervisorType = clusters.getString("hypervisor_type");
+ clusterId = clusters.getLong("id");
+ if (clusterHypervisorType.equalsIgnoreCase("VMware")) {
+ ignoreZone = false;
+ clusterDetailsQuery = conn.prepareStatement("select value from `cloud`.`cluster_details` where name='url' and cluster_id=?");
+ clusterDetailsQuery.setLong(1, clusterId);
+ clusterDetails = clusterDetailsQuery.executeQuery();
+ clusterDetails.next();
+ url = clusterDetails.getString("value");
+ tokens = url.split("/"); // url format - http://vcenter/dc/cluster
+ vc = tokens[2];
+ dcName = tokens[3];
+ if (count > 0) {
+ dcOfPreviousCluster = dcOfCurrentCluster;
+ dcOfCurrentCluster = dcName + "@" + vc;
+ if (!dcOfPreviousCluster.equals(dcOfCurrentCluster)) {
+ legacyZone = true;
+ s_logger.debug("Marking the zone " + zoneId + " as legacy zone.");
+ }
+ }
+ } else {
+ s_logger.debug("Ignoring zone " + zoneId + " with hypervisor type " + clusterHypervisorType);
+ break;
+ }
+ count++;
+ } while (clusters.next());
+ if (ignoreZone) {
+ continue; // Ignore the zone with hypervisors other than VMware
+ }
+ }
+ if (legacyZone) {
+ listOfLegacyZones.add(zoneId);
+ } else {
+ assert(clusterDetails != null) : "Couldn't retrieve details of cluster!";
+ s_logger.debug("Discovered non-legacy zone " + zoneId + ". Processing the zone to associate with VMware datacenter.");
+
+ clusterDetailsQuery = conn.prepareStatement("select name, value from `cloud`.`cluster_details` where cluster_id=?");
+ clusterDetailsQuery.setLong(1, clusterId);
+ clusterDetails = clusterDetailsQuery.executeQuery();
+ while (clusterDetails.next()) {
+ key = clusterDetails.getString(1);
+ value = clusterDetails.getString(2);
+ if (key.equalsIgnoreCase("username")) {
+ user = value;
+ } else if (key.equalsIgnoreCase("password")) {
+ password = value;
+ }
+ }
+ guid = dcName + "@" + vc;
+
+ pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center` (uuid, name, guid, vcenter_host, username, password) values(?, ?, ?, ?, ?, ?)");
+ pstmt.setString(1, UUID.randomUUID().toString());
+ pstmt.setString(2, dcName);
+ pstmt.setString(3, guid);
+ pstmt.setString(4, vc);
+ pstmt.setString(5, user);
+ pstmt.setString(6, password);
+ pstmt.executeUpdate();
+
+ pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`vmware_data_center` where guid=?");
+ pstmt.setString(1, guid);
+ dcInfo = pstmt.executeQuery();
+ if(dcInfo.next()) {
+ vmwareDcId = dcInfo.getLong("id");
+ }
+
+ pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center_zone_map` (zone_id, vmware_data_center_id) values(?, ?)");
+ pstmt.setLong(1, zoneId);
+ pstmt.setLong(2, vmwareDcId);
+ pstmt.executeUpdate();
+ }
+ }
+ updateLegacyZones(conn, listOfLegacyZones);
+ } catch (SQLException e) {
+ String msg = "Unable to discover legacy zones." + e.getMessage();
+ s_logger.error(msg);
+ throw new CloudRuntimeException(msg, e);
+ } finally {
+ try {
+ if (rs != null) {
+ rs.close();
+ }
+ if (pstmt != null) {
+ pstmt.close();
+ }
+ if (dcInfo != null) {
+ dcInfo.close();
+ }
+ if (clusters != null) {
+ clusters.close();
+ }
+ if (clusterDetails != null) {
+ clusterDetails.close();
+ }
+ if (clustersQuery != null) {
+ clustersQuery.close();
+ }
+ if (clusterDetailsQuery != null) {
+ clusterDetailsQuery.close();
+ }
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ private void updateLegacyZones(Connection conn, List zones) {
+ PreparedStatement legacyZonesQuery = null;
+ //Insert legacy zones into table for legacy zones.
+ try {
+ legacyZonesQuery = conn.prepareStatement("INSERT INTO `cloud`.`legacy_zones` (zone_id) VALUES (?)");
+ for(Long zoneId : zones) {
+ legacyZonesQuery.setLong(1, zoneId);
+ legacyZonesQuery.executeUpdate();
+ s_logger.debug("Inserted zone " + zoneId + " into cloud.legacyzones table");
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable add zones to cloud.legacyzones table.", e);
+ } finally {
+ try {
+ if (legacyZonesQuery != null) {
+ legacyZonesQuery.close();
+ }
+ } catch (SQLException e) {
+ }
+ }
+ }
+
private void createPlaceHolderNics(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
@@ -849,4 +1225,363 @@ public class Upgrade410to420 implements DbUpgrade {
}
}
}
+
+ // Corrects upgrade for deployment with F5 and SRX devices (pre 3.0) to network offering &
+ // network service provider paradigm
+ private void correctExternalNetworkDevicesSetup(Connection conn) {
+ PreparedStatement zoneSearchStmt = null, pNetworkStmt = null, f5DevicesStmt = null, srxDevicesStmt = null;
+ ResultSet zoneResults = null, pNetworksResults = null, f5DevicesResult = null, srxDevicesResult = null;
+
+ try {
+ zoneSearchStmt = conn.prepareStatement("SELECT id, networktype FROM `cloud`.`data_center`");
+ zoneResults = zoneSearchStmt.executeQuery();
+ while (zoneResults.next()) {
+ long zoneId = zoneResults.getLong(1);
+ String networkType = zoneResults.getString(2);
+
+ if (!com.cloud.dc.DataCenter.NetworkType.Advanced.toString().equalsIgnoreCase(networkType)) {
+ continue;
+ }
+
+ pNetworkStmt = conn.prepareStatement("SELECT id FROM `cloud`.`physical_network` where data_center_id=?");
+ pNetworkStmt.setLong(1, zoneId);
+ pNetworksResults = pNetworkStmt.executeQuery();
+ while (pNetworksResults.next()) {
+ long physicalNetworkId = pNetworksResults.getLong(1);
+ PreparedStatement fetchF5NspStmt = conn.prepareStatement("SELECT id from `cloud`.`physical_network_service_providers` where physical_network_id=" + physicalNetworkId
+ + " and provider_name = 'F5BigIp'");
+ ResultSet rsF5NSP = fetchF5NspStmt.executeQuery();
+ boolean hasF5Nsp = rsF5NSP.next();
+ fetchF5NspStmt.close();
+
+ // if there is no 'F5BigIP' physical network service provider added into physical network then
+ // add 'F5BigIP' as network service provider and add the entry in 'external_load_balancer_devices'
+ if (!hasF5Nsp) {
+ f5DevicesStmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalLoadBalancer' AND removed IS NULL");
+ f5DevicesStmt.setLong(1, zoneId);
+ f5DevicesResult = f5DevicesStmt.executeQuery();
+ // add F5BigIP provider and provider instance to physical network if there are any external load
+ // balancers added in the zone
+ while (f5DevicesResult.next()) {
+ long f5HostId = f5DevicesResult.getLong(1);;
+ addF5ServiceProvider(conn, physicalNetworkId, zoneId);
+ addF5LoadBalancer(conn, f5HostId, physicalNetworkId);
+ }
+ }
+
+ PreparedStatement fetchSRXNspStmt = conn.prepareStatement("SELECT id from `cloud`.`physical_network_service_providers` where physical_network_id=" + physicalNetworkId
+ + " and provider_name = 'JuniperSRX'");
+ ResultSet rsSRXNSP = fetchSRXNspStmt.executeQuery();
+ boolean hasSrxNsp = rsSRXNSP.next();
+ fetchSRXNspStmt.close();
+
+ // if there is no 'JuniperSRX' physical network service provider added into physical network then
+ // add 'JuniperSRX' as network service provider and add the entry in 'external_firewall_devices'
+ if (!hasSrxNsp) {
+ srxDevicesStmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalFirewall' AND removed IS NULL");
+ srxDevicesStmt.setLong(1, zoneId);
+ srxDevicesResult = srxDevicesStmt.executeQuery();
+ // add JuniperSRX provider and provider instance to physical network if there are any external
+ // firewall instances added in to the zone
+ while (srxDevicesResult.next()) {
+ long srxHostId = srxDevicesResult.getLong(1);
+ // add SRX provider and provider instance to physical network
+ addSrxServiceProvider(conn, physicalNetworkId, zoneId);
+ addSrxFirewall(conn, srxHostId, physicalNetworkId);
+ }
+ }
+ }
+ }
+
+ // not the network service provider has been provisioned in to physical network, mark all guest network
+ // to be using network offering 'Isolated with external providers'
+ fixZoneUsingExternalDevices(conn);
+
+ if (zoneResults != null) {
+ try {
+ zoneResults.close();
+ } catch (SQLException e) {
+ }
+ }
+
+ if (zoneSearchStmt != null) {
+ try {
+ zoneSearchStmt.close();
+ } catch (SQLException e) {
+ }
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Exception while adding PhysicalNetworks", e);
+ } finally {
+
+ }
+ }
+
+ private void addF5LoadBalancer(Connection conn, long hostId, long physicalNetworkId){
+ PreparedStatement pstmtUpdate = null;
+ try{
+ s_logger.debug("Adding F5 Big IP load balancer with host id " + hostId + " in to physical network" + physicalNetworkId);
+ String insertF5 = "INSERT INTO `cloud`.`external_load_balancer_devices` (physical_network_id, host_id, provider_name, " +
+ "device_name, capacity, is_dedicated, device_state, allocation_state, is_inline, is_managed, uuid) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ pstmtUpdate = conn.prepareStatement(insertF5);
+ pstmtUpdate.setLong(1, physicalNetworkId);
+ pstmtUpdate.setLong(2, hostId);
+ pstmtUpdate.setString(3, "F5BigIp");
+ pstmtUpdate.setString(4, "F5BigIpLoadBalancer");
+ pstmtUpdate.setLong(5, 0);
+ pstmtUpdate.setBoolean(6, false);
+ pstmtUpdate.setString(7, "Enabled");
+ pstmtUpdate.setString(8, "Shared");
+ pstmtUpdate.setBoolean(9, false);
+ pstmtUpdate.setBoolean(10, false);
+ pstmtUpdate.setString(11, UUID.randomUUID().toString());
+ pstmtUpdate.executeUpdate();
+ }catch (SQLException e) {
+ throw new CloudRuntimeException("Exception while adding F5 load balancer device" , e);
+ } finally {
+ if (pstmtUpdate != null) {
+ try {
+ pstmtUpdate.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ private void addSrxFirewall(Connection conn, long hostId, long physicalNetworkId){
+ PreparedStatement pstmtUpdate = null;
+ try{
+ s_logger.debug("Adding SRX firewall device with host id " + hostId + " in to physical network" + physicalNetworkId);
+ String insertSrx = "INSERT INTO `cloud`.`external_firewall_devices` (physical_network_id, host_id, provider_name, " +
+ "device_name, capacity, is_dedicated, device_state, allocation_state, uuid) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ pstmtUpdate = conn.prepareStatement(insertSrx);
+ pstmtUpdate.setLong(1, physicalNetworkId);
+ pstmtUpdate.setLong(2, hostId);
+ pstmtUpdate.setString(3, "JuniperSRX");
+ pstmtUpdate.setString(4, "JuniperSRXFirewall");
+ pstmtUpdate.setLong(5, 0);
+ pstmtUpdate.setBoolean(6, false);
+ pstmtUpdate.setString(7, "Enabled");
+ pstmtUpdate.setString(8, "Shared");
+ pstmtUpdate.setString(9, UUID.randomUUID().toString());
+ pstmtUpdate.executeUpdate();
+ }catch (SQLException e) {
+ throw new CloudRuntimeException("Exception while adding SRX firewall device ", e);
+ } finally {
+ if (pstmtUpdate != null) {
+ try {
+ pstmtUpdate.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ private void addF5ServiceProvider(Connection conn, long physicalNetworkId, long zoneId){
+ PreparedStatement pstmtUpdate = null;
+ try{
+ // add physical network service provider - F5BigIp
+ s_logger.debug("Adding PhysicalNetworkServiceProvider F5BigIp" + " in to physical network" + physicalNetworkId);
+ String insertPNSP = "INSERT INTO `cloud`.`physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," +
+ "`destination_physical_network_id`, `vpn_service_provided`, `dhcp_service_provided`, `dns_service_provided`, `gateway_service_provided`," +
+ "`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," +
+ "`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,0,0,0,0,0,0,0,1,0,0,0,0)";
+
+ pstmtUpdate = conn.prepareStatement(insertPNSP);
+ pstmtUpdate.setString(1, UUID.randomUUID().toString());
+ pstmtUpdate.setLong(2, physicalNetworkId);
+ pstmtUpdate.setString(3, "F5BigIp");
+ pstmtUpdate.setString(4, "Enabled");
+ pstmtUpdate.executeUpdate();
+ }catch (SQLException e) {
+ throw new CloudRuntimeException("Exception while adding PhysicalNetworkServiceProvider F5BigIp", e);
+ } finally {
+ if (pstmtUpdate != null) {
+ try {
+ pstmtUpdate.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ private void addSrxServiceProvider(Connection conn, long physicalNetworkId, long zoneId){
+ PreparedStatement pstmtUpdate = null;
+ try{
+ // add physical network service provider - JuniperSRX
+ s_logger.debug("Adding PhysicalNetworkServiceProvider JuniperSRX");
+ String insertPNSP = "INSERT INTO `cloud`.`physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," +
+ "`destination_physical_network_id`, `vpn_service_provided`, `dhcp_service_provided`, `dns_service_provided`, `gateway_service_provided`," +
+ "`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," +
+ "`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,0,0,0,0,1,1,1,0,1,1,0,0)";
+
+ pstmtUpdate = conn.prepareStatement(insertPNSP);
+ pstmtUpdate.setString(1, UUID.randomUUID().toString());
+ pstmtUpdate.setLong(2, physicalNetworkId);
+ pstmtUpdate.setString(3, "JuniperSRX");
+ pstmtUpdate.setString(4, "Enabled");
+ pstmtUpdate.executeUpdate();
+ }catch (SQLException e) {
+ throw new CloudRuntimeException("Exception while adding PhysicalNetworkServiceProvider JuniperSRX" , e);
+ } finally {
+ if (pstmtUpdate != null) {
+ try {
+ pstmtUpdate.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ // This method does two things
+ //
+ // 1) ensure that networks using external load balancer/firewall in deployments prior to release 3.0
+ // has entry in network_external_lb_device_map and network_external_firewall_device_map
+ //
+ // 2) Some keys of host details for F5 and SRX devices were stored in Camel Case in 2.x releases. From 3.0
+ // they are made in lowercase. On upgrade change the host details name to lower case
+ private void fixZoneUsingExternalDevices(Connection conn) {
+ //Get zones to upgrade
+ List zoneIds = new ArrayList();
+ PreparedStatement pstmt = null;
+ PreparedStatement pstmtUpdate = null;
+ ResultSet rs = null;
+ long networkOfferingId, networkId;
+ long f5DeviceId, f5HostId;
+ long srxDevivceId, srxHostId;
+
+ try {
+ pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where lb_provider='F5BigIp' or firewall_provider='JuniperSRX' or gateway_provider='JuniperSRX'");
+ rs = pstmt.executeQuery();
+ while (rs.next()) {
+ zoneIds.add(rs.getLong(1));
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable to create network to LB & firewall device mapping for networks that use them", e);
+ }
+
+ if (zoneIds.size() == 0) {
+ return; // no zones using F5 and SRX devices so return
+ }
+
+ // find the default network offering created for external devices during upgrade from 2.2.14
+ try {
+ pstmt = conn.prepareStatement("select id from `cloud`.`network_offerings` where unique_name='Isolated with external providers' ");
+ rs = pstmt.executeQuery();
+ if (rs.first()) {
+ networkOfferingId = rs.getLong(1);
+ } else {
+ throw new CloudRuntimeException("Cannot upgrade as there is no 'Isolated with external providers' network offering crearted .");
+ }
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable to create network to LB & firewalla device mapping for networks that use them", e);
+ }
+
+ for (Long zoneId : zoneIds) {
+ try {
+ // find the F5 device id in the zone
+ pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalLoadBalancer' AND removed IS NULL");
+ pstmt.setLong(1, zoneId);
+ rs = pstmt.executeQuery();
+ if (rs.first()) {
+ f5HostId = rs.getLong(1);
+ } else {
+ throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device found in data center " + zoneId);
+ }
+ pstmt = conn.prepareStatement("SELECT id FROM external_load_balancer_devices WHERE host_id=?");
+ pstmt.setLong(1, f5HostId);
+ rs = pstmt.executeQuery();
+ if (rs.first()) {
+ f5DeviceId = rs.getLong(1);
+ } else {
+ throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device with host ID " + f5HostId + " found in external_load_balancer_device");
+ }
+
+ // find the SRX device id in the zone
+ pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalFirewall' AND removed IS NULL");
+ pstmt.setLong(1, zoneId);
+ rs = pstmt.executeQuery();
+ if (rs.first()) {
+ srxHostId = rs.getLong(1);
+ } else {
+ throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found in data center " + zoneId);
+ }
+ pstmt = conn.prepareStatement("SELECT id FROM external_firewall_devices WHERE host_id=?");
+ pstmt.setLong(1, srxHostId);
+ rs = pstmt.executeQuery();
+ if (rs.first()) {
+ srxDevivceId = rs.getLong(1);
+ } else {
+ throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found with host ID " + srxHostId + " found in external_firewall_devices");
+ }
+
+ // check if network any uses F5 or SRX devices in the zone
+ pstmt = conn.prepareStatement("select id from `cloud`.`networks` where guest_type='Virtual' and data_center_id=? and network_offering_id=? and removed IS NULL");
+ pstmt.setLong(1, zoneId);
+ pstmt.setLong(2, networkOfferingId);
+ rs = pstmt.executeQuery();
+ while (rs.next()) {
+ // get the network Id
+ networkId = rs.getLong(1);
+
+ // add mapping for the network in network_external_lb_device_map
+ String insertLbMapping = "INSERT INTO `cloud`.`network_external_lb_device_map` (uuid, network_id, external_load_balancer_device_id, created) VALUES ( ?, ?, ?, now())";
+ pstmtUpdate = conn.prepareStatement(insertLbMapping);
+ pstmtUpdate.setString(1, UUID.randomUUID().toString());
+ pstmtUpdate.setLong(2, networkId);
+ pstmtUpdate.setLong(3, f5DeviceId);
+ pstmtUpdate.executeUpdate();
+ s_logger.debug("Successfully added entry in network_external_lb_device_map for network " + networkId + " and F5 device ID " + f5DeviceId);
+
+ // add mapping for the network in network_external_firewall_device_map
+ String insertFwMapping = "INSERT INTO `cloud`.`network_external_firewall_device_map` (uuid, network_id, external_firewall_device_id, created) VALUES ( ?, ?, ?, now())";
+ pstmtUpdate = conn.prepareStatement(insertFwMapping);
+ pstmtUpdate.setString(1, UUID.randomUUID().toString());
+ pstmtUpdate.setLong(2, networkId);
+ pstmtUpdate.setLong(3, srxDevivceId);
+ pstmtUpdate.executeUpdate();
+ s_logger.debug("Successfully added entry in network_external_firewall_device_map for network " + networkId + " and SRX device ID " + srxDevivceId);
+ }
+
+ // update host details for F5 and SRX devices
+ s_logger.debug("Updating the host details for F5 and SRX devices");
+ pstmt = conn.prepareStatement("SELECT host_id, name FROM `cloud`.`host_details` WHERE host_id=? OR host_id=?");
+ pstmt.setLong(1, f5HostId);
+ pstmt.setLong(2, srxHostId);
+ rs = pstmt.executeQuery();
+ while (rs.next()) {
+ long hostId = rs.getLong(1);
+ String camlCaseName = rs.getString(2);
+ if (!(camlCaseName.equalsIgnoreCase("numRetries") ||
+ camlCaseName.equalsIgnoreCase("publicZone") ||
+ camlCaseName.equalsIgnoreCase("privateZone") ||
+ camlCaseName.equalsIgnoreCase("publicInterface") ||
+ camlCaseName.equalsIgnoreCase("privateInterface") ||
+ camlCaseName.equalsIgnoreCase("usageInterface") )) {
+ continue;
+ }
+ String lowerCaseName = camlCaseName.toLowerCase();
+ pstmt = conn.prepareStatement("update `cloud`.`host_details` set name=? where host_id=? AND name=?");
+ pstmt.setString(1, lowerCaseName);
+ pstmt.setLong(2, hostId);
+ pstmt.setString(3, camlCaseName);
+ pstmt.executeUpdate();
+ }
+ s_logger.debug("Successfully updated host details for F5 and SRX devices");
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Unable create a mapping for the networks in network_external_lb_device_map and network_external_firewall_device_map", e);
+ } finally {
+ try {
+ if (rs != null) {
+ rs.close();
+ }
+ if (pstmt != null) {
+ pstmt.close();
+ }
+ } catch (SQLException e) {
+ }
+ }
+ s_logger.info("Successfully upgraded network using F5 and SRX devices to have a entry in the network_external_lb_device_map and network_external_firewall_device_map");
+ }
+ }
}
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java
index e7cd61bddfe..b4f9991c99b 100755
--- a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java
+++ b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java
@@ -54,10 +54,9 @@ public interface UserVmDao extends GenericDao {
/**
* List user vm instances with virtualized networking (i.e. not direct attached networking) for the given account and datacenter
* @param accountId will search for vm instances belonging to this account
- * @param dcId will search for vm instances in this zone
* @return the list of vm instances owned by the account in the given data center that have virtualized networking (not direct attached networking)
*/
- List listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId);
+ List listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId);
List listByNetworkIdAndStates(long networkId, State... states);
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
index 5e8be1054a9..1c11563b270 100755
--- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
+++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
@@ -283,11 +283,10 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use
}
@Override
- public List listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId) {
+ public List listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId) {
SearchCriteria sc = AccountDataCenterVirtualSearch.create();
sc.setParameters("account", accountId);
- sc.setParameters("dc", dcId);
sc.setJoinParameters("nicSearch", "networkId", networkId);
return listBy(sc);
diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
index c385e62f6ab..47f1d361216 100644
--- a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
+++ b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
@@ -31,5 +31,6 @@ public interface ApplicationLoadBalancerRuleDao extends GenericDao listBySourceIpAndNotRevoked(Ip sourceIp, long sourceNetworkId);
List listLbIpsBySourceIpNetworkIdAndScheme(long sourceIpNetworkId, Scheme scheme);
+ long countBySourceIpAndNotRevoked(Ip sourceIp, long sourceIpNetworkId);
}
diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
index 880c67e732c..6036b5a2d60 100644
--- a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
@@ -25,6 +25,7 @@ import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
import org.springframework.stereotype.Component;
import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.State;
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
@@ -41,8 +42,8 @@ public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase listIps;
final GenericSearchBuilder CountBy;
protected final SearchBuilder NotRevokedSearch;
-
-
+ final GenericSearchBuilder CountNotRevoked;
+
protected ApplicationLoadBalancerRuleDaoImpl() {
AllFieldsSearch = createSearchBuilder();
@@ -69,6 +70,13 @@ public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase sc = CountNotRevoked.create();
+ sc.setParameters("sourceIp", sourceIp);
+ sc.setParameters("sourceIpNetworkId", sourceIpNetworkId);
+ sc.setParameters("state", State.Revoke);
+ List results = customSearch(sc, null);
+ return results.get(0);
+ }
+
}
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
index 0020f5d4256..ba9dea067ca 100644
--- a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
@@ -31,12 +31,17 @@ public class GlobalLoadBalancerDaoImpl extends GenericDaoBase listByDomainSearch;
private final SearchBuilder listByRegionIDSearch;
+ private final SearchBuilder AccountIdSearch;
public GlobalLoadBalancerDaoImpl() {
listByDomainSearch = createSearchBuilder();
listByDomainSearch.and("gslbDomain", listByDomainSearch.entity().getGslbDomain(), SearchCriteria.Op.EQ);
listByDomainSearch.done();
+ AccountIdSearch = createSearchBuilder();
+ AccountIdSearch.and("account", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+ AccountIdSearch.done();
+
listByRegionIDSearch = createSearchBuilder();
listByRegionIDSearch.and("region", listByRegionIDSearch.entity().getRegion(), SearchCriteria.Op.EQ);
listByRegionIDSearch.done();
@@ -49,6 +54,13 @@ public class GlobalLoadBalancerDaoImpl extends GenericDaoBase listByAccount(long accountId) {
+ SearchCriteria sc = AccountIdSearch.create();
+ sc.setParameters("account", accountId);
+ return listBy(sc, null);
+ }
+
@Override
public GlobalLoadBalancerRuleVO findByDomainName(String domainName) {
SearchCriteria sc = listByDomainSearch.create();
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
index 1b44caa444a..cfc86256c42 100644
--- a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
+++ b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
@@ -24,5 +24,8 @@ import java.util.List;
public interface GlobalLoadBalancerRuleDao extends GenericDao {
List listByRegionId(int regionId);
+
+ List listByAccount(long accountId);
+
GlobalLoadBalancerRuleVO findByDomainName(String domainName);
}
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java
index ba29c1a14b0..fef97671961 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java
@@ -30,6 +30,7 @@ import org.apache.cloudstack.storage.image.db.ImageDataStoreDao;
import org.apache.cloudstack.storage.image.db.ImageDataStoreVO;
import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
public class DefaultImageDataStoreLifeCycle implements ImageDataStoreLifeCycle {
@Inject
@@ -65,7 +66,7 @@ public class DefaultImageDataStoreLifeCycle implements ImageDataStoreLifeCycle {
@Override
- public boolean attachZone(DataStore dataStore, ZoneScope scope) {
+ public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisor) {
// TODO Auto-generated method stub
return false;
}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
index e9769802a37..d8d413283ad 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
@@ -38,34 +38,36 @@ import com.cloud.vm.VirtualMachineProfile;
@Component
public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
- private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class);
- @Inject PrimaryDataStoreDao _storagePoolDao;
- @Inject DataStoreManager dataStoreMgr;
+ private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class);
+ @Inject PrimaryDataStoreDao _storagePoolDao;
+ @Inject DataStoreManager dataStoreMgr;
- @Override
- protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh,
- DeploymentPlan plan) {
+ @Override
+ protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh,
+ DeploymentPlan plan) {
Volume volume = _volumeDao.findById(dskCh.getVolumeId());
List requestVolumes = new ArrayList();
requestVolumes.add(volume);
return storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool);
- }
+ }
- @Override
- protected List select(DiskProfile dskCh,
- VirtualMachineProfile extends VirtualMachine> vmProfile,
- DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
- s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool");
- List suitablePools = new ArrayList();
- HypervisorType hypervisor = dskCh.getHypervisorType();
- if (hypervisor != null) {
- if (hypervisor != HypervisorType.KVM) {
- s_logger.debug("Only kvm supports zone wide storage");
- return suitablePools;
- }
- }
+ @Override
+ protected List select(DiskProfile dskCh,
+ VirtualMachineProfile extends VirtualMachine> vmProfile,
+ DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+ s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool");
+ List suitablePools = new ArrayList();
+ HypervisorType hypervisor = dskCh.getHypervisorType();
+ if (hypervisor != null) {
+ if (hypervisor != HypervisorType.KVM && hypervisor != HypervisorType.VMware) {
+ s_logger.debug("Only kvm, VMware hypervisors are enabled to support zone wide storage");
+ return suitablePools;
+ }
+ }
- List storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
+ List storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
+ List storagePoolsByHypervisor = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType());
+ storagePools.retainAll(storagePoolsByHypervisor);
// add remaining pools in zone, that did not match tags, to avoid set
List allPools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), null);
@@ -74,17 +76,17 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
avoid.addPool(pool.getId());
}
- for (StoragePoolVO storage : storagePools) {
- if (suitablePools.size() == returnUpTo) {
- break;
- }
- StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
- if (filter(avoid, pol, dskCh, plan)) {
- suitablePools.add(pol);
+ for (StoragePoolVO storage : storagePools) {
+ if (suitablePools.size() == returnUpTo) {
+ break;
+ }
+ StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
+ if (filter(avoid, pol, dskCh, plan)) {
+ suitablePools.add(pol);
} else {
avoid.addPool(pol.getId());
}
- }
- return suitablePools;
- }
+ }
+ return suitablePools;
+ }
}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
index 5f8daf42bb3..349f6ba9079 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
@@ -29,25 +29,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
-import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.alert.AlertManager;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -70,7 +65,7 @@ public class PrimaryDataStoreHelper {
if (dataStoreVO != null) {
throw new CloudRuntimeException("duplicate uuid: " + params.getUuid());
}
-
+
dataStoreVO = new StoragePoolVO();
dataStoreVO.setStorageProviderName(params.getProviderName());
dataStoreVO.setHostAddress(params.getHost());
@@ -84,7 +79,7 @@ public class PrimaryDataStoreHelper {
dataStoreVO.setClusterId(params.getClusterId());
dataStoreVO.setStatus(StoragePoolStatus.Initialized);
dataStoreVO.setUserInfo(params.getUserInfo());
-
+
Map details = params.getDetails();
String tags = params.getTags();
if (tags != null) {
@@ -98,19 +93,19 @@ public class PrimaryDataStoreHelper {
details.put(tag, "true");
}
}
-
+
dataStoreVO = dataStoreDao.persist(dataStoreVO, details);
return dataStoreMgr.getDataStore(dataStoreVO.getId(), DataStoreRole.Primary);
}
-
+
public DataStore attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(store.getId(), scope.getScopeId());
if (poolHost == null) {
poolHost = new StoragePoolHostVO(store.getId(), scope.getScopeId(), existingInfo.getLocalPath());
storagePoolHostDao.persist(poolHost);
}
-
+
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
pool.setScope(scope.getScopeType());
pool.setAvailableBytes(existingInfo.getAvailableBytes());
@@ -120,18 +115,18 @@ public class PrimaryDataStoreHelper {
this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, pool.getCapacityBytes() - pool.getAvailableBytes());
return dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
}
-
+
public DataStore attachCluster(DataStore store) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
-
+
storageMgr.createCapacityEntry(pool.getId());
-
+
pool.setScope(ScopeType.CLUSTER);
pool.setStatus(StoragePoolStatus.Up);
this.dataStoreDao.update(pool.getId(), pool);
return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
}
-
+
public DataStore attachZone(DataStore store) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
pool.setScope(ScopeType.ZONE);
@@ -139,21 +134,30 @@ public class PrimaryDataStoreHelper {
this.dataStoreDao.update(pool.getId(), pool);
return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
}
-
+
+ public DataStore attachZone(DataStore store, HypervisorType hypervisor) {
+ StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
+ pool.setScope(ScopeType.ZONE);
+ pool.setHypervisor(hypervisor);
+ pool.setStatus(StoragePoolStatus.Up);
+ this.dataStoreDao.update(pool.getId(), pool);
+ return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
+ }
+
public boolean maintain(DataStore store) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
pool.setStatus(StoragePoolStatus.Maintenance);
this.dataStoreDao.update(pool.getId(), pool);
return true;
}
-
+
public boolean cancelMaintain(DataStore store) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
pool.setStatus(StoragePoolStatus.Up);
dataStoreDao.update(store.getId(), pool);
return true;
}
-
+
protected boolean deletePoolStats(Long poolId) {
CapacityVO capacity1 = _capacityDao.findByHostIdType(poolId,
@@ -167,10 +171,10 @@ public class PrimaryDataStoreHelper {
if (capacity2 != null) {
_capacityDao.remove(capacity2.getId());
}
-
+
return true;
}
-
+
public boolean deletePrimaryDataStore(DataStore store) {
List hostPoolRecords = this.storagePoolHostDao
.listByPoolId(store.getId());
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
index fea02e8d1ed..cffa1cee4dc 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
@@ -114,7 +114,7 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
}
@Override
- public boolean attachZone(DataStore dataStore, ZoneScope scope) {
+ public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
// TODO Auto-generated method stub
return false;
}
diff --git a/packaging/centos63/cloud-management.rc b/packaging/centos63/cloud-management.rc
index 6fd435b555d..35f31b28538 100755
--- a/packaging/centos63/cloud-management.rc
+++ b/packaging/centos63/cloud-management.rc
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
-# cloud-management This shell script takes care of starting and stopping Tomcat
+# cloudstack-management This shell script takes care of starting and stopping Tomcat
#
# chkconfig: - 80 20
#
@@ -56,13 +56,13 @@ stop() {
let count="${count}+1"
done
if [ "$(ps --pid $pid | grep -c $pid)" -eq "0" ]; then
- log_success_msg "Stopping cloud-management:"
+ log_success_msg "Stopping ${NAME}:"
else
- log_failure_msg "Stopping cloud-management:"
+ log_failure_msg "Stopping ${NAME}:"
fi
else
- echo "Cannot find PID file of Cloud-management"
- log_failure_msg "Stopping cloud-management:"
+ echo "Cannot find PID file of ${NAME}"
+ log_failure_msg "Stopping ${NAME}:"
fi
}
diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec
index 1cde336e7b1..1f112ddd686 100644
--- a/packaging/centos63/cloud.spec
+++ b/packaging/centos63/cloud.spec
@@ -165,11 +165,11 @@ echo VERSION=%{_maventag} >> build/replace.properties
echo PACKAGE=%{name} >> build/replace.properties
if [ "%{_ossnoss}" == "NONOSS" -o "%{_ossnoss}" == "nonoss" ] ; then
- echo "Executing mvn packaging for NONOSS ..."
- mvn -Pawsapi,systemvm -Dnonoss package
+ echo "Executing mvn packaging for NONOSS ..."
+ mvn -Pawsapi,systemvm -Dnonoss package clean install
else
- echo "Executing mvn packaging for OSS ..."
- mvn -Pawsapi package -Dsystemvm
+ echo "Executing mvn packaging for OSS ..."
+ mvn -Pawsapi package -Dsystemvm clean install
fi
%install
@@ -216,6 +216,8 @@ ln -sf /var/log/%{name}/management ${RPM_BUILD_ROOT}%{_datadir}/%{name}-manageme
ln -sf /var/cache/%{name}/management/temp ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/temp
ln -sf /var/cache/%{name}/management/work ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/work
+/bin/touch ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management/catalina.out
+
install -D client/target/utilities/bin/cloud-migrate-databases ${RPM_BUILD_ROOT}%{_bindir}/%{name}-migrate-databases
install -D client/target/utilities/bin/cloud-set-guest-password ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-password
install -D client/target/utilities/bin/cloud-set-guest-sshkey ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-sshkey
@@ -519,6 +521,7 @@ fi
%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}-management
%{_defaultdocdir}/%{name}-management-%{version}/LICENSE
%{_defaultdocdir}/%{name}-management-%{version}/NOTICE
+%attr(0644,cloud,cloud) %{_localstatedir}/log/%{name}/management/catalina.out
%files agent
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
index ca3b970210b..0dcd5710664 100755
--- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config
+++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash
### BEGIN INIT INFO
# Provides: cloud-early-config
# Required-Start: mountkernfs $local_fs
@@ -87,14 +87,13 @@ EOF
hypervisor() {
[ -d /proc/xen ] && mount -t xenfs none /proc/xen
+ [ -d /proc/xen ] && echo "xen-domU" && return 0
local try=$([ -x /usr/sbin/virt-what ] && virt-what | tail -1)
[ "$try" != "" ] && echo $try && return 0
vmware-checkvm &> /dev/null && echo "vmware" && return 0
- [ -d /proc/xen ] && echo "xen-domU" && return 0
-
grep -q QEMU /proc/cpuinfo && echo "kvm" && return 0
grep -q QEMU /var/log/messages && echo "kvm" && return 0
@@ -343,6 +342,22 @@ enable_svc() {
[ -f $cfg ] && sed -i "s/ENABLED=.*$/ENABLED=$enabled/" $cfg && return
}
+
+enable_irqbalance() {
+ local enabled=$1
+ local proc=0
+
+ proc=$(cat /proc/cpuinfo | grep "processor" | wc -l)
+ if [ $proc -le 1 ] && [ $enabled -eq 1 ]
+ then
+ enabled=0
+ fi
+
+ log_it "Processors = $proc Enable service ${svc} = $enabled"
+ local cfg=/etc/default/irqbalance
+ [ -f $cfg ] && sed -i "s/ENABLED=.*$/ENABLED=$enabled/" $cfg && return
+}
+
disable_hvc() {
[ ! -d /proc/xen ] && sed -i 's/^vc/#vc/' /etc/inittab && telinit q
[ -d /proc/xen ] && sed -i 's/^#vc/vc/' /etc/inittab && telinit q
@@ -699,6 +714,7 @@ setup_router() {
enable_svc dnsmasq 1
enable_svc haproxy 1
+ enable_irqbalance 1
enable_svc cloud-passwd-srvr 1
enable_svc cloud 0
disable_rpfilter_domR
@@ -778,6 +794,7 @@ EOF
enable_svc dnsmasq 1
enable_svc haproxy 1
+ enable_irqbalance 1
enable_svc cloud 0
disable_rpfilter
enable_fwding 1
@@ -804,6 +821,7 @@ setup_dhcpsrvr() {
enable_svc dnsmasq 1
enable_svc haproxy 0
+ enable_irqbalance 0
enable_svc cloud-passwd-srvr 1
enable_svc cloud 0
enable_fwding 0
@@ -856,6 +874,7 @@ setup_secstorage() {
disable_rpfilter
enable_fwding 0
enable_svc haproxy 0
+ enable_irqbalance 0
enable_svc dnsmasq 0
enable_svc cloud-passwd-srvr 0
enable_svc cloud 1
@@ -880,6 +899,7 @@ setup_console_proxy() {
disable_rpfilter
enable_fwding 0
enable_svc haproxy 0
+ enable_irqbalance 0
enable_svc dnsmasq 0
enable_svc cloud-passwd-srvr 0
enable_svc cloud 1
@@ -906,6 +926,7 @@ setup_elbvm() {
enable_fwding 0
enable_svc haproxy 0
+ enable_irqbalance 0
enable_svc dnsmasq 0
enable_svc cloud-passwd-srvr 0
enable_svc cloud 0
@@ -928,6 +949,7 @@ setup_ilbvm() {
enable_fwding 0
enable_svc haproxy 1
+ enable_irqbalance 1
enable_svc dnsmasq 0
enable_svc cloud-passwd-srvr 0
enable_svc cloud 0
diff --git a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
index f326fac9e54..d23ec00de5e 100755
--- a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
+++ b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
@@ -227,7 +227,8 @@ add_first_ip() {
if [ $if_keep_state -ne 1 -o $old_state -ne 0 ]
then
sudo ip link set $ethDev up
- sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
+ sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
+ sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
fi
add_routing $1
@@ -273,7 +274,8 @@ add_an_ip () {
if [ $if_keep_state -ne 1 -o $old_state -ne 0 ]
then
sudo ip link set $ethDev up
- sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
+ sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
+ sudo arping -c 1 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
fi
add_routing $1
return $?
diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh
index 17cb078b34f..2f8835120e4 100755
--- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh
+++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh
@@ -22,7 +22,7 @@ getEthByIp (){
local ip=$1
for dev in `ls -1 /sys/class/net | grep eth`
do
- sudo ip addr show dev $dev | grep $ip > /dev/null
+ sudo ip addr show dev $dev | grep $ip\/ > /dev/null
if [ $? -eq 0 ]
then
echo $dev
diff --git a/patches/systemvm/debian/config/root/deleteIpAlias.sh b/patches/systemvm/debian/config/root/deleteIpAlias.sh
index 865ff3b4769..cf6d4de5269 100755
--- a/patches/systemvm/debian/config/root/deleteIpAlias.sh
+++ b/patches/systemvm/debian/config/root/deleteIpAlias.sh
@@ -24,7 +24,7 @@ set -x
var="$1"
cert="/root/.ssh/id_rsa.cloud"
-while [ -n "$var" ]
+while [[ !( "$var" == "-" ) ]]
do
var1=$(echo $var | cut -f1 -d "-")
alias_count=$( echo $var1 | cut -f1 -d ":" )
diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml
new file mode 100644
index 00000000000..bb3c595841a
--- /dev/null
+++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+ cloud-plugin-explicit-dedication
+ Apache CloudStack Plugin - Explicit Dedication Processor
+
+ org.apache.cloudstack
+ cloudstack-plugins
+ 4.2.0-SNAPSHOT
+ ../../pom.xml
+
+
+ install
+ src
+
+
diff --git a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
new file mode 100644
index 00000000000..a0eb56cbb8a
--- /dev/null
+++ b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
@@ -0,0 +1,383 @@
+// 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.affinity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.AffinityConflictException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value = AffinityGroupProcessor.class)
+public class ExplicitDedicationProcessor extends AffinityProcessorBase implements AffinityGroupProcessor {
+
+ private static final Logger s_logger = Logger.getLogger(ExplicitDedicationProcessor.class);
+ @Inject
+ protected UserVmDao _vmDao;
+ @Inject
+ protected VMInstanceDao _vmInstanceDao;
+ @Inject
+ protected DataCenterDao _dcDao;
+ @Inject
+ protected DedicatedResourceDao _dedicatedDao;
+ @Inject
+ protected HostPodDao _podDao;
+ @Inject
+ protected ClusterDao _clusterDao;
+ @Inject
+ protected HostDao _hostDao;
+ @Inject
+ protected DomainDao _domainDao;
+ @Inject
+ protected AffinityGroupDao _affinityGroupDao;
+ @Inject
+ protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
+
+ /**
+ * This method will process the affinity group of type 'Explicit Dedication' for a deployment of a VM that demands dedicated resources.
+ * For ExplicitDedicationProcessor we need to add dedicated resources into the IncludeList based on the level we have dedicated resources available.
+ * For eg. if admin dedicates a pod to a domain, then all the user in that domain can use the resources of that pod.
+ * We need to take care of the situation when dedicated resources further have resources dedicated to sub-domain/account.
+ * This IncludeList is then used to update the avoid list for a given data center.
+ */
+ @Override
+ public void process(VirtualMachineProfile extends VirtualMachine> vmProfile, DeploymentPlan plan,
+ ExcludeList avoid) throws AffinityConflictException {
+ VirtualMachine vm = vmProfile.getVirtualMachine();
+ List vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), getType());
+ DataCenter dc = _dcDao.findById(vm.getDataCenterId());
+ long domainId = vm.getDomainId();
+ long accountId = vm.getAccountId();
+
+ for (AffinityGroupVMMapVO vmGroupMapping : vmGroupMappings) {
+ if (vmGroupMapping != null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Processing affinity group of type 'ExplicitDedication' for VM Id: " + vm.getId());
+ }
+
+ List dr = _dedicatedDao.listByAccountId(accountId);
+ List drOfDomain = searchInDomainResources(domainId);
+ List drOfParentDomain = searchInParentDomainResources(domainId);
+ List resourceList = new ArrayList();
+ resourceList.addAll(dr);
+ resourceList.addAll(drOfDomain);
+ resourceList.addAll(drOfParentDomain);
+ boolean canUse = false;
+
+ if (plan.getHostId() != null) {
+ HostVO host = _hostDao.findById(plan.getHostId());
+ ClusterVO clusterofHost = _clusterDao.findById(host.getClusterId());
+ HostPodVO podOfHost = _podDao.findById(host.getPodId());
+ DataCenterVO zoneOfHost = _dcDao.findById(host.getDataCenterId());
+ if (resourceList != null && resourceList.size() != 0) {
+ for(DedicatedResourceVO resource : resourceList){
+ if ((resource.getHostId() != null && resource.getHostId() == plan.getHostId()) ||
+ (resource.getClusterId() != null && resource.getClusterId() == clusterofHost.getId()) ||
+ (resource.getPodId() != null && resource.getPodId() == podOfHost.getId()) ||
+ (resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfHost.getId())){
+ canUse = true;
+ }
+ }
+ }
+ if (!canUse) {
+ throw new CloudRuntimeException("Cannot use this host " + host.getName() + " for explicit dedication");
+ }
+ } else if (plan.getClusterId() != null) {
+ ClusterVO cluster = _clusterDao.findById(plan.getClusterId());
+ HostPodVO podOfCluster = _podDao.findById(cluster.getPodId());
+ DataCenterVO zoneOfCluster = _dcDao.findById(cluster.getDataCenterId());
+ List hostToUse = new ArrayList();
+ // check whether this cluster or its pod is dedicated
+ if (resourceList != null && resourceList.size() != 0) {
+ for(DedicatedResourceVO resource : resourceList){
+ if ((resource.getClusterId() != null && resource.getClusterId() == cluster.getId()) ||
+ (resource.getPodId() != null && resource.getPodId() == podOfCluster.getId()) ||
+ (resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfCluster.getId())){
+ canUse = true;
+ }
+
+ // check for all dedicated host; if it belongs to this cluster
+ if (!canUse){
+ if (resource.getHostId() != null) {
+ HostVO dHost = _hostDao.findById(resource.getHostId());
+ if (dHost.getClusterId() == cluster.getId()) {
+ hostToUse.add(dHost);
+ }
+ }
+ }
+
+ }
+ }
+
+ if (hostToUse.isEmpty() && !canUse) {
+ throw new CloudRuntimeException("Cannot use this cluster " + cluster.getName() + " for explicit dedication");
+ }
+
+ if (hostToUse != null && hostToUse.size() != 0) {
+ // add other non-dedicated hosts to avoid list
+ List hostList = _hostDao.findByClusterId(cluster.getId());
+ for (HostVO host : hostList){
+ if (!hostToUse.contains(host)) {
+ avoid.addHost(host.getId());
+ }
+ }
+ }
+
+ } else if (plan.getPodId() != null) {
+ HostPodVO pod = _podDao.findById(plan.getPodId());
+ DataCenterVO zoneOfPod = _dcDao.findById(pod.getDataCenterId());
+ List clustersToUse = new ArrayList();
+ List hostsToUse = new ArrayList();
+ // check whether this cluster or its pod is dedicated
+ if (resourceList != null && resourceList.size() != 0) {
+ for(DedicatedResourceVO resource : resourceList){
+ if ((resource.getPodId() != null && resource.getPodId() == pod.getId()) ||
+ (resource.getDataCenterId() != null && resource.getDataCenterId() == zoneOfPod.getId())){
+ canUse = true;
+ }
+
+ // check for all dedicated cluster/host; if it belongs to this pod
+ if (!canUse){
+ if (resource.getClusterId() != null) {
+ ClusterVO dCluster = _clusterDao.findById(resource.getClusterId());
+ if (dCluster.getPodId() == pod.getId()) {
+ clustersToUse.add(dCluster);
+ }
+ }
+ if (resource.getHostId() != null) {
+ HostVO dHost = _hostDao.findById(resource.getHostId());
+ if (dHost.getPodId() == pod.getId()) {
+ hostsToUse.add(dHost);
+ }
+ }
+ }
+
+ }
+ }
+
+ if (hostsToUse.isEmpty() && clustersToUse.isEmpty() && !canUse) {
+ throw new CloudRuntimeException("Cannot use this pod " + pod.getName() + " for explicit dedication");
+ }
+
+ if (clustersToUse != null && clustersToUse.size() != 0) {
+ // add other non-dedicated clusters to avoid list
+ List clusterList = _clusterDao.listByPodId(pod.getId());
+ for (ClusterVO cluster : clusterList){
+ if (!clustersToUse.contains(cluster)) {
+ avoid.addCluster(cluster.getId());
+ }
+ }
+ }
+
+ if (hostsToUse != null && hostsToUse.size() != 0) {
+ // add other non-dedicated hosts to avoid list
+ List hostList = _hostDao.findByPodId(pod.getId());
+ for (HostVO host : hostList){
+ if (!hostsToUse.contains(host)) {
+ avoid.addHost(host.getId());
+ }
+ }
+ }
+
+ } else {
+ //check all resources under this zone
+ if (dr != null && dr.size() != 0) {
+ avoid = updateAvoidList(dr, avoid, dc);
+ } else if(drOfDomain != null && drOfDomain.size() != 0){
+ avoid = updateAvoidList(drOfDomain, avoid, dc);
+ } else if(drOfParentDomain != null && drOfParentDomain.size() != 0){
+ avoid = updateAvoidList(drOfParentDomain, avoid, dc);
+ } else {
+ avoid.addDataCenter(dc.getId());
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("No dedicated resources available for this domain or account");
+ }
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("ExplicitDedicationProcessor returns Avoid List as: Deploy avoids pods: " + avoid.getPodsToAvoid() + ", clusters: "
+ + avoid.getClustersToAvoid() + ", hosts: " + avoid.getHostsToAvoid());
+ }
+ }
+ }
+ }
+ }
+
+ private ExcludeList updateAvoidList(List dedicatedResources, ExcludeList avoidList, DataCenter dc) {
+ ExcludeList includeList = new ExcludeList();
+ for (DedicatedResourceVO dr : dedicatedResources) {
+ if (dr.getHostId() != null){
+ includeList.addHost(dr.getHostId());
+ HostVO dedicatedHost = _hostDao.findById(dr.getHostId());
+ includeList.addCluster(dedicatedHost.getClusterId());
+ includeList.addPod(dedicatedHost.getPodId());
+ }
+
+ if (dr.getClusterId() != null) {
+ includeList.addCluster(dr.getClusterId());
+ //add all hosts inside this in includeList
+ List hostList = _hostDao.findByClusterId(dr.getClusterId());
+ for (HostVO host : hostList) {
+ DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+ if (dHost != null) {
+ avoidList.addHost(host.getId());
+ } else {
+ includeList.addHost(host.getId());
+ }
+ }
+ ClusterVO dedicatedCluster = _clusterDao.findById(dr.getClusterId());
+ includeList.addPod(dedicatedCluster.getPodId());
+ }
+
+ if (dr.getPodId() != null) {
+ includeList.addPod(dr.getPodId());
+ //add all cluster under this pod in includeList
+ List clusterList = _clusterDao.listByPodId(dr.getPodId());
+ for (ClusterVO cluster : clusterList) {
+ if (_dedicatedDao.findByClusterId(cluster.getId()) != null) {
+ avoidList.addCluster(cluster.getId());
+ } else {
+ includeList.addCluster(cluster.getId());
+ }
+ }
+ //add all hosts inside this pod in includeList
+ List hostList = _hostDao.findByPodId(dr.getPodId());
+ for (HostVO host : hostList) {
+ if (_dedicatedDao.findByHostId(host.getId()) != null) {
+ avoidList.addHost(host.getId());
+ } else {
+ includeList.addHost(host.getId());
+ }
+ }
+ }
+
+ if (dr.getDataCenterId() != null) {
+ includeList.addDataCenter(dr.getDataCenterId());
+ //add all Pod under this data center in includeList
+ List podList = _podDao.listByDataCenterId(dr.getDataCenterId());
+ for (HostPodVO pod : podList) {
+ if (_dedicatedDao.findByPodId(pod.getId()) != null) {
+ avoidList.addPod(pod.getId());
+ } else {
+ includeList.addPod(pod.getId());
+ }
+ }
+ List clusterList = _clusterDao.listClustersByDcId(dr.getDataCenterId());
+ for (ClusterVO cluster : clusterList) {
+ if (_dedicatedDao.findByClusterId(cluster.getId()) != null) {
+ avoidList.addCluster(cluster.getId());
+ } else {
+ includeList.addCluster(cluster.getId());
+ }
+ }
+ //add all hosts inside this in includeList
+ List hostList = _hostDao.listByDataCenterId(dr.getDataCenterId());
+ for (HostVO host : hostList) {
+ if (_dedicatedDao.findByHostId(host.getId()) != null) {
+ avoidList.addHost(host.getId());
+ } else {
+ includeList.addHost(host.getId());
+ }
+ }
+ }
+ }
+ //Update avoid list using includeList.
+ //add resources in avoid list which are not in include list.
+
+ List pods = _podDao.listByDataCenterId(dc.getId());
+ List clusters = _clusterDao.listClustersByDcId(dc.getId());
+ List hosts = _hostDao.listByDataCenterId(dc.getId());
+ Set podsInIncludeList = includeList.getPodsToAvoid();
+ Set clustersInIncludeList = includeList.getClustersToAvoid();
+ Set hostsInIncludeList = includeList.getHostsToAvoid();
+
+ for (HostPodVO pod : pods){
+ if (podsInIncludeList != null && !podsInIncludeList.contains(pod.getId())) {
+ avoidList.addPod(pod.getId());
+ }
+ }
+
+ for (ClusterVO cluster : clusters) {
+ if (clustersInIncludeList != null && !clustersInIncludeList.contains(cluster.getId())) {
+ avoidList.addCluster(cluster.getId());
+ }
+ }
+
+ for (HostVO host : hosts) {
+ if (hostsInIncludeList != null && !hostsInIncludeList.contains(host.getId())) {
+ avoidList.addHost(host.getId());
+ }
+ }
+ return avoidList;
+ }
+
+ private List searchInParentDomainResources(long domainId) {
+ List domainIds = getDomainParentIds(domainId);
+ List dr = new ArrayList();
+ for (Long id : domainIds) {
+ List resource = _dedicatedDao.listByDomainId(id);
+ if(resource != null) {
+ dr.addAll(resource);
+ }
+ }
+ return dr;
+ }
+
+ private List searchInDomainResources(long domainId) {
+ List dr = _dedicatedDao.listByDomainId(domainId);
+ return dr;
+ }
+
+ private List getDomainParentIds(long domainId) {
+ DomainVO domainRecord = _domainDao.findById(domainId);
+ List domainIds = new ArrayList();
+ domainIds.add(domainRecord.getId());
+ while (domainRecord.getParent() != null ){
+ domainRecord = _domainDao.findById(domainRecord.getParent());
+ domainIds.add(domainRecord.getId());
+ }
+ return domainIds;
+ }
+
+}
diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml
new file mode 100644
index 00000000000..4c908f4ff96
--- /dev/null
+++ b/plugins/dedicated-resources/pom.xml
@@ -0,0 +1,29 @@
+
+
+ 4.0.0
+ cloud-plugin-dedicated-resources
+ Apache CloudStack Plugin - Dedicated Resources
+
+ org.apache.cloudstack
+ cloudstack-plugins
+ 4.2.0-SNAPSHOT
+ ../pom.xml
+
+
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateClusterCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateClusterCmd.java
new file mode 100644
index 00000000000..91e4fcee3ad
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateClusterCmd.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.DedicateClusterResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "dedicateCluster", description= "Dedicate an existing cluster", responseObject = DedicateClusterResponse.class )
+public class DedicateClusterCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(DedicateClusterCmd.class.getName());
+
+ private static final String s_name = "dedicateclusterresponse";
+ @Inject DedicatedService dedicatedService;
+
+ @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
+ required=true, description="the ID of the Cluster")
+ private Long clusterId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getClusterId() {
+ return clusterId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "dedicating a cluster";
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ List extends DedicatedResources> result = dedicatedService.dedicateCluster(getClusterId(), getDomainId(), getAccountName());
+ ListResponse response = new ListResponse();
+ List clusterResponseList = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result) {
+ DedicateClusterResponse clusterResponse = dedicatedService.createDedicateClusterResponse(resource);
+ clusterResponseList.add(clusterResponse);
+ }
+ response.setResponses(clusterResponseList);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate cluster");
+ }
+ }
+
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateHostCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateHostCmd.java
new file mode 100644
index 00000000000..cb8eb45e0c4
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateHostCmd.java
@@ -0,0 +1,118 @@
+// 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.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.DedicateHostResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "dedicateHost", description = "Dedicates a host.", responseObject = DedicateHostResponse.class)
+public class DedicateHostCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(DedicateHostCmd.class.getName());
+ private static final String s_name = "dedicatehostresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType = HostResponse.class,
+ required=true, description="the ID of the host to update")
+ private Long hostId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getHostId() {
+ return hostId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ List extends DedicatedResources> result = dedicatedService.dedicateHost(getHostId(), getDomainId(), getAccountName());
+ ListResponse response = new ListResponse();
+ List hostResponseList = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result) {
+ DedicateHostResponse hostResponse = dedicatedService.createDedicateHostResponse(resource);
+ hostResponseList.add(hostResponse);
+ }
+ response.setResponses(hostResponseList);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate host");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "dedicating a host";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicatePodCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicatePodCmd.java
new file mode 100644
index 00000000000..ed3c227e508
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicatePodCmd.java
@@ -0,0 +1,120 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.DedicatePodResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "dedicatePod", description ="Dedicates a Pod.", responseObject = DedicatePodResponse.class)
+public class DedicatePodCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(DedicatePodCmd.class.getName());
+
+ private static final String s_name = "dedicatepodresponse";
+ @Inject public DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
+ required=true, description="the ID of the Pod")
+ private Long podId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ List extends DedicatedResources> result = dedicatedService.dedicatePod(getPodId(), getDomainId(), getAccountName());
+ ListResponse response = new ListResponse();
+ List podResponseList = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result) {
+ DedicatePodResponse podresponse = dedicatedService.createDedicatePodResponse(resource);
+ podResponseList.add(podresponse);
+ }
+ response.setResponses(podResponseList);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate pod");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "dedicating a pod";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateZoneCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateZoneCmd.java
new file mode 100644
index 00000000000..31c6025c305
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateZoneCmd.java
@@ -0,0 +1,120 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.api.response.DedicateZoneResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "dedicateZone", description ="Dedicates a zones.", responseObject = DedicateZoneResponse.class)
+public class DedicateZoneCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(DedicateZoneCmd.class.getName());
+
+ private static final String s_name = "dedicatezoneresponse";
+ @Inject public DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+ required=true, description="the ID of the zone")
+ private Long zoneId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, required=true, description="the ID of the containing domain")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the name of the account which needs dedication. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ List extends DedicatedResources> result = dedicatedService.dedicateZone(getZoneId(), getDomainId(), getAccountName());
+ ListResponse response = new ListResponse();
+ List zoneResponseList = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result) {
+ DedicateZoneResponse zoneresponse = dedicatedService.createDedicateZoneResponse(resource);
+ zoneResponseList.add(zoneresponse);
+ }
+ response.setResponses(zoneResponseList);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate zone");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "dedicating a zone";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
new file mode 100644
index 00000000000..f3947876581
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
@@ -0,0 +1,105 @@
+// 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.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.DedicateClusterResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listDedicatedClusters", description = "Lists dedicated clusters.", responseObject = DedicateClusterResponse.class)
+public class ListDedicatedClustersCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListDedicatedClustersCmd.class.getName());
+
+ private static final String s_name = "listdedicatedclustersresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
+ description="the ID of the cluster")
+ private Long clusterId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+ description="the ID of the domain associated with the cluster")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
+ description = "the name of the account associated with the cluster. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getClusterId() {
+ return clusterId;
+ }
+
+ public Long getDomainId(){
+ return domainId;
+ }
+
+ public String getAccountName(){
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public void execute(){
+ Pair, Integer> result = dedicatedService.listDedicatedClusters(this);
+ ListResponse response = new ListResponse();
+ List Responses = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result.first()) {
+ DedicateClusterResponse clusterResponse = dedicatedService.createDedicateClusterResponse(resource);
+ Responses.add(clusterResponse);
+ }
+ response.setResponses(Responses, result.second());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated clusters");
+ }
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
new file mode 100644
index 00000000000..736251b36d6
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
@@ -0,0 +1,105 @@
+// 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.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.DedicateHostResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listDedicatedHosts", description = "Lists dedicated hosts.", responseObject = DedicateHostResponse.class)
+public class ListDedicatedHostsCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListDedicatedHostsCmd.class.getName());
+
+ private static final String s_name = "listdedicatedhostsresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+ description="the ID of the host")
+ private Long hostId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+ description="the ID of the domain associated with the host")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
+ description = "the name of the account associated with the host. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getHostId() {
+ return hostId;
+ }
+
+ public Long getDomainId(){
+ return domainId;
+ }
+
+ public String getAccountName(){
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////l
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public void execute(){
+ Pair, Integer> result = dedicatedService.listDedicatedHosts(this);
+ ListResponse response = new ListResponse();
+ List Responses = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result.first()) {
+ DedicateHostResponse hostResponse = dedicatedService.createDedicateHostResponse(resource);
+ Responses.add(hostResponse);
+ }
+ response.setResponses(Responses, result.second());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated hosts");
+ }
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
new file mode 100644
index 00000000000..da59edae8d3
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
@@ -0,0 +1,105 @@
+// 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.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.DedicatePodResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listDedicatedPods", description = "Lists dedicated pods.", responseObject = DedicatePodResponse.class)
+public class ListDedicatedPodsCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListDedicatedPodsCmd.class.getName());
+
+ private static final String s_name = "listdedicatedpodsresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
+ description="the ID of the pod")
+ private Long podId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+ description="the ID of the domain associated with the pod")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
+ description = "the name of the account associated with the pod. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public Long getDomainId(){
+ return domainId;
+ }
+
+ public String getAccountName(){
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public void execute(){
+ Pair, Integer> result = dedicatedService.listDedicatedPods(this);
+ ListResponse response = new ListResponse();
+ List Responses = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result.first()) {
+ DedicatePodResponse podresponse = dedicatedService.createDedicatePodResponse(resource);
+ Responses.add(podresponse);
+ }
+ response.setResponses(Responses, result.second());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated pods");
+ }
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
new file mode 100644
index 00000000000..a21f129f5be
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
@@ -0,0 +1,105 @@
+// 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.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.api.response.DedicateZoneResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listDedicatedZones", description = "List dedicated zones.", responseObject = DedicateZoneResponse.class)
+public class ListDedicatedZonesCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListDedicatedZonesCmd.class.getName());
+
+ private static final String s_name = "listdedicatedzonesresponse";
+ @Inject DedicatedService _dedicatedservice;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+ description="the ID of the Zone")
+ private Long zoneId;
+
+ @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+ description="the ID of the domain associated with the zone")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
+ description = "the name of the account associated with the zone. Must be used with domainId.")
+ private String accountName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getDomainId(){
+ return domainId;
+ }
+
+ public String getAccountName(){
+ return accountName;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public void execute(){
+ Pair, Integer> result = _dedicatedservice.listDedicatedZones(this);
+ ListResponse response = new ListResponse();
+ List Responses = new ArrayList();
+ if (result != null) {
+ for (DedicatedResources resource : result.first()) {
+ DedicateZoneResponse zoneResponse = _dedicatedservice.createDedicateZoneResponse(resource);
+ Responses.add(zoneResponse);
+ }
+ response.setResponses(Responses, result.second());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to list dedicated zones");
+ }
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java
new file mode 100644
index 00000000000..ba1c6aad7cc
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java
@@ -0,0 +1,91 @@
+// 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.commands;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "releaseDedicatedCluster", description = "Release the dedication for cluster", responseObject = SuccessResponse.class)
+public class ReleaseDedicatedClusterCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedClusterCmd.class.getName());
+
+ private static final String s_name = "releasededicatedclusterresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType=ClusterResponse.class,
+ required=true, description="the ID of the Cluster")
+ private Long clusterId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getClusterId() {
+ return clusterId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ boolean result = dedicatedService.releaseDedicatedResource(null, null, getClusterId(), null);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated cluster");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "releasing dedicated cluster";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java
new file mode 100644
index 00000000000..a79c965926d
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java
@@ -0,0 +1,91 @@
+// 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.commands;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "releaseDedicatedHost", description = "Release the dedication for host", responseObject = SuccessResponse.class)
+public class ReleaseDedicatedHostCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedHostCmd.class.getName());
+
+ private static final String s_name = "releasededicatedhostresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+ required=true, description="the ID of the host")
+ private Long hostId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getHostId() {
+ return hostId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ boolean result = dedicatedService.releaseDedicatedResource(null, null, null, getHostId());
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated Host");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "releasing dedicated host";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java
new file mode 100644
index 00000000000..d84ef66ef5a
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java
@@ -0,0 +1,91 @@
+// 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.commands;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "releaseDedicatedPod", description = "Release the dedication for the pod", responseObject = SuccessResponse.class)
+public class ReleaseDedicatedPodCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedPodCmd.class.getName());
+
+ private static final String s_name = "releasededicatedpodresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
+ required=true, description="the ID of the Pod")
+ private Long podId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ boolean result = dedicatedService.releaseDedicatedResource(null, getPodId(), null, null);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated pod");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "releasing dedicated pod";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java
new file mode 100644
index 00000000000..c78a4961dc8
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java
@@ -0,0 +1,91 @@
+// 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.commands;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.dedicated.DedicatedService;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "releaseDedicatedZone", description = "Release dedication of zone", responseObject = SuccessResponse.class)
+public class ReleaseDedicatedZoneCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedZoneCmd.class.getName());
+
+ private static final String s_name = "releasededicatedzoneresponse";
+ @Inject DedicatedService dedicatedService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType= ZoneResponse.class,
+ required=true, description="the ID of the Zone")
+ private Long zoneId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ boolean result = dedicatedService.releaseDedicatedResource(getZoneId(), null, null, null);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated zone");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "releasing dedicated zone";
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
new file mode 100644
index 00000000000..3c8dde3fd08
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
@@ -0,0 +1,79 @@
+// 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 org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class DedicateClusterResponse extends BaseResponse {
+ @SerializedName("id") @Param(description="the ID of the dedicated resource")
+ private String id;
+
+ @SerializedName("clusterid") @Param(description="the ID of the cluster")
+ private String clusterId;
+
+ @SerializedName("clustername") @Param(description="the name of the cluster")
+ private String clusterName;
+
+ @SerializedName("domainid") @Param(description="the domain ID of the cluster")
+ private String domainId;
+
+ @SerializedName("accountid") @Param(description="the Account ID of the cluster")
+ private String accountId;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getClusterId() {
+ return clusterId;
+ }
+
+ public void setClusterId(String clusterId) {
+ this.clusterId = clusterId;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getDomainId() {
+ return domainId;
+ }
+
+ public void setDomainId(String domainId) {
+ this.domainId = domainId;
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
new file mode 100644
index 00000000000..cea31fe392b
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
@@ -0,0 +1,79 @@
+// 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 org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class DedicateHostResponse extends BaseResponse {
+ @SerializedName("id") @Param(description="the ID of the dedicated resource")
+ private String id;
+
+ @SerializedName("hostid") @Param(description="the ID of the host")
+ private String hostId;
+
+ @SerializedName("hostname") @Param(description="the name of the host")
+ private String hostName;
+
+ @SerializedName("domainid") @Param(description="the domain ID of the host")
+ private String domainId;
+
+ @SerializedName("accountid") @Param(description="the Account ID of the host")
+ private String accountId;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getHostId() {
+ return hostId;
+ }
+
+ public void setHostId(String hostId) {
+ this.hostId = hostId;
+ }
+
+ public String getHostName() {
+ return hostName;
+ }
+
+ public void setHostName(String hostName) {
+ this.hostName = hostName;
+ }
+
+ public String getDomainId() {
+ return domainId;
+ }
+
+ public void setDomainId(String domainId) {
+ this.domainId = domainId;
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
new file mode 100644
index 00000000000..4bcaa61c269
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
@@ -0,0 +1,82 @@
+// 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 org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = DedicatedResources.class)
+public class DedicatePodResponse extends BaseResponse {
+ @SerializedName("id") @Param(description="the ID of the dedicated resource")
+ private String id;
+
+ @SerializedName("podid") @Param(description="the ID of the Pod")
+ private String podId;
+
+ @SerializedName("podname") @Param(description="the Name of the Pod")
+ private String podName;
+
+ @SerializedName("domainid") @Param(description="the domain ID to which the Pod is dedicated")
+ private String domainId;
+
+ @SerializedName("accountid") @Param(description="the Account Id to which the Pod is dedicated")
+ private String accountId;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getPodId() {
+ return podId;
+ }
+
+ public void setPodId(String podId) {
+ this.podId = podId;
+ }
+
+ public String getPodName() {
+ return podName;
+ }
+
+ public void setPodName(String podName) {
+ this.podName = podName;
+ }
+
+ public String getDomainId() {
+ return domainId;
+ }
+
+ public void setDomainId(String domainId) {
+ this.domainId = domainId;
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
new file mode 100644
index 00000000000..57497cd3484
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
@@ -0,0 +1,83 @@
+// 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 org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.dc.DedicatedResources;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = DedicatedResources.class)
+public class DedicateZoneResponse extends BaseResponse {
+ @SerializedName("id") @Param(description="the ID of the dedicated resource")
+ private String id;
+
+ @SerializedName("zoneid") @Param(description="the ID of the Zone")
+ private String zoneId;
+
+ @SerializedName("zonename") @Param(description="the Name of the Zone")
+ private String zoneName;
+
+ @SerializedName("domainid") @Param(description="the domain ID to which the Zone is dedicated")
+ private String domainId;
+
+ @SerializedName("accountid") @Param(description="the Account Id to which the Zone is dedicated")
+ private String accountId;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getZoneId() {
+ return zoneId;
+ }
+
+ public void setZoneId(String zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ public String getZoneName() {
+ return zoneName;
+ }
+
+ public void setZoneName(String zoneName) {
+ this.zoneName = zoneName;
+ }
+
+ public String getDomainId() {
+ return domainId;
+ }
+
+ public void setDomainId(String domainId) {
+ this.domainId = domainId;
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
new file mode 100755
index 00000000000..c321b22176e
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
@@ -0,0 +1,815 @@
+// 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.dedicated;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.component.AdapterBase;
+import org.apache.cloudstack.api.commands.DedicateClusterCmd;
+import org.apache.cloudstack.api.commands.DedicateHostCmd;
+import org.apache.cloudstack.api.commands.DedicatePodCmd;
+import org.apache.cloudstack.api.commands.DedicateZoneCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedClustersCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedHostsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedPodsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedZonesCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedClusterCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedHostCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedPodCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedZoneCmd;
+import org.apache.cloudstack.api.response.DedicateClusterResponse;
+import org.apache.cloudstack.api.response.DedicateHostResponse;
+import org.apache.cloudstack.api.response.DedicatePodResponse;
+import org.apache.cloudstack.api.response.DedicateZoneResponse;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.UserContext;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+
+@Component
+@Local({DedicatedService.class })
+public class DedicatedResourceManagerImpl implements DedicatedService {
+ private static final Logger s_logger = Logger.getLogger(DedicatedResourceManagerImpl.class);
+
+ @Inject AccountDao _accountDao;
+ @Inject DomainDao _domainDao;
+ @Inject HostPodDao _podDao;
+ @Inject ClusterDao _clusterDao;
+ @Inject HostDao _hostDao;
+ @Inject DedicatedResourceDao _dedicatedDao;
+ @Inject DataCenterDao _zoneDao;
+ @Inject AccountManager _accountMgr;
+ @Inject UserVmDao _userVmDao;
+ @Inject ConfigurationDao _configDao;
+
+ private int capacityReleaseInterval;
+
+ public boolean configure(final String name, final Map params) throws ConfigurationException {
+ capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+ return true;
+ }
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone")
+ public List dedicateZone(Long zoneId, Long domainId, String accountName) {
+ Long accountId = null;
+ List hosts = null;
+ if(accountName != null){
+ Account caller = UserContext.current().getCaller();
+ Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+ accountId = owner.getId();
+ }
+ List childDomainIds = getDomainChildIds(domainId);
+ childDomainIds.add(domainId);
+ checkAccountAndDomain(accountId, domainId);
+ DataCenterVO dc = _zoneDao.findById(zoneId);
+ if (dc == null) {
+ throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+ } else {
+ DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zoneId);
+ //check if zone is dedicated
+ if(dedicatedZone != null) {
+ s_logger.error("Zone " + dc.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Zone " + dc.getName() + " is already dedicated");
+ }
+
+ //check if any resource under this zone is dedicated to different account or sub-domain
+ List pods = _podDao.listByDataCenterId(dc.getId());
+ List podsToRelease = new ArrayList();
+ List clustersToRelease = new ArrayList();
+ List hostsToRelease = new ArrayList();
+ for (HostPodVO pod : pods) {
+ DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
+ if (dPod != null) {
+ if(!(childDomainIds.contains(dPod.getDomainId()))) {
+ throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ if (accountId != null) {
+ if (dPod.getAccountId() == accountId) {
+ podsToRelease.add(dPod);
+ } else {
+ s_logger.error("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ } else {
+ if (dPod.getAccountId() == null && dPod.getDomainId() == domainId) {
+ podsToRelease.add(dPod);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : podsToRelease) {
+ releaseDedicatedResource(null, dr.getPodId(), null, null);
+ }
+
+ List clusters = _clusterDao.listClustersByDcId(dc.getId());
+ for (ClusterVO cluster : clusters) {
+ DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
+ if (dCluster != null) {
+ if(!(childDomainIds.contains(dCluster.getDomainId()))) {
+ throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ if (accountId != null) {
+ if (dCluster.getAccountId() == accountId) {
+ clustersToRelease.add(dCluster);
+ } else {
+ s_logger.error("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ } else {
+ if (dCluster.getAccountId() == null && dCluster.getDomainId() == domainId) {
+ clustersToRelease.add(dCluster);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : clustersToRelease) {
+ releaseDedicatedResource(null, null, dr.getClusterId(), null);
+ }
+
+ hosts = _hostDao.listByDataCenterId(dc.getId());
+ for (HostVO host : hosts) {
+ DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+ if (dHost != null) {
+ if(!(childDomainIds.contains(dHost.getDomainId()))) {
+ throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ if (accountId != null) {
+ if (dHost.getAccountId() == accountId) {
+ hostsToRelease.add(dHost);
+ } else {
+ s_logger.error("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+ }
+ } else {
+ if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
+ hostsToRelease.add(dHost);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : hostsToRelease) {
+ releaseDedicatedResource(null, null, null, dr.getHostId());
+ }
+ }
+
+ checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null);
+ try {
+ dedicatedResource.setDomainId(domainId);
+ if (accountId != null) {
+ dedicatedResource.setAccountId(accountId);
+ }
+ dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+ } catch (Exception e) {
+ s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e);
+ throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+ }
+ txn.commit();
+
+ List result = new ArrayList();
+ result.add(dedicatedResource);
+ return result;
+ }
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Pod")
+ public List dedicatePod(Long podId, Long domainId, String accountName) {
+ Long accountId = null;
+ if(accountName != null){
+ Account caller = UserContext.current().getCaller();
+ Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+ accountId = owner.getId();
+ }
+ List childDomainIds = getDomainChildIds(domainId);
+ childDomainIds.add(domainId);
+ checkAccountAndDomain(accountId, domainId);
+ HostPodVO pod = _podDao.findById(podId);
+ List hosts = null;
+ if (pod == null) {
+ throw new InvalidParameterValueException("Unable to find pod by id " + podId);
+ } else {
+ DedicatedResourceVO dedicatedPod = _dedicatedDao.findByPodId(podId);
+ DedicatedResourceVO dedicatedZoneOfPod = _dedicatedDao.findByZoneId(pod.getDataCenterId());
+ //check if pod is dedicated
+ if(dedicatedPod != null ) {
+ s_logger.error("Pod " + pod.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Pod " + pod.getName() + " is already dedicated");
+ }
+
+ if (dedicatedZoneOfPod != null) {
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfPod.getDomainId()).contains(domainId);
+ //can dedicate a pod to an account/domain if zone is dedicated to parent-domain
+ if (dedicatedZoneOfPod.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedZoneOfPod.getDomainId() == domainId || domainIdInChildreanList))) {
+ DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId());
+ s_logger.error("Cannot dedicate Pod. Its zone is already dedicated");
+ throw new CloudRuntimeException("Pod's Zone " + zone.getName() + " is already dedicated");
+ }
+ }
+
+ //check if any resource under this pod is dedicated to different account or sub-domain
+ List clusters = _clusterDao.listByPodId(pod.getId());
+ List clustersToRelease = new ArrayList();
+ List hostsToRelease = new ArrayList();
+ for (ClusterVO cluster : clusters) {
+ DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
+ if (dCluster != null) {
+ if(!(childDomainIds.contains(dCluster.getDomainId()))) {
+ throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ }
+ /*if all dedicated resources belongs to same account and domain then we should release dedication
+ and make new entry for this Pod*/
+ if (accountId != null) {
+ if (dCluster.getAccountId() == accountId) {
+ clustersToRelease.add(dCluster);
+ } else {
+ s_logger.error("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ }
+ } else {
+ if (dCluster.getAccountId() == null && dCluster.getDomainId() == domainId) {
+ clustersToRelease.add(dCluster);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : clustersToRelease) {
+ releaseDedicatedResource(null, null, dr.getClusterId(), null);
+ }
+
+ hosts = _hostDao.findByPodId(pod.getId());
+ for (HostVO host : hosts) {
+ DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+ if (dHost != null) {
+ if(!(getDomainChildIds(domainId).contains(dHost.getDomainId()))) {
+ throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ }
+ if (accountId != null) {
+ if (dHost.getAccountId() == accountId) {
+ hostsToRelease.add(dHost);
+ } else {
+ s_logger.error("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+ }
+ } else {
+ if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
+ hostsToRelease.add(dHost);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : hostsToRelease) {
+ releaseDedicatedResource(null, null, null, dr.getHostId());
+ }
+ }
+
+ checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null);
+ try {
+ dedicatedResource.setDomainId(domainId);
+ if (accountId != null) {
+ dedicatedResource.setAccountId(accountId);
+ }
+ dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+ } catch (Exception e) {
+ s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e);
+ throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support.");
+ }
+ txn.commit();
+
+ List result = new ArrayList();
+ result.add(dedicatedResource);
+ return result;
+ }
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Cluster")
+ public List dedicateCluster(Long clusterId, Long domainId, String accountName) {
+ Long accountId = null;
+ List hosts = null;
+ if(accountName != null){
+ Account caller = UserContext.current().getCaller();
+ Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+ accountId = owner.getId();
+ }
+ List childDomainIds = getDomainChildIds(domainId);
+ childDomainIds.add(domainId);
+ checkAccountAndDomain(accountId, domainId);
+ ClusterVO cluster = _clusterDao.findById(clusterId);
+ if (cluster == null) {
+ throw new InvalidParameterValueException("Unable to find cluster by id " + clusterId);
+ } else {
+ DedicatedResourceVO dedicatedCluster = _dedicatedDao.findByClusterId(clusterId);
+ DedicatedResourceVO dedicatedPodOfCluster = _dedicatedDao.findByPodId(cluster.getPodId());
+ DedicatedResourceVO dedicatedZoneOfCluster = _dedicatedDao.findByZoneId(cluster.getDataCenterId());
+
+ //check if cluster is dedicated
+ if(dedicatedCluster != null) {
+ s_logger.error("Cluster " + cluster.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Cluster "+ cluster.getName() + " is already dedicated");
+ }
+
+ if (dedicatedPodOfCluster != null) {
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfCluster.getDomainId()).contains(domainId);
+ //can dedicate a cluster to an account/domain if pod is dedicated to parent-domain
+ if (dedicatedPodOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedPodOfCluster.getDomainId() == domainId || domainIdInChildreanList))) {
+ s_logger.error("Cannot dedicate Cluster. Its Pod is already dedicated");
+ HostPodVO pod = _podDao.findById(cluster.getPodId());
+ throw new CloudRuntimeException("Cluster's Pod " + pod.getName() + " is already dedicated");
+ }
+ }
+
+ if (dedicatedZoneOfCluster != null) {
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfCluster.getDomainId()).contains(domainId);
+ //can dedicate a cluster to an account/domain if zone is dedicated to parent-domain
+ if (dedicatedZoneOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedZoneOfCluster.getDomainId() == domainId || domainIdInChildreanList))) {
+ s_logger.error("Cannot dedicate Cluster. Its zone is already dedicated");
+ DataCenterVO zone = _zoneDao.findById(cluster.getDataCenterId());
+ throw new CloudRuntimeException("Cluster's Zone "+ zone.getName() + " is already dedicated");
+ }
+ }
+
+ //check if any resource under this cluster is dedicated to different account or sub-domain
+ hosts = _hostDao.findByClusterId(cluster.getId());
+ List hostsToRelease = new ArrayList();
+ for (HostVO host : hosts) {
+ DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+ if (dHost != null) {
+ if(!(childDomainIds.contains(dHost.getDomainId()))) {
+ throw new CloudRuntimeException("Host " + host.getName() + " under this Cluster " + cluster.getName() + " is dedicated to different account/domain");
+ }
+ /*if all dedicated resources belongs to same account and domain then we should release dedication
+ and make new entry for this cluster */
+ if (accountId != null) {
+ if (dHost.getAccountId() == accountId) {
+ hostsToRelease.add(dHost);
+ } else {
+ s_logger.error("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
+ throw new CloudRuntimeException("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
+ }
+ } else {
+ if (dHost.getAccountId() == null && dHost.getDomainId() == domainId) {
+ hostsToRelease.add(dHost);
+ }
+ }
+ }
+ }
+
+ for (DedicatedResourceVO dr : hostsToRelease) {
+ releaseDedicatedResource(null, null, null, dr.getHostId());
+ }
+ }
+
+ checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null);
+ try {
+ dedicatedResource.setDomainId(domainId);
+ if (accountId != null) {
+ dedicatedResource.setAccountId(accountId);
+ }
+ dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+ } catch (Exception e) {
+ s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
+ throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support.");
+ }
+ txn.commit();
+
+ List result = new ArrayList();
+ result.add(dedicatedResource);
+ return result;
+ }
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Host")
+ public List dedicateHost(Long hostId, Long domainId, String accountName) {
+ Long accountId = null;
+ if(accountName != null){
+ Account caller = UserContext.current().getCaller();
+ Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+ accountId = owner.getId();
+ }
+ checkAccountAndDomain(accountId, domainId);
+ HostVO host = _hostDao.findById(hostId);
+ if (host == null) {
+ throw new InvalidParameterValueException("Unable to find host by id " + hostId);
+ } else {
+ //check if host is of routing type
+ if (host.getType() != Host.Type.Routing) {
+ throw new CloudRuntimeException("Invalid host type for host " + host.getName());
+ }
+
+ DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+ DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+ DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+ DedicatedResourceVO dedicatedZoneOfHost = _dedicatedDao.findByZoneId(host.getDataCenterId());
+
+ if(dedicatedHost != null) {
+ s_logger.error("Host "+ host.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Host "+ host.getName() + " is already dedicated");
+ }
+
+ if (dedicatedClusterOfHost != null) {
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedClusterOfHost.getDomainId()).contains(domainId);
+ //can dedicate a host to an account/domain if cluster is dedicated to parent-domain
+ if (dedicatedClusterOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedClusterOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
+ ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+ s_logger.error("Host's Cluster " + cluster.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Host's Cluster " + cluster.getName() + " is already dedicated");
+ }
+ }
+
+ if (dedicatedPodOfHost != null){
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfHost.getDomainId()).contains(domainId);
+ //can dedicate a host to an account/domain if pod is dedicated to parent-domain
+ if (dedicatedPodOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedPodOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
+ HostPodVO pod = _podDao.findById(host.getPodId());
+ s_logger.error("Host's Pod " + pod.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Host's Pod " + pod.getName() + " is already dedicated");
+ }
+ }
+
+ if (dedicatedZoneOfHost != null) {
+ boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfHost.getDomainId()).contains(domainId);
+ //can dedicate a host to an account/domain if zone is dedicated to parent-domain
+ if (dedicatedZoneOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList)
+ || (accountId != null && !(dedicatedZoneOfHost.getDomainId() == domainId || domainIdInChildreanList))) {
+ DataCenterVO zone = _zoneDao.findById(host.getDataCenterId());
+ s_logger.error("Host's Data Center " + zone.getName() + " is already dedicated");
+ throw new CloudRuntimeException("Host's Data Center " + zone.getName() + " is already dedicated");
+ }
+ }
+ }
+
+ List childDomainIds = getDomainChildIds(domainId);
+ childDomainIds.add(domainId);
+ checkHostSuitabilityForExplicitDedication(accountId, childDomainIds, hostId);
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null);
+ try {
+ dedicatedResource.setDomainId(domainId);
+ if (accountId != null) {
+ dedicatedResource.setAccountId(accountId);
+ }
+ dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+ } catch (Exception e) {
+ s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
+ throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support.");
+ }
+ txn.commit();
+
+ List result = new ArrayList();
+ result.add(dedicatedResource);
+ return result;
+ }
+
+ private List getVmsOnHost(long hostId) {
+ List vms = _userVmDao.listUpByHostId(hostId);
+ List vmsByLastHostId = _userVmDao.listByLastHostId(hostId);
+ if (vmsByLastHostId.size() > 0) {
+ // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
+ for (UserVmVO stoppedVM : vmsByLastHostId) {
+ long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
+ .getTime()) / 1000;
+ if (secondsSinceLastUpdate < capacityReleaseInterval) {
+ vms.add(stoppedVM);
+ }
+ }
+ }
+
+ return vms;
+ }
+
+ private boolean checkHostSuitabilityForExplicitDedication(Long accountId, List domainIds, long hostId) {
+ boolean suitable = true;
+ List allVmsOnHost = getVmsOnHost(hostId);
+ if (accountId != null) {
+ for (UserVmVO vm : allVmsOnHost) {
+ if (vm.getAccountId() != accountId) {
+ s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " +
+ "running instances of another account");
+ throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
+ "running instances of another account");
+ }
+ }
+ } else {
+ for (UserVmVO vm : allVmsOnHost) {
+ if (!domainIds.contains(vm.getDomainId())) {
+ s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " +
+ "running instances of another domain");
+ throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
+ "running instances of another domain");
+ }
+ }
+ }
+ return suitable;
+ }
+
+ private boolean checkHostsSuitabilityForExplicitDedication(Long accountId, List domainIds, List hosts) {
+ boolean suitable = true;
+ for (HostVO host : hosts){
+ checkHostSuitabilityForExplicitDedication(accountId, domainIds, host.getId());
+ }
+ return suitable;
+ }
+
+ private void checkAccountAndDomain(Long accountId, Long domainId) {
+ DomainVO domain = _domainDao.findById(domainId);
+ if (domain == null) {
+ throw new InvalidParameterValueException("Unable to find the domain by id " + domainId + ", please specify valid domainId");
+ }
+ //check if account belongs to the domain id
+ if (accountId != null) {
+ AccountVO account = _accountDao.findById(accountId);
+ if (account == null || domainId != account.getDomainId()){
+ throw new InvalidParameterValueException("Please specify the domain id of the account: " + account.getAccountName());
+ }
+ }
+ }
+
+ private List getDomainChildIds(long domainId) {
+ DomainVO domainRecord = _domainDao.findById(domainId);
+ List domainIds = new ArrayList();
+ domainIds.add(domainRecord.getId());
+ // find all domain Ids till leaf
+ List allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
+ for (DomainVO domain : allChildDomains) {
+ domainIds.add(domain.getId());
+ }
+ return domainIds;
+ }
+
+ @Override
+ public DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource) {
+ DedicateZoneResponse dedicateZoneResponse = new DedicateZoneResponse();
+ DataCenterVO dc = _zoneDao.findById(resource.getDataCenterId());
+ DomainVO domain = _domainDao.findById(resource.getDomainId());
+ AccountVO account = _accountDao.findById(resource.getAccountId());
+ dedicateZoneResponse.setId(resource.getUuid());
+ dedicateZoneResponse.setZoneId(dc.getUuid());
+ dedicateZoneResponse.setZoneName(dc.getName());
+ dedicateZoneResponse.setDomainId(domain.getUuid());
+ if (account != null) {
+ dedicateZoneResponse.setAccountId(account.getUuid());
+ }
+ dedicateZoneResponse.setObjectName("dedicatedzone");
+ return dedicateZoneResponse;
+ }
+
+ @Override
+ public DedicatePodResponse createDedicatePodResponse(DedicatedResources resource) {
+ DedicatePodResponse dedicatePodResponse = new DedicatePodResponse();
+ HostPodVO pod = _podDao.findById(resource.getPodId());
+ DomainVO domain = _domainDao.findById(resource.getDomainId());
+ AccountVO account = _accountDao.findById(resource.getAccountId());
+ dedicatePodResponse.setId(resource.getUuid());
+ dedicatePodResponse.setPodId(pod.getUuid());
+ dedicatePodResponse.setPodName(pod.getName());
+ dedicatePodResponse.setDomainId(domain.getUuid());
+ if (account != null) {
+ dedicatePodResponse.setAccountId(account.getUuid());
+ }
+ dedicatePodResponse.setObjectName("dedicatedpod");
+ return dedicatePodResponse;
+ }
+
+ @Override
+ public DedicateClusterResponse createDedicateClusterResponse(DedicatedResources resource) {
+ DedicateClusterResponse dedicateClusterResponse = new DedicateClusterResponse();
+ ClusterVO cluster = _clusterDao.findById(resource.getClusterId());
+ DomainVO domain = _domainDao.findById(resource.getDomainId());
+ AccountVO account = _accountDao.findById(resource.getAccountId());
+ dedicateClusterResponse.setId(resource.getUuid());
+ dedicateClusterResponse.setClusterId(cluster.getUuid());
+ dedicateClusterResponse.setClusterName(cluster.getName());
+ dedicateClusterResponse.setDomainId(domain.getUuid());
+ if (account != null) {
+ dedicateClusterResponse.setAccountId(account.getUuid());
+ }
+ dedicateClusterResponse.setObjectName("dedicatedcluster");
+ return dedicateClusterResponse;
+ }
+
+ @Override
+ public DedicateHostResponse createDedicateHostResponse(DedicatedResources resource) {
+ DedicateHostResponse dedicateHostResponse = new DedicateHostResponse();
+ HostVO host = _hostDao.findById(resource.getHostId());
+ DomainVO domain = _domainDao.findById(resource.getDomainId());
+ AccountVO account = _accountDao.findById(resource.getAccountId());
+ dedicateHostResponse.setId(resource.getUuid());
+ dedicateHostResponse.setHostId(host.getUuid());
+ dedicateHostResponse.setHostName(host.getName());
+ dedicateHostResponse.setDomainId(domain.getUuid());
+ if (account != null) {
+ dedicateHostResponse.setAccountId(account.getUuid());
+ }
+ dedicateHostResponse.setObjectName("dedicatedhost");
+ return dedicateHostResponse;
+ }
+
+ @Override
+ public List> getCommands() {
+ List> cmdList = new ArrayList>();
+ cmdList.add(DedicateZoneCmd.class);
+ cmdList.add(DedicatePodCmd.class);
+ cmdList.add(DedicateClusterCmd.class);
+ cmdList.add(DedicateHostCmd.class);
+ cmdList.add(ListDedicatedZonesCmd.class);
+ cmdList.add(ListDedicatedPodsCmd.class);
+ cmdList.add(ListDedicatedClustersCmd.class);
+ cmdList.add(ListDedicatedHostsCmd.class);
+ cmdList.add(ReleaseDedicatedClusterCmd.class);
+ cmdList.add(ReleaseDedicatedHostCmd.class);
+ cmdList.add(ReleaseDedicatedPodCmd.class);
+ cmdList.add(ReleaseDedicatedZoneCmd.class);
+ return cmdList;
+ }
+
+ @Override
+ public Pair, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd) {
+ Long zoneId = cmd.getZoneId();
+ Long domainId = cmd.getDomainId();
+ String accountName = cmd.getAccountName();
+ Long accountId = null;
+ if (accountName != null) {
+ if (domainId != null) {
+ Account account = _accountDao.findActiveAccount(accountName, domainId);
+ if (account != null) {
+ accountId = account.getId();
+ }
+ } else {
+ throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+ }
+ }
+ Pair, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId, accountId);
+ return new Pair, Integer>(result.first(), result.second());
+ }
+
+ @Override
+ public Pair, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd) {
+ Long podId = cmd.getPodId();
+ Long domainId = cmd.getDomainId();
+ String accountName = cmd.getAccountName();
+ Long accountId = null;
+ if (accountName != null) {
+ if (domainId != null) {
+ Account account = _accountDao.findActiveAccount(accountName, domainId);
+ if (account != null) {
+ accountId = account.getId();
+ }
+ } else {
+ throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+ }
+ }
+ Pair, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId);
+ return new Pair, Integer>(result.first(), result.second());
+ }
+
+ @Override
+ public Pair, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd) {
+ Long clusterId = cmd.getClusterId();
+ Long domainId = cmd.getDomainId();
+ String accountName = cmd.getAccountName();
+ Long accountId = null;
+ if (accountName != null) {
+ if (domainId != null) {
+ Account account = _accountDao.findActiveAccount(accountName, domainId);
+ if (account != null) {
+ accountId = account.getId();
+ }
+ } else {
+ throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+ }
+ }
+ Pair, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId, accountId);
+ return new Pair, Integer>(result.first(), result.second());
+ }
+
+ @Override
+ public Pair, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd) {
+ Long hostId = cmd.getHostId();
+ Long domainId = cmd.getDomainId();
+ String accountName = cmd.getAccountName();
+ Long accountId = null;
+ if (accountName != null) {
+ if (domainId != null) {
+ Account account = _accountDao.findActiveAccount(accountName, domainId);
+ if (account != null) {
+ accountId = account.getId();
+ }
+ } else {
+ throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+ }
+ }
+
+ Pair, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId);
+ return new Pair, Integer>(result.first(), result.second());
+ }
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE, eventDescription = "Releasing dedicated resource")
+ public boolean releaseDedicatedResource(Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException{
+ DedicatedResourceVO resource = null;
+ Long resourceId = null;
+ if (zoneId != null) {
+ resource = _dedicatedDao.findByZoneId(zoneId);
+ }
+ if (podId != null) {
+ resource = _dedicatedDao.findByPodId(podId);
+ }
+ if (clusterId != null) {
+ resource = _dedicatedDao.findByClusterId(clusterId);
+ }
+ if (hostId != null ) {
+ resource = _dedicatedDao.findByHostId(hostId);
+ }
+ if (resource == null){
+ throw new InvalidParameterValueException("No Dedicated Resource available to release");
+ } else {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ resourceId = resource.getId();
+ if (!_dedicatedDao.remove(resourceId)) {
+ throw new CloudRuntimeException("Failed to delete Resource " + resourceId);
+ }
+ txn.commit();
+ }
+ return true;
+ }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedService.java b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedService.java
new file mode 100755
index 00000000000..6f26ad62f84
--- /dev/null
+++ b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedService.java
@@ -0,0 +1,63 @@
+// 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.dedicated;
+
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.PluggableService;
+import org.apache.cloudstack.api.commands.ListDedicatedClustersCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedHostsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedPodsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedZonesCmd;
+import org.apache.cloudstack.api.response.DedicateClusterResponse;
+import org.apache.cloudstack.api.response.DedicateHostResponse;
+import org.apache.cloudstack.api.response.DedicatePodResponse;
+import org.apache.cloudstack.api.response.DedicateZoneResponse;
+
+import java.util.List;
+
+public interface DedicatedService extends PluggableService {
+
+ DedicatePodResponse createDedicatePodResponse(DedicatedResources resource);
+
+ DedicateClusterResponse createDedicateClusterResponse(
+ DedicatedResources resource);
+
+ DedicateHostResponse createDedicateHostResponse(DedicatedResources resource);
+
+ Pair, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd);
+
+ Pair, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd);
+
+ Pair, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd);
+
+ boolean releaseDedicatedResource(Long zoneId, Long podId, Long clusterId, Long hostId);
+
+ DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource);
+
+ Pair, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd);
+
+ List dedicateZone(Long zoneId, Long domainId, String accountName);
+
+ List dedicatePod(Long podId, Long domainId, String accountName);
+
+ List dedicateCluster(Long clusterId, Long domainId, String accountName);
+
+ List dedicateHost(Long hostId, Long domainId, String accountName);
+
+}
diff --git a/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java b/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
new file mode 100644
index 00000000000..58aae238d88
--- /dev/null
+++ b/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
@@ -0,0 +1,317 @@
+// 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.dedicated.manager;
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+
+import org.apache.cloudstack.dedicated.DedicatedResourceManagerImpl;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.UserContext;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.dao.UserVmDao;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class DedicatedApiUnitTest {
+ public static final Logger s_logger = Logger.getLogger(DedicatedApiUnitTest.class);
+ @Inject
+ DedicatedResourceManagerImpl _dedicatedService = new DedicatedResourceManagerImpl();
+
+ @Inject
+ AccountManager _acctMgr;
+
+ @Inject
+ AccountDao _accountDao;
+
+ @Inject
+ DomainDao _domainDao;
+
+ @Inject
+ UserVmDao _vmDao;
+
+ @Inject
+ DedicatedResourceDao _dedicatedDao;
+
+ @Inject
+ DataCenterDao _dcDao;
+
+ @Inject
+ HostPodDao _podDao;
+
+ @Inject
+ ClusterDao _clusterDao;
+
+ @Inject
+ HostDao _hostDao;
+
+ @Inject
+ ConfigurationDao _configDao;
+
+ private static long domainId = 5L;
+ private static long accountId = 5L;
+ private static String accountName = "admin";
+
+ @BeforeClass
+ public static void setUp() throws ConfigurationException {
+
+ }
+
+ @Before
+ public void testSetUp() {
+ ComponentContext.initComponentsLifeCycle();
+ AccountVO account = new AccountVO(accountName, domainId, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
+ DomainVO domain = new DomainVO("rootDomain", 5L, 5L, "networkDomain");
+
+ UserContext.registerContext(1, account, null, true);
+ when(_acctMgr.finalizeOwner((Account) anyObject(), anyString(), anyLong(), anyLong())).thenReturn(account);
+ when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(account);
+ when(_accountDao.findById(anyLong())).thenReturn(account);
+ when(_domainDao.findById(domainId)).thenReturn(domain);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void InvalidDomainIDForAccountTest() {
+ _dedicatedService.dedicateZone(10L, domainId, accountName);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void dedicateResourceInvalidAccountIDTest() {
+ _dedicatedService.dedicateZone(10L, domainId, accountName);
+ }
+
+ @Test
+ public void releaseDedicatedZoneInvalidIdTest() {
+ when(_dedicatedDao.findByZoneId(10L)).thenReturn(null);
+ try {
+ _dedicatedService.releaseDedicatedResource(10L, null, null, null);
+ } catch (InvalidParameterValueException e) {
+ Assert.assertTrue(e.getMessage().contains(
+ "No Dedicated Resource available to release"));
+ }
+ }
+
+/* @Test
+ public void runDedicateZoneTest() {
+ DataCenterVO dc = new DataCenterVO(10L, "TestZone", "Dedicated",
+ "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null,
+ NetworkType.Basic, null, null);
+ when(_dcDao.findById(10L)).thenReturn(dc);
+ try {
+ List result = _dedicatedService.dedicateZone(10L, domainId, accountName);
+ Assert.assertNotNull(result);
+ } catch (Exception e) {
+ s_logger.info("exception in testing dedication of zone "
+ + e.toString());
+ }
+ }
+
+ @Test
+ public void runDedicatePodTest() {
+ HostPodVO pod = new HostPodVO("TestPod", 20L, "10.0.0.1", "10.0.0.0",
+ 22, null);
+ when(_podDao.findById(10L)).thenReturn(pod);
+ try {
+ List