Merge branch 'master' into object_store.

This commit is contained in:
Min Chen 2013-05-23 18:00:15 -07:00
commit 98af424053
241 changed files with 10606 additions and 3321 deletions

View File

@ -35,6 +35,7 @@ public interface AsyncJob extends Identity, InternalIdentity {
Host,
StoragePool,
IpAddress,
PortableIpAddress,
SecurityGroup,
PhysicalNetwork,
TrafficType,

View File

@ -39,6 +39,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
@ -56,6 +59,8 @@ import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
public interface ConfigurationService {
@ -278,4 +283,12 @@ public interface ConfigurationService {
* @return
*/
boolean isOfferingForVpc(NetworkOffering offering);
PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException;
boolean deletePortableIpRange(DeletePortableIpRangeCmd cmd);
List<? extends PortableIpRange> listPortableIpRanges(ListPortableIpRangesCmd cmd);
List<? extends PortableIp> listPortableIps(long id);
}

View File

@ -213,6 +213,13 @@ public interface DeploymentPlanner extends Adapter {
_hostIds.add(hostId);
}
public void addHostList(Collection<Long> hostList) {
if (_hostIds == null) {
_hostIds = new HashSet<Long>();
}
_hostIds.addAll(hostList);
}
public boolean shouldAvoid(Host host) {
if (_dcIds != null && _dcIds.contains(host.getDataCenterId())) {
return true;

View File

@ -92,6 +92,8 @@ public class EventTypes {
public static final String EVENT_PROXY_STOP = "PROXY.STOP";
public static final String EVENT_PROXY_REBOOT = "PROXY.REBOOT";
public static final String EVENT_PROXY_HA = "PROXY.HA";
public static final String EVENT_PROXY_SCALE = "PROXY.SCALE";
// VNC Console Events
public static final String EVENT_VNC_CONNECT = "VNC.CONNECT";
@ -100,6 +102,8 @@ public class EventTypes {
// Network Events
public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN";
public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE";
public static final String EVENT_PORTABLE_IP_ASSIGN = "PORTABLE.IPASSIGN";
public static final String EVENT_PORTABLE_IP_RELEASE = "PORTABLEIPRELEASE";
public static final String EVENT_NET_RULE_ADD = "NET.RULEADD";
public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE";
public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY";
@ -213,6 +217,7 @@ public class EventTypes {
public static final String EVENT_SSVM_STOP = "SSVM.STOP";
public static final String EVENT_SSVM_REBOOT = "SSVM.REBOOT";
public static final String EVENT_SSVM_HA = "SSVM.HA";
public static final String EVENT_SSVM_SCALE = "SSVM.SCALE";
// Service Offerings
public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE";
@ -429,6 +434,9 @@ public class EventTypes {
public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE";
public static final String EVENT_PORTABLE_IP_RANGE_CREATE = "PORTABLE.IP.RANGE.CREATE";
public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking

View File

@ -27,6 +27,8 @@ public class InsufficientServerCapacityException extends InsufficientCapacityExc
private static final long serialVersionUID = SerialVersionUID.InsufficientServerCapacityException;
private boolean affinityGroupsApplied = false;
public InsufficientServerCapacityException(String msg, Long clusterId) {
this(msg, Cluster.class, clusterId);
}
@ -34,4 +36,13 @@ public class InsufficientServerCapacityException extends InsufficientCapacityExc
public InsufficientServerCapacityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
public InsufficientServerCapacityException(String msg, Class<?> scope, Long id, boolean affinityGroupsApplied) {
super(msg, scope, id);
this.affinityGroupsApplied = affinityGroupsApplied;
}
public boolean isAffinityApplied() {
return affinityGroupsApplied;
}
}

View File

@ -82,6 +82,8 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity
String getVmIp();
boolean isPortable();
Long getNetworkId();
}

View File

@ -0,0 +1,70 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network;
import com.cloud.deploy.DeployDestination;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
/**
* NetworkGuru and NetworkElements that implement this interface
* will be called during Virtual Machine migration.
*/
public interface NetworkMigrationResponder {
/**
* Prepare for migration.
*
* This method will be called per nic before the vm migration.
* @param nic
* @param network
* @param vm
* @param dest
* @param context
* @return true when operation was successful.
*/
public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context);
/**
* Cancel for migration preparation.
*
* This method will be called per nic when the entire vm migration
* process failed and need to release the resouces that was
* allocated at the migration preparation.
* @param nic destination nic
* @param network destination network
* @param vm destination vm profile
* @param src The context nic migrates from.
* @param dst The context nic migrates to.
*/
public void rollbackMigration(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext src, ReservationContext dst);
/**
* Commit the migration resource.
*
* This method will be called per nic when the entire vm migration
* process was successful. This is useful to release the resource of
* source deployment where vm has left.
* @param nic source nic
* @param network source network
* @param vm source vm profile
* @param src the context nic migrates from.
* @param dst the context nic migrates to.
*/
public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext src, ReservationContext dst);
}

View File

@ -52,6 +52,11 @@ public interface NetworkService {
boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
InsufficientAddressCapacityException, ConcurrentOperationException;
boolean releasePortableIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceAllocationException;

View File

@ -32,7 +32,7 @@ public interface RemoteAccessVpnService {
RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, long networkId)
throws NetworkRuleConflictException;
void destroyRemoteAccessVpn(long vpnServerAddressId, Account caller) throws ResourceUnavailableException;
void destroyRemoteAccessVpnForIp(long vpnServerAddressId, Account caller) throws ResourceUnavailableException;
RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException;
VpnUser addVpnUser(long vpnOwnerId, String userName, String password);

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.cloud.exception.*;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
@ -34,11 +35,7 @@ import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
import org.apache.cloudstack.api.command.admin.systemvm.DestroySystemVmCmd;
import org.apache.cloudstack.api.command.admin.systemvm.ListSystemVMsCmd;
import org.apache.cloudstack.api.command.admin.systemvm.RebootSystemVmCmd;
import org.apache.cloudstack.api.command.admin.systemvm.StopSystemVmCmd;
import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd;
import org.apache.cloudstack.api.command.admin.systemvm.*;
import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
@ -64,10 +61,6 @@ import com.cloud.configuration.Configuration;
import com.cloud.dc.Pod;
import com.cloud.dc.Vlan;
import com.cloud.domain.Domain;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InternalErrorException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorCapabilities;
@ -391,4 +384,5 @@ public interface ManagementService {
List<String> listDeploymentPlanners();
VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException, ConcurrentOperationException;
}

View File

@ -461,6 +461,6 @@ public interface UserVmService {
UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
boolean upgradeVirtualMachine(ScaleVMCmd scaleVMCmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
}

View File

@ -114,6 +114,7 @@ public class ApiConstants {
public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
public static final String IS_EXTRACTABLE = "isextractable";
public static final String IS_FEATURED = "isfeatured";
public static final String IS_PORTABLE = "isportable";
public static final String IS_PUBLIC = "ispublic";
public static final String IS_PERSISTENT = "ispersistent";
public static final String IS_READY = "isready";
@ -158,6 +159,7 @@ public class ApiConstants {
public static final String POLICY_ID = "policyid";
public static final String PORT = "port";
public static final String PORTAL = "portal";
public static final String PORTABLE_IP_ADDRESS = "portableipaddress";
public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid";
public static final String PRIVATE_INTERFACE = "privateinterface";
public static final String PRIVATE_IP = "privateip";
@ -312,6 +314,7 @@ public class ApiConstants {
public static final String ACCEPT = "accept";
public static final String SORT_KEY = "sortkey";
public static final String ACCOUNT_DETAILS = "accountdetails";
public static final String SERVICE_OFFERING_DETAILS = "serviceofferingdetails";
public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";

View File

@ -36,6 +36,8 @@ import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
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;
@ -363,7 +365,12 @@ public interface ResponseGenerator {
Long getAffinityGroupId(String name, long entityOwnerId);
PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange range);
PortableIpResponse createPortableIPResponse(PortableIp portableIp);
InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result);
IsolationMethodResponse createIsolationMethodResponse(IsolationType method);
}

View File

@ -17,13 +17,11 @@
package org.apache.cloudstack.api.command.admin.cluster;
import java.util.ArrayList;
import java.util.List;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException;
import org.apache.cloudstack.api.*;
import org.apache.log4j.Logger;
import com.cloud.exception.ResourceInUseException;
import com.cloud.org.Cluster;
import com.cloud.user.Account;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -36,10 +34,8 @@ import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.log4j.Logger;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.org.Cluster;
import com.cloud.user.Account;
import java.util.ArrayList;
import java.util.List;
@APICommand(name = "addCluster", description="Adds a new cluster", responseObject=ClusterResponse.class)
public class AddClusterCmd extends BaseCmd {
@ -86,10 +82,10 @@ public class AddClusterCmd extends BaseCmd {
private String vsmipaddress;
@Parameter (name=ApiConstants.CPU_OVERCOMMIT_RATIO, type = CommandType.STRING, required = false , description = "value of the cpu overcommit ratio, defaults to 1")
private String cpuovercommitRatio;
private String cpuOvercommitRatio;
@Parameter(name = ApiConstants.MEMORY_OVERCOMMIT_RATIO, type = CommandType.STRING, required = false ,description = "value of the default ram overcommit ratio, defaults to 1")
private String memoryovercommitratio;
@Parameter(name = ApiConstants.MEMORY_OVERCOMMIT_RATIO, type = CommandType.STRING, required = false, description = "value of the default memory overcommit ratio, defaults to 1")
private String memoryOvercommitRatio;
@Parameter(name = ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC, type = CommandType.STRING, required = false, description = "Type of virtual switch used for guest traffic in the cluster. Allowed values are, vmwaresvs (for VMware standard vSwitch) and vmwaredvs (for VMware distributed vSwitch)")
private String vSwitchTypeGuestTraffic;
@ -186,15 +182,15 @@ public class AddClusterCmd extends BaseCmd {
}
public Float getCpuOvercommitRatio (){
if(cpuovercommitRatio != null){
return Float.parseFloat(cpuovercommitRatio);
if(cpuOvercommitRatio != null){
return Float.parseFloat(cpuOvercommitRatio);
}
return 1.0f;
}
public Float getMemoryOvercommitRaito (){
if (memoryovercommitratio != null){
return Float.parseFloat(memoryovercommitratio);
public Float getMemoryOvercommitRatio(){
if (memoryOvercommitRatio != null){
return Float.parseFloat(memoryOvercommitRatio);
}
return 1.0f;
}
@ -202,8 +198,8 @@ public class AddClusterCmd extends BaseCmd {
@Override
public void execute(){
try {
if ((getMemoryOvercommitRaito().compareTo(1f) < 0) | (getCpuOvercommitRatio().compareTo(1f) < 0)) {
throw new InvalidParameterValueException("Cpu and ram overcommit ratios should not be less than 1");
if (getMemoryOvercommitRatio().compareTo(1f) < 0 || getCpuOvercommitRatio().compareTo(1f) < 0) {
throw new InvalidParameterValueException("cpu and memory overcommit ratios should be greater than or equal to one");
}
List<? extends Cluster> result = _resourceService.discoverCluster(this);
ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();

View File

@ -57,7 +57,7 @@ public class UpdateClusterCmd extends BaseCmd {
@Parameter(name=ApiConstants.CPU_OVERCOMMIT_RATIO, type = CommandType.STRING, description = "Value of cpu overcommit ratio")
private String cpuovercommitratio;
@Parameter(name=ApiConstants.MEMORY_OVERCOMMIT_RATIO, type = CommandType.STRING, description = "Value of ram overcommit ratio")
@Parameter(name=ApiConstants.MEMORY_OVERCOMMIT_RATIO, type = CommandType.STRING, description = "Value of memory overcommit ratio")
private String memoryovercommitratio;

View File

@ -45,7 +45,7 @@ public class FindHostsForMigrationCmd extends BaseListCmd {
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
required=false, description="find hosts to which this VM can be migrated and flag the hosts with enough " +
required=true, description="find hosts to which this VM can be migrated and flag the hosts with enough " +
"CPU/RAM to host the VM")
private Long virtualMachineId;

View File

@ -16,6 +16,9 @@
// under the License.
package org.apache.cloudstack.api.command.admin.offering;
import java.util.Collection;
import java.util.Map;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -87,6 +90,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
private String deploymentPlanner;
@Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
private Map<String, String> details;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -155,6 +161,16 @@ public class CreateServiceOfferingCmd extends BaseCmd {
return deploymentPlanner;
}
public Map<String, String> getDetails() {
if (details == null || details.isEmpty()) {
return null;
}
Collection<String> paramsCollection = details.values();
Map<String, String> params = (Map<String, String>)(paramsCollection.toArray())[0];
return params;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -0,0 +1,156 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import com.cloud.async.AsyncJob;
import com.cloud.dc.Vlan;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
@APICommand(name = "createPortableIpRange", responseObject=PortableIpRangeResponse.class, description="adds a range of portable public IP's to a region", since="4.2.0")
public class CreatePortableIpRangeCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreatePortableIpRangeCmd.class.getName());
private static final String s_name = "createportableiprangeresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, entityType = RegionResponse.class, required=true, description="Id of the Region")
private Integer regionId;
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the portable IP range")
private String startIp;
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, required=true, description="the ending IP address in the portable IP range")
private String endIp;
@Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway for the portable IP range")
private String gateway;
@Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the portable IP range")
private String netmask;
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="VLAN id, if not specified defaulted to untagged")
private String vlan;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Integer getRegionId() {
return regionId;
}
public String getStartIp() {
return startIp;
}
public String getEndIp() {
return endIp;
}
public String getVlan() {
return vlan;
}
public String getGateway() {
return gateway;
}
public String getNetmask() {
return netmask;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
PortableIpRange portableIpRange = _entityMgr.findById(PortableIpRange.class, getEntityId());
PortableIpRangeResponse response = null;
if (portableIpRange != null) {
response = _responseGenerator.createPortableIPRangeResponse(portableIpRange);
}
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public void create() throws ResourceAllocationException {
try {
PortableIpRange portableIpRange = _configService.createPortableIpRange(this);
if (portableIpRange != null) {
this.setEntityId(portableIpRange.getId());
this.setEntityUuid(portableIpRange.getUuid());
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create portable public IP range");
}
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE;
}
@Override
public String getEventDescription() {
return "creating a portable public ip range in region: " + getRegionId();
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.PortableIpAddress;
}
}

View File

@ -0,0 +1,93 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
@APICommand(name = "deletePortableIpRange", description="deletes a range of portable public IP's associated with a region", responseObject=SuccessResponse.class)
public class DeletePortableIpRangeCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeletePortableIpRangeCmd.class.getName());
private static final String s_name = "deleteportablepublicipresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, required=true, entityType = PortableIpRangeResponse.class, description="Id of the portable ip range")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = _configService.deletePortableIpRange(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete portable ip range");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_PORTABLE_IP_RANGE_DELETE;
}
@Override
public String getEventDescription() {
return "deleting a portable public ip range";
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.PortableIpAddress;
}
}

View File

@ -0,0 +1,109 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.PortableIpResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
import java.util.ArrayList;
import java.util.List;
@APICommand(name = "listPortableIpRanges", description="list portable IP ranges", responseObject=PortableIpRangeResponse.class)
public class ListPortableIpRangesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListPortableIpRangesCmd.class.getName());
private static final String s_name = "listportableipresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, required=false, description="Id of a Region")
private Integer regionId;
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, required=false, entityType = PortableIpRangeResponse.class, description="Id of the portable ip range")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Integer getRegionIdId() {
return regionId;
}
public Long getPortableIpRangeId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
ListResponse<PortableIpRangeResponse> response = new ListResponse<PortableIpRangeResponse>();
List<PortableIpRangeResponse> responses = new ArrayList<PortableIpRangeResponse>();
List<? extends PortableIpRange> portableIpRanges = new ArrayList<PortableIpRange>();
portableIpRanges = _configService.listPortableIpRanges(this);
if (portableIpRanges != null && !portableIpRanges.isEmpty()) {
for (PortableIpRange range : portableIpRanges) {
PortableIpRangeResponse rangeResponse = _responseGenerator.createPortableIPRangeResponse(range);
List<? extends PortableIp> portableIps = _configService.listPortableIps(range.getId());
if (portableIps != null && !portableIps.isEmpty()) {
List<PortableIpResponse> portableIpResponses = new ArrayList<PortableIpResponse>();
for (PortableIp portableIP: portableIps) {
PortableIpResponse portableIpresponse = _responseGenerator.createPortableIPResponse(portableIP);
portableIpResponses.add(portableIpresponse);
}
rangeResponse.setPortableIpResponses(portableIpResponses);
}
rangeResponse.setObjectName("portableiprange");
responses.add(rangeResponse);
}
}
response.setResponses(responses, portableIpRanges.size());
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,131 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.systemvm;
import com.cloud.event.EventTypes;
import com.cloud.exception.*;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.SystemVmResponse;
import org.apache.log4j.Logger;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.vm.VirtualMachine;
@APICommand(name = "scaleSystemVm", responseObject=SystemVmResponse.class, description="Scale the service offering for a system vm (console proxy or secondary storage). " +
"The system vm must be in a \"Stopped\" state for " +
"this command to take effect.")
public class ScaleSystemVMCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
private static final String s_name = "changeserviceforsystemvmresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=SystemVmResponse.class,
required=true, description="The ID of the system vm")
private Long id;
@Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
required=true, description="the service offering ID to apply to the system vm")
private Long serviceOfferingId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Long getServiceOfferingId() {
return serviceOfferingId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
Account account = UserContext.current().getCaller();
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public void execute(){
UserContext.current().setEventDetails("SystemVm Id: "+getId());
ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId);
if (serviceOffering == null) {
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
}
VirtualMachine result = null;
try {
result = _mgr.upgradeSystemVM(this);
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (ManagementServerException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (VirtualMachineMigrationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result != null) {
SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale system vm");
}
}
@Override
public String getEventType() {
VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
if(type == VirtualMachine.Type.ConsoleProxy){
return EventTypes.EVENT_PROXY_SCALE;
}
else{
return EventTypes.EVENT_SSVM_SCALE;
}
}
@Override
public String getEventDescription() {
return "scaling system vm: " + getId() + " to service offering: " + getServiceOfferingId();
}
}

View File

@ -66,6 +66,14 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
"be associated with")
private Long vpcId;
@Parameter(name=ApiConstants.IS_PORTABLE, type = BaseCmd.CommandType.BOOLEAN, description = "should be set to true " +
"if public IP is required to be transferable across zones, if not specified defaults to false")
private Boolean isPortable;
@Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, entityType = RegionResponse.class,
required=false, description="region ID from where portable ip is to be associated.")
private Integer regionId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -107,6 +115,18 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
return vpcId;
}
public boolean isPortable() {
if (isPortable == null) {
return false;
} else {
return isPortable;
}
}
public Integer getRegionId() {
return regionId;
}
public Long getNetworkId() {
if (vpcId != null) {
return null;
@ -196,7 +216,13 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
@Override
public void create() throws ResourceAllocationException{
try {
IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId());
IpAddress ip = null;
if (!isPortable()) {
ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId());
} else {
ip = _networkService.allocatePortableIP(_accountService.getAccount(getEntityOwnerId()), 1, getZoneId(), getNetworkId(), getVpcId());
}
if (ip != null) {
this.setEntityId(ip.getId());

View File

@ -74,7 +74,12 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
@Override
public void execute() throws InsufficientAddressCapacityException{
UserContext.current().setEventDetails("Ip Id: " + getIpAddressId());
boolean result = _networkService.releaseIpAddress(getIpAddressId());
boolean result = false;
if (!isPortable(id)) {
result = _networkService.releaseIpAddress(getIpAddressId());
} else {
result = _networkService.releaseIpAddress(getIpAddressId());
}
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
@ -139,4 +144,9 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
public Long getInstanceId() {
return getIpAddressId();
}
private boolean isPortable(long id) {
IpAddress ip = getIpAddress(id);
return ip.isPortable();
}
}

View File

@ -27,6 +27,7 @@ import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.IPAddressResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.LoadBalancerResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.log4j.Logger;
@ -63,6 +64,10 @@ public class ListLoadBalancerRulesCmd extends BaseListTaggedResourcesCmd {
description = "the availability zone ID")
private Long zoneId;
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
description = "list by network id the rule belongs to")
private Long networkId;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@ -87,6 +92,10 @@ public class ListLoadBalancerRulesCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public Long getNetworkId() {
return networkId;
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////

View File

@ -91,6 +91,12 @@ public class EnableStaticNatCmd extends BaseCmd{
} else {
ntwkId = networkId;
}
// in case of portable public IP, network ID passed takes precedence
if (ip.isPortable() && networkId != null ) {
ntwkId = networkId;
}
if (ntwkId == null) {
throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipAddressId +
" as ip is not associated with any network and no networkId is passed in");

View File

@ -51,6 +51,7 @@ import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
@ -424,9 +425,15 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (InsufficientCapacityException ex) {
StringBuilder message = new StringBuilder(ex.getMessage());
if (ex instanceof InsufficientServerCapacityException) {
if(((InsufficientServerCapacityException)ex).isAffinityApplied()){
message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
}
}
s_logger.info(ex);
s_logger.info(ex.getMessage(), ex);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
s_logger.info(message.toString(), ex);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
}
} else {
result = _userVmService.getUserVm(getEntityId());

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.vm;
import com.cloud.event.EventTypes;
import com.cloud.exception.*;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@ -26,9 +27,11 @@ import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.log4j.Logger;
import java.util.List;
@APICommand(name = "scaleVirtualMachine", description="Scales the virtual machine to a new service offering.", responseObject=SuccessResponse.class)
public class ScaleVMCmd extends BaseCmd {
public class ScaleVMCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
private static final String s_name = "scalevirtualmachineresponse";
@ -84,7 +87,7 @@ public class ScaleVMCmd extends BaseCmd {
@Override
public void execute(){
//UserContext.current().setEventDetails("Vm Id: "+getId());
boolean result;
UserVm result;
try {
result = _userVmService.upgradeVirtualMachine(this);
} catch (ResourceUnavailableException ex) {
@ -100,11 +103,23 @@ public class ScaleVMCmd extends BaseCmd {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result){
SuccessResponse response = new SuccessResponse(getCommandName());
if (result != null){
List<UserVmResponse> responseList = _responseGenerator.createUserVmResponse("virtualmachine", result);
UserVmResponse response = responseList.get(0);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_VM_SCALE;
}
@Override
public String getEventDescription() {
return "scaling volume: " + getId() + " to service offering: " + getServiceOfferingId();
}
}

View File

@ -30,10 +30,10 @@ import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@ -112,7 +112,7 @@ public class StartVMCmd extends BaseAsyncCmd {
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
public void execute() throws ResourceUnavailableException, ResourceAllocationException {
try {
UserContext.current().setEventDetails("Vm Id: " + getId());
@ -135,6 +135,16 @@ public class StartVMCmd extends BaseAsyncCmd {
} catch (ExecutionException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (InsufficientCapacityException ex) {
StringBuilder message = new StringBuilder(ex.getMessage());
if (ex instanceof InsufficientServerCapacityException) {
if (((InsufficientServerCapacityException) ex).isAffinityApplied()) {
message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
}
}
s_logger.info(ex);
s_logger.info(message.toString(), ex);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
}
}

View File

@ -84,7 +84,7 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd {
@Override
public void execute() throws ResourceUnavailableException {
_ravService.destroyRemoteAccessVpn(publicIpId, UserContext.current().getCaller());
_ravService.destroyRemoteAccessVpnForIp(publicIpId, UserContext.current().getCaller());
}
@Override

View File

@ -16,16 +16,15 @@
// under the License.
package org.apache.cloudstack.api.response;
import java.util.ArrayList;
import java.util.List;
import com.cloud.org.Cluster;
import com.cloud.serializer.Param;
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 com.cloud.org.Cluster;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
@EntityReference(value = Cluster.class)
public class ClusterResponse extends BaseResponse {
@ -68,7 +67,7 @@ public class ClusterResponse extends BaseResponse {
@SerializedName("cpuovercommitratio") @Param(description = "The cpu overcommit ratio of the cluster")
private String cpuovercommitratio;
@SerializedName("memoryovercommitratio") @Param (description = "The ram overcommit ratio of the cluster")
@SerializedName("memoryovercommitratio") @Param (description = "The memory overcommit ratio of the cluster")
private String memoryovercommitratio;
public String getId() {
@ -162,18 +161,20 @@ public class ClusterResponse extends BaseResponse {
public void setCapacitites(ArrayList<CapacityResponse> arrayList) {
this.capacitites = arrayList;
}
public void setCpuovercommitratio(String cpuovercommitratio){
public void setCpuOvercommitRatio(String cpuovercommitratio){
this.cpuovercommitratio= cpuovercommitratio;
}
public void setRamovercommitratio (String memoryOvercommitRatio){
this.memoryovercommitratio= memoryOvercommitRatio;
}
public String getCpuovercommitratio (){
public String getCpuOvercommitRatio(){
return cpuovercommitratio;
}
public String getRamovercommitratio (){
public void setMemoryOvercommitRatio(String memoryovercommitratio){
this.memoryovercommitratio= memoryovercommitratio;
}
public String getMemoryOvercommitRatio(){
return memoryovercommitratio;
}
}

View File

@ -115,6 +115,9 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class)
private List<ResourceTagResponse> tags;
@SerializedName(ApiConstants.IS_PORTABLE) @Param(description = "is public IP portable across the zones")
private Boolean isPortable;
/*
@SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume")
private IdentityProxy jobId = new IdentityProxy("async_job");
@ -247,4 +250,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
public void setAssociatedNetworkName(String associatedNetworkName) {
this.associatedNetworkName = associatedNetworkName;
}
public void setPortable(Boolean portable) {
this.isPortable = portable;
}
}

View File

@ -58,6 +58,10 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti
@Param(description = "the load balancer algorithm (source, roundrobin, leastconn)")
private String algorithm;
@SerializedName(ApiConstants.NETWORK_ID)
@Param(description = "the id of the guest network the lb rule belongs to")
private String networkId;
@SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from")
private String cidrList;
@ -90,6 +94,7 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with load balancer", responseObject = ResourceTagResponse.class)
private List<ResourceTagResponse> tags;
public void setId(String id) {
this.id = id;
}
@ -161,4 +166,8 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti
this.tags = tags;
}
public void setNetworkId(String networkId) {
this.networkId = networkId;
}
}

View File

@ -0,0 +1,93 @@
// 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 java.util.List;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.IpAddress;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.region.PortableIpRange;
@EntityReference(value=PortableIpRange.class)
public class PortableIpRangeResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "portable IP range ID")
private String id;
@SerializedName(ApiConstants.REGION_ID)
@Param(description = "Region Id in which portable ip range is provisioned")
private Integer regionId;
@SerializedName(ApiConstants.GATEWAY) @Param(description="the gateway of the VLAN IP range")
private String gateway;
@SerializedName(ApiConstants.NETMASK) @Param(description="the netmask of the VLAN IP range")
private String netmask;
@SerializedName(ApiConstants.VLAN) @Param(description="the ID or VID of the VLAN.")
private String vlan;
@SerializedName(ApiConstants.START_IP) @Param(description="the start ip of the portable IP range")
private String startIp;
@SerializedName(ApiConstants.END_IP) @Param(description="the end ip of the portable IP range")
private String endIp;
@SerializedName(ApiConstants.PORTABLE_IP_ADDRESS)
@Param(description="List of portable IP and association with zone/network/vpc details that are part of GSLB rule", responseObject = PortableIpResponse.class)
private List<PortableIpResponse> portableIpResponses;
public void setId(String id) {
this.id = id;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
public void setStartIp(String startIp) {
this.startIp = startIp;
}
public void setEndIp(String endIp) {
this.endIp = endIp;
}
public void setNetmask(String netmask) {
this.netmask = netmask;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
public void setVlan(String vlan) {
this.vlan = vlan;
}
public void setPortableIpResponses(List<PortableIpResponse> portableIpResponses) {
this.portableIpResponses = portableIpResponses;
}
}

View File

@ -0,0 +1,106 @@
// 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 java.util.List;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.IpAddress;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
@EntityReference(value=PortableIp.class)
public class PortableIpResponse extends BaseResponse {
@SerializedName(ApiConstants.REGION_ID)
@Param(description = "Region Id in which global load balancer is created")
private Integer regionId;
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="public IP address")
private String ipAddress;
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the ID of the zone the public IP address belongs to")
private String zoneId;
@SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the Network where ip belongs to")
private String networkId;
@SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the ip belongs to")
private String vpcId;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network this belongs to")
private String physicalNetworkId;
@SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the account ID the portable IP address is associated with")
private String accountId;
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID the portable IP address is associated with")
private String domainId;
@SerializedName("allocated") @Param(description="date the portal IP address was acquired")
private Date allocated;
@SerializedName(ApiConstants.STATE) @Param(description="State of the ip address. Can be: Allocatin, Allocated and Releasing")
private String state;
public void setRegionId(Integer regionId) {
this.regionId = regionId;
}
public void setAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public void setAssociatedDataCenterId(String zoneId) {
this.zoneId = zoneId;
}
public void setAssociatedWithNetworkId(String networkId) {
this.networkId = networkId;
}
public void setAssociatedWithVpcId(String vpcId) {
this.vpcId = vpcId;
}
public void setPhysicalNetworkId(String physicalNetworkId) {
this.physicalNetworkId = physicalNetworkId;
}
public void setAllocatedToAccountId(String accountId) {
this.accountId = accountId;
}
public void setAllocatedInDomainId(String domainId) {
this.domainId = domainId;
}
public void setAllocatedTime(Date allocatedTimetime) {
this.allocated = allocatedTimetime;
}
public void setState(String state) {
this.state = state;
}
}

View File

@ -0,0 +1,58 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.region;
import java.util.Date;
import com.cloud.utils.net.Ip;
import org.apache.cloudstack.api.InternalIdentity;
public interface PortableIp extends InternalIdentity {
enum State {
Allocating, // The IP Address is being propagated to other network elements and is not ready for use yet.
Allocated, // The IP address is in used.
Releasing, // The IP address is being released for other network elements and is not ready for allocation.
Free // The IP address is ready to be allocated.
}
Long getAllocatedToAccountId();
Long getAllocatedInDomainId();
Date getAllocatedTime();
State getState();
int getRegionId();
Long getAssociatedDataCenterId();
Long getAssociatedWithNetworkId();
Long getAssociatedWithVpcId();
Long getPhysicalNetworkId();
String getAddress();
String getVlan();
String getNetmask();
String getGateway();
}

View File

@ -0,0 +1,38 @@
// 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.region;
import org.apache.cloudstack.acl.InfrastructureEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface PortableIpRange extends InfrastructureEntity, InternalIdentity, Identity {
public final static String UNTAGGED = "untagged";
public String getVlanTag();
public String getGateway();
public String getNetmask();
public int getRegionId();
public String getIpRange();
}

View File

@ -24,11 +24,18 @@ import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.api.response.SwiftResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import static org.mockito.Matchers.anyInt;
import java.util.LinkedList;
import java.util.List;
public class ScaleVMCmdTest extends TestCase{
@ -58,19 +65,34 @@ public class ScaleVMCmdTest extends TestCase{
public void testCreateSuccess() {
UserVmService userVmService = Mockito.mock(UserVmService.class);
UserVm userVm = Mockito.mock(UserVm.class);
try {
Mockito.when(
userVmService.upgradeVirtualMachine(scaleVMCmd))
.thenReturn(true);
.thenReturn(userVm);
}catch (Exception e){
Assert.fail("Received exception when success expected " +e.getMessage());
}
scaleVMCmd._userVmService = userVmService;
responseGenerator = Mockito.mock(ResponseGenerator.class);
ResponseGenerator responseGenerator = Mockito.mock(ResponseGenerator.class);
scaleVMCmd._responseGenerator = responseGenerator;
UserVmResponse userVmResponse = Mockito.mock(UserVmResponse.class);
//List<UserVmResponse> list = Mockito.mock(UserVmResponse.class);
//list.add(userVmResponse);
//LinkedList<UserVmResponse> mockedList = Mockito.mock(LinkedList.class);
//Mockito.when(mockedList.get(0)).thenReturn(userVmResponse);
List<UserVmResponse> list = new LinkedList<UserVmResponse>();
list.add(userVmResponse);
Mockito.when(responseGenerator.createUserVmResponse("virtualmachine", userVm)).thenReturn(
list);
scaleVMCmd._userVmService = userVmService;
scaleVMCmd.execute();
}
@ -83,7 +105,7 @@ public class ScaleVMCmdTest extends TestCase{
try {
Mockito.when(
userVmService.upgradeVirtualMachine(scaleVMCmd))
.thenReturn(false);
.thenReturn(null);
}catch (Exception e){
Assert.fail("Received exception when success expected " +e.getMessage());
}

View File

@ -19,15 +19,14 @@ package com.cloud.bridge.persist.dao;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.springframework.stereotype.Component;
import com.cloud.bridge.model.CloudStackUserVO;
import com.cloud.bridge.util.EncryptionSecretKeyCheckerUtil;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.crypt.DBEncryptionUtil;
@Component
@Local(value={CloudStackUserDao.class})
@ -51,13 +50,8 @@ public class CloudStackUserDaoImpl extends GenericDaoBase<CloudStackUserVO, Stri
sc.setParameters("apiKey", accessKey);
user = findOneBy(sc);
if ( user != null && user.getSecretKey() != null) {
// if the cloud db is encrypted, decrypt the secret_key returned by cloud db before signature generation
if( EncryptionSecretKeyCheckerUtil.useEncryption() ) {
StandardPBEStringEncryptor encryptor = EncryptionSecretKeyCheckerUtil.getEncryptor();
cloudSecretKey = encryptor.decrypt( user.getSecretKey() );
} else {
cloudSecretKey = user.getSecretKey();
}
// User secret key could be encrypted
cloudSecretKey = DBEncryptionUtil.decrypt(user.getSecretKey());
}
return cloudSecretKey;
} finally {

View File

@ -94,7 +94,7 @@ public class EC2MainServlet extends HttpServlet{
if(!isEC2APIEnabled){
//response.sendError(404, "EC2 API is disabled.");
response.setStatus(404);
faultResponse(response, "404" , "EC2 API is disabled.");
faultResponse(response, "Unavailable" , "EC2 API is disabled");
return;
}

View File

@ -35,7 +35,9 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
@ -68,10 +70,12 @@ import com.amazon.ec2.CreateImageResponse;
import com.amazon.ec2.CreateKeyPairResponse;
import com.amazon.ec2.CreateSecurityGroupResponse;
import com.amazon.ec2.CreateSnapshotResponse;
import com.amazon.ec2.CreateTagsResponse;
import com.amazon.ec2.CreateVolumeResponse;
import com.amazon.ec2.DeleteKeyPairResponse;
import com.amazon.ec2.DeleteSecurityGroupResponse;
import com.amazon.ec2.DeleteSnapshotResponse;
import com.amazon.ec2.DeleteTagsResponse;
import com.amazon.ec2.DeleteVolumeResponse;
import com.amazon.ec2.DeregisterImageResponse;
import com.amazon.ec2.DescribeAvailabilityZonesResponse;
@ -82,14 +86,14 @@ import com.amazon.ec2.DescribeInstancesResponse;
import com.amazon.ec2.DescribeKeyPairsResponse;
import com.amazon.ec2.DescribeSecurityGroupsResponse;
import com.amazon.ec2.DescribeSnapshotsResponse;
import com.amazon.ec2.DescribeTagsResponse;
import com.amazon.ec2.DescribeVolumesResponse;
import com.amazon.ec2.DetachVolumeResponse;
import com.amazon.ec2.DisassociateAddressResponse;
import com.amazon.ec2.GetPasswordDataResponse;
import com.amazon.ec2.GroupItemType;
import com.amazon.ec2.ImportKeyPairResponse;
import com.amazon.ec2.LaunchPermissionItemType;
import com.amazon.ec2.ModifyImageAttributeResponse;
import com.amazon.ec2.ModifyInstanceAttributeResponse;
import com.amazon.ec2.RebootInstancesResponse;
import com.amazon.ec2.RegisterImageResponse;
import com.amazon.ec2.ReleaseAddressResponse;
@ -99,9 +103,7 @@ import com.amazon.ec2.RunInstancesResponse;
import com.amazon.ec2.StartInstancesResponse;
import com.amazon.ec2.StopInstancesResponse;
import com.amazon.ec2.TerminateInstancesResponse;
import com.cloud.bridge.model.CloudStackUserVO;
import com.cloud.bridge.model.UserCredentialsVO;
import com.cloud.bridge.persist.dao.CloudStackConfigurationDao;
import com.cloud.bridge.persist.dao.CloudStackUserDaoImpl;
import com.cloud.bridge.persist.dao.OfferingDaoImpl;
import com.cloud.bridge.persist.dao.UserCredentialsDaoImpl;
@ -122,12 +124,14 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups;
import com.cloud.bridge.service.core.ec2.EC2DescribeSnapshots;
import com.cloud.bridge.service.core.ec2.EC2DescribeTags;
import com.cloud.bridge.service.core.ec2.EC2DescribeVolumes;
import com.cloud.bridge.service.core.ec2.EC2DisassociateAddress;
import com.cloud.bridge.service.core.ec2.EC2Engine;
import com.cloud.bridge.service.core.ec2.EC2Filter;
import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet;
import com.cloud.bridge.service.core.ec2.EC2Image;
import com.cloud.bridge.service.core.ec2.EC2ImageFilterSet;
import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute;
import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission;
import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair;
@ -135,6 +139,7 @@ import com.cloud.bridge.service.core.ec2.EC2InstanceFilterSet;
import com.cloud.bridge.service.core.ec2.EC2IpPermission;
import com.cloud.bridge.service.core.ec2.EC2KeyPairFilterSet;
import com.cloud.bridge.service.core.ec2.EC2ModifyImageAttribute;
import com.cloud.bridge.service.core.ec2.EC2ModifyInstanceAttribute;
import com.cloud.bridge.service.core.ec2.EC2RebootInstances;
import com.cloud.bridge.service.core.ec2.EC2RegisterImage;
import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress;
@ -143,6 +148,8 @@ import com.cloud.bridge.service.core.ec2.EC2SecurityGroup;
import com.cloud.bridge.service.core.ec2.EC2SnapshotFilterSet;
import com.cloud.bridge.service.core.ec2.EC2StartInstances;
import com.cloud.bridge.service.core.ec2.EC2StopInstances;
import com.cloud.bridge.service.core.ec2.EC2Tags;
import com.cloud.bridge.service.core.ec2.EC2TagsFilterSet;
import com.cloud.bridge.service.core.ec2.EC2Volume;
import com.cloud.bridge.service.core.ec2.EC2VolumeFilterSet;
import com.cloud.bridge.service.exception.EC2ServiceException;
@ -277,6 +284,7 @@ public class EC2RestServlet extends HttpServlet {
else if (action.equalsIgnoreCase( "DetachVolume" )) detachVolume(request, response);
else if (action.equalsIgnoreCase( "DisassociateAddress" )) disassociateAddress(request, response);
else if (action.equalsIgnoreCase( "ModifyImageAttribute" )) modifyImageAttribute(request, response);
else if (action.equalsIgnoreCase( "ModifyInstanceAttribute" )) modifyInstanceAttribute(request, response);
else if (action.equalsIgnoreCase( "RebootInstances" )) rebootInstances(request, response);
else if (action.equalsIgnoreCase( "RegisterImage" )) registerImage(request, response);
else if (action.equalsIgnoreCase( "ReleaseAddress" )) releaseAddress(request, response);
@ -294,6 +302,9 @@ public class EC2RestServlet extends HttpServlet {
else if (action.equalsIgnoreCase( "ImportKeyPair" )) importKeyPair(request, response);
else if (action.equalsIgnoreCase( "DeleteKeyPair" )) deleteKeyPair(request, response);
else if (action.equalsIgnoreCase( "DescribeKeyPairs" )) describeKeyPairs(request, response);
else if (action.equalsIgnoreCase( "CreateTags" )) createTags(request, response);
else if (action.equalsIgnoreCase( "DeleteTags" )) deleteTags(request, response);
else if (action.equalsIgnoreCase( "DescribeTags" )) describeTags(request, response);
else if (action.equalsIgnoreCase( "GetPasswordData" )) getPasswordData(request, response);
else {
logger.error("Unsupported action " + action);
@ -303,8 +314,14 @@ public class EC2RestServlet extends HttpServlet {
} catch( EC2ServiceException e ) {
response.setStatus(e.getErrorCode());
if (e.getCause() != null && e.getCause() instanceof AxisFault)
faultResponse(response, ((AxisFault)e.getCause()).getFaultCode().getLocalPart(), e.getMessage());
if (e.getCause() != null && e.getCause() instanceof AxisFault) {
String errorCode = ((AxisFault)e.getCause()).getFaultCode().getLocalPart();
if (errorCode.startsWith("Client.")) // only in a SOAP API client error code is prefixed with Client.
errorCode = errorCode.split("Client.")[1];
else if (errorCode.startsWith("Server.")) // only in a SOAP API server error code is prefixed with Server.
errorCode = errorCode.split("Server.")[1];
faultResponse(response, errorCode, e.getMessage());
}
else {
logger.error("EC2ServiceException: " + e.getMessage(), e);
endResponse(response, e.toString());
@ -380,11 +397,6 @@ public class EC2RestServlet extends HttpServlet {
endResponse(response, "SetUserKeys exception " + e.getMessage());
return;
}
// prime UserContext here
// logger.debug("initializing context");
UserContext context = UserContext.current();
try {
txn = Transaction.open(Transaction.AWSAPI_DB);
// -> use the keys to see if the account actually exists
@ -666,17 +678,23 @@ public class EC2RestServlet extends HttpServlet {
String[] volumeId = request.getParameterValues( "VolumeId" );
if ( null != volumeId && 0 < volumeId.length )
EC2request.setId( volumeId[0] );
else { response.sendError(530, "Missing VolumeId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - VolumeId");
}
String[] instanceId = request.getParameterValues( "InstanceId" );
if ( null != instanceId && 0 < instanceId.length )
EC2request.setInstanceId( instanceId[0] );
else { response.sendError(530, "Missing InstanceId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
String[] device = request.getParameterValues( "Device" );
if ( null != device && 0 < device.length )
EC2request.setDevice( device[0] );
else { response.sendError(530, "Missing Device parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Device");
}
// -> execute the request
AttachVolumeResponse EC2response = EC2SoapServiceImpl.toAttachVolumeResponse( ServiceProvider.getInstance().getEC2Engine().attachVolume( EC2request ));
@ -694,7 +712,9 @@ public class EC2RestServlet extends HttpServlet {
String[] groupName = request.getParameterValues( "GroupName" );
if ( null != groupName && 0 < groupName.length )
EC2request.setName( groupName[0] );
else { response.sendError(530, "Missing GroupName parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - GroupName");
}
// -> not clear how many parameters there are until we fail to get IpPermissions.n.IpProtocol
int nCount = 1, mCount;
@ -757,8 +777,7 @@ public class EC2RestServlet extends HttpServlet {
} while( true );
if (1 == nCount) {
response.sendError(530, "At least one IpPermissions required" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - IpPermissions");
}
// -> execute the request
@ -775,7 +794,9 @@ public class EC2RestServlet extends HttpServlet {
String[] groupName = request.getParameterValues( "GroupName" );
if ( null != groupName && 0 < groupName.length )
EC2request.setName( groupName[0] );
else { response.sendError(530, "Missing GroupName parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter 'Groupname'");
}
// -> not clear how many parameters there are until we fail to get IpPermissions.n.IpProtocol
int nCount = 1;
@ -837,8 +858,9 @@ public class EC2RestServlet extends HttpServlet {
} while( true );
if (1 == nCount) { response.sendError(530, "At least one IpPermissions required" ); return; }
if (1 == nCount) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - IpPermissions");
}
// -> execute the request
AuthorizeSecurityGroupIngressResponse EC2response = EC2SoapServiceImpl.toAuthorizeSecurityGroupIngressResponse(
@ -853,7 +875,9 @@ public class EC2RestServlet extends HttpServlet {
String[] volumeId = request.getParameterValues( "VolumeId" );
if ( null != volumeId && 0 < volumeId.length )
EC2request.setId(volumeId[0]);
else { response.sendError(530, "Missing VolumeId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter 'VolumeId'");
}
String[] instanceId = request.getParameterValues( "InstanceId" );
if ( null != instanceId && 0 < instanceId.length )
@ -875,7 +899,9 @@ public class EC2RestServlet extends HttpServlet {
String[] volumeId = request.getParameterValues( "VolumeId" );
if ( null != volumeId && 0 < volumeId.length )
EC2request.setId(volumeId[0]);
else { response.sendError(530, "Missing VolumeId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - VolumeId");
}
// -> execute the request
DeleteVolumeResponse EC2response = EC2SoapServiceImpl.toDeleteVolumeResponse( ServiceProvider.getInstance().getEC2Engine().deleteVolume( EC2request ));
@ -889,7 +915,9 @@ public class EC2RestServlet extends HttpServlet {
String[] zoneName = request.getParameterValues( "AvailabilityZone" );
if ( null != zoneName && 0 < zoneName.length )
EC2request.setZoneName( zoneName[0] );
else { response.sendError(530, "Missing AvailabilityZone parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing parameter - AvailabilityZone");
}
String[] size = request.getParameterValues( "Size" );
String[] snapshotId = request.getParameterValues("SnapshotId");
@ -907,9 +935,9 @@ public class EC2RestServlet extends HttpServlet {
} else if (useSnapshot && !useSize) {
EC2request.setSnapshotId(snapshotId[0]);
} else if (useSize && useSnapshot) {
response.sendError(530, "Size and SnapshotId parameters are mutually exclusive" ); return;
throw new EC2ServiceException( ClientError.InvalidParameterCombination, "Parameters 'Size' and 'SnapshotId' are mutually exclusive");
} else {
response.sendError(530, "Size or SnapshotId has to be specified" ); return;
throw new EC2ServiceException( ClientError.MissingParamter, "Parameter 'Size' or 'SnapshotId' has to be specified");
}
@ -926,12 +954,15 @@ public class EC2RestServlet extends HttpServlet {
String[] name = request.getParameterValues( "GroupName" );
if ( null != name && 0 < name.length )
groupName = name[0];
else { response.sendError(530, "Missing GroupName parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - GroupName");
}
String[] desc = request.getParameterValues( "GroupDescription" );
if ( null != desc && 0 < desc.length )
groupDescription = desc[0];
else { response.sendError(530, "Missing GroupDescription parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - GroupDescription");
}
// -> execute the request
CreateSecurityGroupResponse EC2response = EC2SoapServiceImpl.toCreateSecurityGroupResponse( ServiceProvider.getInstance().getEC2Engine().createSecurityGroup( groupName, groupDescription ));
@ -945,7 +976,9 @@ public class EC2RestServlet extends HttpServlet {
String[] name = request.getParameterValues( "GroupName" );
if ( null != name && 0 < name.length )
groupName = name[0];
else { response.sendError(530, "Missing GroupName parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - GroupName");
}
// -> execute the request
DeleteSecurityGroupResponse EC2response = EC2SoapServiceImpl.toDeleteSecurityGroupResponse( ServiceProvider.getInstance().getEC2Engine().deleteSecurityGroup( groupName ));
@ -959,7 +992,9 @@ public class EC2RestServlet extends HttpServlet {
String[] snapSet = request.getParameterValues( "SnapshotId" );
if ( null != snapSet && 0 < snapSet.length )
snapshotId = snapSet[0];
else { response.sendError(530, "Missing SnapshotId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - SnapshotId");
}
// -> execute the request
DeleteSnapshotResponse EC2response = EC2SoapServiceImpl.toDeleteSnapshotResponse( ServiceProvider.getInstance().getEC2Engine().deleteSnapshot( snapshotId ));
@ -973,7 +1008,9 @@ public class EC2RestServlet extends HttpServlet {
String[] volSet = request.getParameterValues( "VolumeId" );
if ( null != volSet && 0 < volSet.length )
volumeId = volSet[0];
else { response.sendError(530, "Missing VolumeId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - VolumeId");
}
// -> execute the request
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
@ -988,7 +1025,9 @@ public class EC2RestServlet extends HttpServlet {
String[] imageId = request.getParameterValues( "ImageId" );
if ( null != imageId && 0 < imageId.length )
image.setId( imageId[0] );
else { response.sendError(530, "Missing ImageId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ImageId");
}
// -> execute the request
DeregisterImageResponse EC2response = EC2SoapServiceImpl.toDeregisterImageResponse( ServiceProvider.getInstance().getEC2Engine().deregisterImage( image ));
@ -1002,16 +1041,25 @@ public class EC2RestServlet extends HttpServlet {
String[] instanceId = request.getParameterValues( "InstanceId" );
if ( null != instanceId && 0 < instanceId.length )
EC2request.setInstanceId( instanceId[0] );
else { response.sendError(530, "Missing InstanceId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
String[] name = request.getParameterValues( "Name" );
if ( null != name && 0 < name.length )
EC2request.setName( name[0] );
else { response.sendError(530, "Missing Name parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Name");
}
String[] description = request.getParameterValues( "Description" );
if ( null != description && 0 < description.length )
if ( null != description && 0 < description.length ) {
if (description[0].length() > 255)
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Length of the value of parameter Description should be less than 255");
EC2request.setDescription( description[0] );
}
// -> execute the request
CreateImageResponse EC2response = EC2SoapServiceImpl.toCreateImageResponse( ServiceProvider.getInstance().getEC2Engine().createImage( EC2request ));
@ -1025,16 +1073,23 @@ public class EC2RestServlet extends HttpServlet {
String[] location = request.getParameterValues( "ImageLocation" );
if ( null != location && 0 < location.length )
EC2request.setLocation( location[0] );
else { response.sendError(530, "Missing ImageLocation parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing parameter - ImageLocation");
}
String[] cloudRedfined = request.getParameterValues( "Architecture" );
if ( null != cloudRedfined && 0 < cloudRedfined.length )
EC2request.setArchitecture( cloudRedfined[0] );
else { response.sendError(530, "Missing Architecture parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Architecture");
}
String[] name = request.getParameterValues( "Name" );
if ( null != name && 0 < name.length )
EC2request.setName( name[0] );
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Name");
}
String[] description = request.getParameterValues( "Description" );
if ( null != description && 0 < description.length )
@ -1053,8 +1108,7 @@ public class EC2RestServlet extends HttpServlet {
if ( imageId != null && imageId.length > 0 )
ec2request.setImageId( imageId[0]);
else {
response.sendError(530, "Missing ImageId parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ImageId");
}
String[] description = request.getParameterValues( "Description.Value" );
@ -1067,8 +1121,8 @@ public class EC2RestServlet extends HttpServlet {
if (ec2request.getLaunchPermissionSet().length > 0)
ec2request.setAttribute(ImageAttribute.launchPermission);
else {
response.sendError(530, "Missing Attribute parameter - Description/LaunchPermission should be provided" );
return;
throw new EC2ServiceException( ClientError.MissingParamter,
"Missing required parameter - Description/LaunchPermission should be provided");
}
}
@ -1120,8 +1174,7 @@ public class EC2RestServlet extends HttpServlet {
if ( imageId != null && imageId.length > 0)
ec2request.setImageId(imageId[0]);
else {
response.sendError(530, "Missing ImageId parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ImageId");
}
String[] attribute = request.getParameterValues( "Attribute" );
@ -1129,12 +1182,11 @@ public class EC2RestServlet extends HttpServlet {
if (attribute[0].equalsIgnoreCase("launchPermission"))
ec2request.setAttribute(ImageAttribute.launchPermission);
else {
response.sendError(501, "Unsupported Attribute - only launchPermission supported" );
return;
throw new EC2ServiceException( ClientError.MissingParamter,
"Missing required parameter - Description/LaunchPermission should be provided");
}
} else {
response.sendError(530, "Missing Attribute parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Attribute");
}
EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission();
@ -1155,12 +1207,13 @@ public class EC2RestServlet extends HttpServlet {
String[] imageId = request.getParameterValues( "ImageId" );
if ( null != imageId && 0 < imageId.length )
EC2request.setTemplateId( imageId[0] );
else { response.sendError(530, "Missing ImageId parameter" ); return; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ImageId");
}
String[] minCount = request.getParameterValues( "MinCount" );
if ( minCount == null || minCount.length < 1) {
response.sendError(530, "Missing MinCount parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - MinCount");
} else if ( Integer.parseInt(minCount[0]) < 1) {
throw new EC2ServiceException(ClientError.InvalidParameterValue,
"Value of parameter MinCount should be greater than 0");
@ -1170,8 +1223,7 @@ public class EC2RestServlet extends HttpServlet {
String[] maxCount = request.getParameterValues( "MaxCount" );
if ( maxCount == null || maxCount.length < 1) {
response.sendError(530, "Missing MaxCount parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - MaxCount");
} else if ( Integer.parseInt(maxCount[0]) < 1) {
throw new EC2ServiceException(ClientError.InvalidParameterValue,
"Value of parameter MaxCount should be greater than 0");
@ -1235,7 +1287,9 @@ public class EC2RestServlet extends HttpServlet {
}
}
}
if (0 == count) { response.sendError(530, "Missing InstanceId parameter" ); return; }
if (0 == count) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
// -> execute the request
RebootInstancesResponse EC2response = EC2SoapServiceImpl.toRebootInstancesResponse( ServiceProvider.getInstance().getEC2Engine().rebootInstances(EC2request));
@ -1259,7 +1313,9 @@ public class EC2RestServlet extends HttpServlet {
}
}
}
if (0 == count) { response.sendError(530, "Missing InstanceId parameter" ); return; }
if (0 == count) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
// -> execute the request
StartInstancesResponse EC2response = EC2SoapServiceImpl.toStartInstancesResponse( ServiceProvider.getInstance().getEC2Engine().startInstances(EC2request));
@ -1283,7 +1339,9 @@ public class EC2RestServlet extends HttpServlet {
}
}
}
if (0 == count) { response.sendError(530, "Missing InstanceId parameter" ); return; }
if (0 == count) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
String[] force = request.getParameterValues("Force");
if ( force != null) {
@ -1312,7 +1370,9 @@ public class EC2RestServlet extends HttpServlet {
}
}
}
if (0 == count) { response.sendError(530, "Missing InstanceId parameter" ); return; }
if (0 == count) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
// -> execute the request
EC2request.setDestroyInstances( true );
@ -1349,7 +1409,8 @@ public class EC2RestServlet extends HttpServlet {
}
// -> execute the request
DescribeAvailabilityZonesResponse EC2response = EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse( ServiceProvider.getInstance().getEC2Engine().handleRequest( EC2request ));
DescribeAvailabilityZonesResponse EC2response = EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse(
ServiceProvider.getInstance().getEC2Engine().describeAvailabilityZones( EC2request ));
serializeResponse(response, EC2response);
}
@ -1366,6 +1427,15 @@ public class EC2RestServlet extends HttpServlet {
if (null != value && 0 < value.length) EC2request.addImageSet( value[0] );
}
}
// add filters
EC2Filter[] filterSet = extractFilters( request );
if ( filterSet != null ) {
EC2ImageFilterSet ifs = new EC2ImageFilterSet();
for( int i=0; i < filterSet.length; i++ ) {
ifs.addFilter(filterSet[i]);
}
EC2request.setFilterSet( ifs );
}
// -> execute the request
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
DescribeImagesResponse EC2response = EC2SoapServiceImpl.toDescribeImagesResponse( engine.describeImages( EC2request ));
@ -1380,8 +1450,7 @@ public class EC2RestServlet extends HttpServlet {
if (imageId != null && imageId.length > 0)
ec2request.setImageId(imageId[0]);
else {
response.sendError(530, "Missing ImageId parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ImageId");
}
String[] attribute = request.getParameterValues( "Attribute" );
@ -1391,12 +1460,11 @@ public class EC2RestServlet extends HttpServlet {
else if (attribute[0].equalsIgnoreCase("launchPermission"))
ec2request.setAttribute(ImageAttribute.launchPermission);
else {
response.sendError(501, "Unsupported Attribute - description and launchPermission supported" );
return;
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Only values supported for paramter Attribute are - Description/LaunchPermission");
}
} else {
response.sendError(530, "Missing Attribute parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Attribute");
}
DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().describeImageAttribute( ec2request ));
@ -1478,8 +1546,7 @@ public class EC2RestServlet extends HttpServlet {
String publicIp = request.getParameter( "PublicIp" );
if (publicIp == null) {
response.sendError(530, "Missing PublicIp parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - PublicIp");
}
EC2ReleaseAddress ec2Request = new EC2ReleaseAddress();
@ -1498,13 +1565,11 @@ public class EC2RestServlet extends HttpServlet {
String publicIp = request.getParameter( "PublicIp" );
if (null == publicIp) {
response.sendError(530, "Missing PublicIp parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - PublicIp");
}
String instanceId = request.getParameter( "InstanceId" );
if (null == instanceId) {
response.sendError(530, "Missing InstanceId parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
EC2AssociateAddress ec2Request = new EC2AssociateAddress();
@ -1524,8 +1589,7 @@ public class EC2RestServlet extends HttpServlet {
String publicIp = request.getParameter( "PublicIp" );
if (null == publicIp) {
response.sendError(530, "Missing PublicIp parameter" );
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - PublicIp");
}
EC2DisassociateAddress ec2Request = new EC2DisassociateAddress();
@ -1573,27 +1637,20 @@ public class EC2RestServlet extends HttpServlet {
private void describeInstanceAttribute( HttpServletRequest request, HttpServletResponse response )
throws ADBException, XMLStreamException, IOException {
EC2DescribeInstances EC2request = new EC2DescribeInstances();
String instanceType = null;
String[] instanceId = request.getParameterValues( "InstanceId" );
if ( instanceId != null && instanceId.length > 0)
EC2request.addInstanceId( instanceId[0] );
else
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
// -> we are only handling queries about the "Attribute=instanceType"
Enumeration<?> names = request.getParameterNames();
while( names.hasMoreElements()) {
String key = (String)names.nextElement();
if (key.startsWith("Attribute")) {
String[] value = request.getParameterValues( key );
if (null != value && 0 < value.length && value[0].equalsIgnoreCase( "instanceType" )) {
instanceType = value[0];
break;
String[] attribute = request.getParameterValues( "Attribute" );
if (attribute != null && attribute.length > 0) {
if ( !attribute[0].equalsIgnoreCase("instanceType") ) {
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Only value supported for paramter Attribute is 'instanceType'");
}
}
}
if ( null != instanceType ) {
String[] value = request.getParameterValues( "InstanceId" );
EC2request.addInstanceId( value[0] );
}
else {
response.sendError(501, "Unsupported - only instanceType supported" );
return;
} else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Attribute");
}
// -> execute the request
@ -1601,6 +1658,38 @@ public class EC2RestServlet extends HttpServlet {
serializeResponse(response, EC2response);
}
private void modifyInstanceAttribute(HttpServletRequest request, HttpServletResponse response)
throws ADBException, XMLStreamException, IOException {
EC2ModifyInstanceAttribute ec2Request = new EC2ModifyInstanceAttribute();
String[] instanceId = request.getParameterValues( "InstanceId" );
if ( instanceId != null && instanceId.length > 0 )
ec2Request.setInstanceId(instanceId[0]);
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
String[] instanceType = request.getParameterValues( "InstanceType.Value" );
String[] userData = request.getParameterValues( "UserData.Value" );
if ( instanceType != null && userData != null ) {
throw new EC2ServiceException( ClientError.InvalidParameterCombination, "Only one attribute can be" +
" specified at a time");
}
if ( instanceType != null && instanceType.length > 0 ) {
ec2Request.setInstanceType(instanceType[0]);
} else if ( userData != null && userData.length > 0 ) {
ec2Request.setUserData(userData[0]);
} else {
throw new EC2ServiceException( ClientError.MissingParamter,
"Missing parameter - InstanceType/UserData should be provided");
}
// -> execute the request
ModifyInstanceAttributeResponse EC2response = EC2SoapServiceImpl.toModifyInstanceAttributeResponse(
ServiceProvider.getInstance().getEC2Engine().modifyInstanceAttribute( ec2Request ));
serializeResponse(response, EC2response);
}
private void describeSnapshots( HttpServletRequest request, HttpServletResponse response )
throws ADBException, XMLStreamException, IOException
@ -1629,7 +1718,8 @@ public class EC2RestServlet extends HttpServlet {
// -> execute the request
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
DescribeSnapshotsResponse EC2response = EC2SoapServiceImpl.toDescribeSnapshotsResponse( engine.handleRequest( EC2request ));
DescribeSnapshotsResponse EC2response = EC2SoapServiceImpl.toDescribeSnapshotsResponse(
engine.describeSnapshots( EC2request ));
serializeResponse(response, EC2response);
}
@ -1661,7 +1751,9 @@ public class EC2RestServlet extends HttpServlet {
}
// -> execute the request
DescribeVolumesResponse EC2response = EC2SoapServiceImpl.toDescribeVolumesResponse( ServiceProvider.getInstance().getEC2Engine().handleRequest( EC2request ));
EC2Engine engine = ServiceProvider.getInstance().getEC2Engine();
DescribeVolumesResponse EC2response = EC2SoapServiceImpl.toDescribeVolumesResponse(
ServiceProvider.getInstance().getEC2Engine().describeVolumes( EC2request ), engine);
serializeResponse(response, EC2response);
}
@ -1755,10 +1847,13 @@ public class EC2RestServlet extends HttpServlet {
throws ADBException, XMLStreamException, IOException {
String keyName = request.getParameter("KeyName");
if ( keyName == null ) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - KeyName");
}
String publicKeyMaterial = request.getParameter("PublicKeyMaterial");
if (keyName==null && publicKeyMaterial==null) {
response.sendError(530, "Missing parameter");
return;
if ( publicKeyMaterial == null ) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - PublicKeyMaterial");
}
if (!publicKeyMaterial.contains(" "))
@ -1781,8 +1876,7 @@ public class EC2RestServlet extends HttpServlet {
throws ADBException, XMLStreamException, IOException {
String keyName = request.getParameter("KeyName");
if (keyName==null) {
response.sendError(530, "Missing KeyName parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - KeyName");
}
EC2CreateKeyPair ec2Request = new EC2CreateKeyPair();
@ -1799,8 +1893,7 @@ public class EC2RestServlet extends HttpServlet {
throws ADBException, XMLStreamException, IOException {
String keyName = request.getParameter("KeyName");
if (keyName==null) {
response.sendError(530, "Missing KeyName parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - KeyName");
}
EC2DeleteKeyPair ec2Request = new EC2DeleteKeyPair();
@ -1815,8 +1908,7 @@ public class EC2RestServlet extends HttpServlet {
throws ADBException, XMLStreamException, IOException {
String instanceId = request.getParameter("InstanceId");
if (instanceId==null) {
response.sendError(530, "Missing InstanceId parameter");
return;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - InstanceId");
}
GetPasswordDataResponse EC2Response = EC2SoapServiceImpl.toGetPasswordData(
@ -1824,6 +1916,81 @@ public class EC2RestServlet extends HttpServlet {
serializeResponse(response, EC2Response);
}
private void createTags(HttpServletRequest request, HttpServletResponse response)
throws ADBException, XMLStreamException, IOException {
EC2Tags ec2Request = createTagsRequest(request, response);
if (ec2Request == null) return;
CreateTagsResponse EC2Response = EC2SoapServiceImpl.toCreateTagsResponse(
ServiceProvider.getInstance().getEC2Engine().modifyTags( ec2Request, "create"));
serializeResponse(response, EC2Response);
}
private void deleteTags(HttpServletRequest request, HttpServletResponse response)
throws ADBException, XMLStreamException, IOException {
EC2Tags ec2Request = createTagsRequest(request, response);
if (ec2Request == null) return;
DeleteTagsResponse EC2Response = EC2SoapServiceImpl.toDeleteTagsResponse(
ServiceProvider.getInstance().getEC2Engine().modifyTags( ec2Request, "delete"));
serializeResponse(response, EC2Response);
}
private EC2Tags createTagsRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException {
EC2Tags ec2Request = new EC2Tags();
ArrayList<String> resourceIdList = new ArrayList<String>();
Map<String, String> resourceTagList = new HashMap<String, String>();
int nCount = 1;
do {
String[] resourceIds = request.getParameterValues( "ResourceId." + nCount );
if (resourceIds != null && resourceIds.length > 0)
resourceIdList.add(resourceIds[0]);
else break;
nCount++;
} while (true);
if ( resourceIdList.isEmpty() ) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ResourceId");
}
ec2Request = EC2SoapServiceImpl.toResourceTypeAndIds(ec2Request, resourceIdList);
nCount = 1;
do {
String[] tagKey = request.getParameterValues( "Tag." + nCount + ".Key" );
if ( tagKey != null && tagKey.length > 0 ) {
String[] tagValue = request.getParameterValues( "Tag." + nCount + ".Value" );
if ( tagValue != null && tagValue.length > 0 ) {
resourceTagList.put(tagKey[0], tagValue[0]);
} else
resourceTagList.put(tagKey[0], null);
} else break;
nCount++;
} while (true);
if ( resourceTagList.isEmpty() ) {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - ResourceTag");
}
ec2Request = EC2SoapServiceImpl.toResourceTag(ec2Request, resourceTagList);
return ec2Request;
}
private void describeTags(HttpServletRequest request, HttpServletResponse response)
throws ADBException, XMLStreamException, IOException {
EC2DescribeTags ec2Request = new EC2DescribeTags();
EC2Filter[] filterSet = extractFilters( request );
if (null != filterSet) {
EC2TagsFilterSet tfs = new EC2TagsFilterSet();
for( int i=0; i < filterSet.length; i++ )
tfs.addFilter( filterSet[i] );
ec2Request.setFilterSet( tfs );
}
DescribeTagsResponse EC2Response = EC2SoapServiceImpl.toDescribeTagsResponse(
ServiceProvider.getInstance().getEC2Engine().describeTags( ec2Request));
serializeResponse(response, EC2Response);
}
/**
* This function implements the EC2 REST authentication algorithm. It uses the given
* "AWSAccessKeyId" parameter to look up the Cloud.com account holder's secret key which is
@ -1843,69 +2010,76 @@ public class EC2RestServlet extends HttpServlet {
String[] awsAccess = request.getParameterValues( "AWSAccessKeyId" );
if ( null != awsAccess && 0 < awsAccess.length )
cloudAccessKey = awsAccess[0];
else { response.sendError(530, "Missing AWSAccessKeyId parameter" ); return false; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - AWSAccessKeyId");
}
String[] clientSig = request.getParameterValues( "Signature" );
if ( null != clientSig && 0 < clientSig.length )
signature = clientSig[0];
else { response.sendError(530, "Missing Signature parameter" ); return false; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Signature");
}
String[] method = request.getParameterValues( "SignatureMethod" );
if ( null != method && 0 < method.length )
{
sigMethod = method[0];
if (!sigMethod.equals( "HmacSHA256" ) && !sigMethod.equals( "HmacSHA1" )) {
response.sendError(531, "Unsupported SignatureMethod value: " + sigMethod + " expecting: HmacSHA256 or HmacSHA1" );
return false;
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Unsupported SignatureMethod value: " + sigMethod + " expecting: HmacSHA256 or HmacSHA1");
}
} else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - SignatureMethod");
}
else { response.sendError(530, "Missing SignatureMethod parameter" ); return false; }
String[] version = request.getParameterValues( "Version" );
if ( null != version && 0 < version.length )
{
if (!version[0].equals( wsdlVersion )) {
response.sendError(531, "Unsupported Version value: " + version[0] + " expecting: " + wsdlVersion );
return false;
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Unsupported Version value: " + version[0] + " expecting: " + wsdlVersion);
}
} else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - Version");
}
else { response.sendError(530, "Missing Version parameter" ); return false; }
String[] sigVersion = request.getParameterValues( "SignatureVersion" );
if ( null != sigVersion && 0 < sigVersion.length )
{
if (!sigVersion[0].equals( "2" )) {
response.sendError(531, "Unsupported SignatureVersion value: " + sigVersion[0] + " expecting: 2" );
return false;
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Unsupported SignatureVersion value: " + sigVersion[0] + " expecting: 2");
}
}
else { response.sendError(530, "Missing SignatureVersion parameter" ); return false; }
else {
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter - SignatureVersion");
}
// -> can have only one but not both { Expires | Timestamp } headers
String[] expires = request.getParameterValues( "Expires" );
if ( null != expires && 0 < expires.length )
{
// -> contains the date and time at which the signature included in the request EXPIRES
if (hasSignatureExpired( expires[0] )) {
response.sendError(531, "Expires parameter indicates signature has expired: " + expires[0] );
return false;
if (hasSignatureExpired( expires[0] )) { //InvalidSecurity.RequestHasExpired
throw new EC2ServiceException( ClientError.InvalidSecurity_RequestHasExpired,
"Expires parameter indicates signature has expired: " + expires[0]);
}
}
else
{ // -> contains the date and time at which the request is SIGNED
String[] time = request.getParameterValues( "Timestamp" );
if ( null == time || 0 == time.length ) {
response.sendError(530, "Missing Timestamp and Expires parameter, one is required" );
return false;
throw new EC2ServiceException( ClientError.MissingParamter, "Missing required parameter -" +
" Timestamp/Expires");
}
}
// [B] Use the access key to get the users secret key from the cloud DB
cloudSecretKey = userDao.getSecretKeyByAccessKey( cloudAccessKey );
if ( cloudSecretKey == null ) {
logger.debug("No Secret key found for Access key '" + cloudAccessKey + "' in the the EC2 service");
throw new EC2ServiceException( ClientError.AuthFailure, "No Secret key found for Access key '" + cloudAccessKey +
"' in the the EC2 service" );
logger.debug( "Access key '" + cloudAccessKey + "' not found in the the EC2 service ");
throw new EC2ServiceException( ClientError.AuthFailure, "Access key '" + cloudAccessKey + "' not found in the the EC2 service ");
}
// [C] Verify the signature
@ -1949,7 +2123,8 @@ public class EC2RestServlet extends HttpServlet {
UserContext.current().initContext( cloudAccessKey, cloudSecretKey, cloudAccessKey, "REST request", null );
return true;
}
else throw new PermissionDeniedException("Invalid signature");
else throw new EC2ServiceException( ClientError.SignatureDoesNotMatch,
"The request signature calculated does not match the signature provided by the user.");
}
/**
@ -2043,8 +2218,9 @@ public class EC2RestServlet extends HttpServlet {
throws ADBException, XMLStreamException, IOException {
OutputStream os = response.getOutputStream();
response.setStatus(200);
response.setContentType("text/xml; charset=UTF-8");
response.setContentType("text/xml");
XMLStreamWriter xmlWriter = xmlOutFactory.createXMLStreamWriter( os );
xmlWriter.writeStartDocument("UTF-8","1.0");
MTOMAwareXMLSerializer MTOMWriter = new MTOMAwareXMLSerializer( xmlWriter );
MTOMWriter.setDefaultNamespace("http://ec2.amazonaws.com/doc/" + wsdlVersion + "/");
EC2Response.serialize( null, factory, MTOMWriter );

View File

@ -18,7 +18,10 @@ package com.cloud.bridge.service;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
@ -48,7 +51,9 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
import com.cloud.bridge.service.core.ec2.EC2DescribeInstancesResponse;
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs;
import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairsResponse;
import com.cloud.bridge.service.core.ec2.EC2ImageFilterSet;
import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission;
import com.cloud.bridge.service.core.ec2.EC2ModifyInstanceAttribute;
import com.cloud.bridge.service.core.ec2.EC2ResourceTag;
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups;
import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroupsResponse;
@ -92,7 +97,6 @@ import com.cloud.bridge.service.core.ec2.EC2Volume;
import com.cloud.bridge.service.core.ec2.EC2VolumeFilterSet;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
import com.cloud.bridge.service.exception.EC2ServiceException.ServerError;
import com.cloud.bridge.util.EC2RestAuth;
@ -210,62 +214,69 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
public CreateTagsResponse createTags(CreateTags createTags) {
EC2Tags request = new EC2Tags();
ArrayList<String> resourceIdList = new ArrayList<String>();
Map<String, String> resourceTagList = new HashMap<String, String>();
CreateTagsType ctt = createTags.getCreateTags();
ResourceIdSetType resourceIds = ctt.getResourcesSet();
ResourceTagSetType resourceTags = ctt.getTagSet();
request = toResourceTypeAndIds(resourceIds);
ResourceIdSetItemType[] resourceIdItems = resourceIds.getItem();
if (resourceIdItems != null) {
for( int i=0; i < resourceIdItems.length; i++ )
resourceIdList.add(resourceIdItems[i].getResourceId());
}
request = toResourceTypeAndIds(request, resourceIdList);
//add resource tag's to the request
if (resourceTags != null) {
ResourceTagSetItemType[] items = resourceTags.getItem();
if (items != null) {
for( int i=0; i < items.length; i++ ) {
EC2TagKeyValue param1 = new EC2TagKeyValue();
param1.setKey(items[i].getKey());
param1.setValue(items[i].getValue());
request.addResourceTag(param1);
}
}
ResourceTagSetItemType[] resourceTagItems = resourceTags.getItem();
if (resourceTagItems != null) {
for( int i=0; i < resourceTagItems.length; i++ )
resourceTagList.put(resourceTagItems[i].getKey(), resourceTagItems[i].getValue());
}
request = toResourceTag(request, resourceTagList);
return toCreateTagsResponse( engine.modifyTags( request, "create"));
}
public DeleteTagsResponse deleteTags(DeleteTags deleteTags) {
EC2Tags request = new EC2Tags();
ArrayList<String> resourceIdList = new ArrayList<String>();
Map<String, String> resourceTagList = new HashMap<String, String>();
DeleteTagsType dtt = deleteTags.getDeleteTags();
ResourceIdSetType resourceIds = dtt.getResourcesSet();
DeleteTagsSetType resourceTags = dtt.getTagSet();
request = toResourceTypeAndIds(resourceIds);
ResourceIdSetItemType[] resourceIdItems = resourceIds.getItem();
if (resourceIdItems != null) {
for( int i=0; i < resourceIdItems.length; i++ )
resourceIdList.add(resourceIdItems[i].getResourceId());
}
request = toResourceTypeAndIds(request, resourceIdList);
//add resource tag's to the request
if (resourceTags != null) {
DeleteTagsSetItemType[] items = resourceTags.getItem();
if (items != null) {
for( int i=0; i < items.length; i++ ) {
EC2TagKeyValue param1 = new EC2TagKeyValue();
param1.setKey(items[i].getKey());
if (items[i].getValue() != null)
param1.setValue(items[i].getValue());
request.addResourceTag(param1);
}
}
DeleteTagsSetItemType[] resourceTagItems = resourceTags.getItem();
if (resourceTagItems != null) {
for( int i=0; i < resourceTagItems.length; i++ )
resourceTagList.put(resourceTagItems[i].getKey(), resourceTagItems[i].getValue());
}
request = toResourceTag(request, resourceTagList);
return toDeleteTagsResponse( engine.modifyTags( request, "delete"));
}
private EC2Tags toResourceTypeAndIds(ResourceIdSetType resourceIds) {
EC2Tags request = new EC2Tags();
//add resource-type and resource-id's to the request
if (resourceIds != null) {
ResourceIdSetItemType[] items = resourceIds.getItem();
public static EC2Tags toResourceTypeAndIds( EC2Tags request, ArrayList<String> resourceIdList ) {
List<String> resourceTypeList = new ArrayList<String>();
if (items != null) {
for( int i=0; i < items.length; i++ ) {
if (!items[i].getResourceId().contains(":") || items[i].getResourceId().split(":").length != 2) {
throw new EC2ServiceException( ClientError.InvalidResourceId_Format,
"Invalid Format. ResourceId format is resource-type:resource-uuid");
for (String resourceId : resourceIdList) {
if (!resourceId.contains(":") || resourceId.split(":").length != 2) {
throw new EC2ServiceException( ClientError.InvalidParameterValue,
"Invalid usage. ResourceId format is resource-type:resource-uuid");
}
String resourceType = items[i].getResourceId().split(":")[0];
String resourceType = resourceId.split(":")[0];
if (resourceTypeList.isEmpty())
resourceTypeList.add(resourceType);
else {
@ -283,14 +294,23 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
for (String resourceType : resourceTypeList) {
EC2TagTypeId param1 = new EC2TagTypeId();
param1.setResourceType(resourceType);
for( int i=0; i < items.length; i++ ) {
String[] resourceTag = items[i].getResourceId().split(":");
for (String resourceId : resourceIdList) {
String[] resourceTag = resourceId.split(":");
if (resourceType.equals(resourceTag[0]))
param1.addResourceId(resourceTag[1]);
}
request.addResourceType(param1);
}
return request;
}
public static EC2Tags toResourceTag( EC2Tags request, Map<String, String> resourceTagList ) {
Set<String> resourceTagKeySet = resourceTagList.keySet();
for (String resourceTagKey : resourceTagKeySet) {
EC2TagKeyValue param1 = new EC2TagKeyValue();
param1.setKey(resourceTagKey);
param1.setValue(resourceTagList.get(resourceTagKey));
request.addResourceTag(param1);
}
return request;
}
@ -336,7 +356,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
request.setFilterSet( toAvailabiltyZonesFilterSet(fst));
}
return toDescribeAvailabilityZonesResponse( engine.handleRequest( request ));
return toDescribeAvailabilityZonesResponse( engine.describeAvailabilityZones( request ));
}
/**
@ -388,7 +408,10 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
for( int i=0; i < items3.length; i++ ) request.addOwnersSet( items3[i].getOwner());
}
}
FilterSetType fst = dit.getFilterSet();
if ( fst != null) {
request.setFilterSet(toImageFilterSet(fst));
}
return toDescribeImagesResponse( engine.describeImages( request ));
}
@ -526,7 +549,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
request = toSnapshotFilterSet( request, fst, timeFilters );
}
return toDescribeSnapshotsResponse(engine.handleRequest(request));
return toDescribeSnapshotsResponse(engine.describeSnapshots(request));
}
public DescribeTagsResponse describeTags(DescribeTags decsribeTags) {
@ -565,7 +588,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
request = toVolumeFilterSet( request, fst, timeFilters );
}
return toDescribeVolumesResponse( engine.handleRequest( request ));
return toDescribeVolumesResponse( engine.describeVolumes( request ), engine);
}
public DetachVolumeResponse detachVolume(DetachVolume detachVolume) {
@ -606,6 +629,26 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
throw new EC2ServiceException( ClientError.Unsupported, "Unsupported - can only modify image description or launchPermission");
}
public ModifyInstanceAttributeResponse modifyInstanceAttribute(ModifyInstanceAttribute modifyInstanceAttribute) {
EC2ModifyInstanceAttribute request = new EC2ModifyInstanceAttribute();
ModifyInstanceAttributeType modifyInstanceAttribute2 = modifyInstanceAttribute.getModifyInstanceAttribute();
ModifyInstanceAttributeTypeChoice_type0 mia = modifyInstanceAttribute2.getModifyInstanceAttributeTypeChoice_type0();
request.setInstanceId(modifyInstanceAttribute2.getInstanceId());
// we only support instanceType and userData
if (mia.getInstanceType() != null) {
request.setInstanceType(mia.getInstanceType().getValue());
} else if (mia.getUserData() != null) {
request.setUserData(mia.getUserData().getValue());
} else {
throw new EC2ServiceException( ClientError.MissingParamter,
"Missing required parameter - InstanceType/UserData should be provided");
}
return toModifyInstanceAttributeResponse(engine.modifyInstanceAttribute(request));
}
private void setAccountOrGroupList(LaunchPermissionItemType[] items, EC2ModifyImageAttribute request, String operation){
EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission();
@ -836,24 +879,18 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
return response;
}
/**
* @param modifyInstanceAttribute
* @return
*/
public static ModifyInstanceAttributeResponse toModifyInstanceAttributeResponse(Boolean status) {
ModifyInstanceAttributeResponse miat = new ModifyInstanceAttributeResponse();
public static DescribeImageAttributeResponse toDescribeImageAttributeResponse(EC2DescribeImagesResponse engineResponse) {
DescribeImageAttributeResponse response = new DescribeImageAttributeResponse();
DescribeImageAttributeResponseType param1 = new DescribeImageAttributeResponseType();
EC2Image[] imageSet = engineResponse.getImageSet();
if ( 0 < imageSet.length ) {
DescribeImageAttributeResponseTypeChoice_type0 param2 = new DescribeImageAttributeResponseTypeChoice_type0();
NullableAttributeValueType param3 = new NullableAttributeValueType();
param3.setValue( imageSet[0].getDescription());
param2.setDescription( param3 );
param1.setDescribeImageAttributeResponseTypeChoice_type0( param2 );
param1.setImageId( imageSet[0].getId());
}
param1.setRequestId( UUID.randomUUID().toString());
response.setDescribeImageAttributeResponse( param1 );
return response;
ModifyInstanceAttributeResponseType param = new ModifyInstanceAttributeResponseType();
param.set_return(status);
param.setRequestId(UUID.randomUUID().toString());
miat.setModifyInstanceAttributeResponse(param);
return miat;
}
public static DescribeImageAttributeResponse toDescribeImageAttributeResponse(EC2ImageAttributes engineResponse) {
@ -929,7 +966,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
DescribeImagesResponseItemType param3 = new DescribeImagesResponseItemType();
param3.setImageId( images[i].getId());
param3.setImageLocation( "" );
param3.setImageState( (images[i].getIsReady() ? "available" : "unavailable" ));
param3.setImageState( images[i].getState());
param3.setImageOwnerId(ownerId);
param3.setIsPublic( images[i].getIsPublic());
@ -942,15 +979,13 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
String description = images[i].getDescription();
param3.setDescription( (null == description ? "" : description));
if (null == description) param3.setArchitecture( "" );
else if (-1 != description.indexOf( "x86_64" )) param3.setArchitecture( "x86_64" );
else if (-1 != description.indexOf( "i386" )) param3.setArchitecture( "i386" );
else param3.setArchitecture( "" );
param3.setArchitecture( images[i].getArchitecture());
param3.setImageType( "machine" );
param3.setImageType( images[i].getImageType());
param3.setKernelId( "" );
param3.setRamdiskId( "" );
param3.setPlatform( "" );
param3.setHypervisor( images[i].getHypervisor());
StateReasonType param6 = new StateReasonType();
param6.setCode( "" );
@ -1268,8 +1303,29 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
return tfs;
}
private EC2ImageFilterSet toImageFilterSet( FilterSetType fst ) {
EC2ImageFilterSet ifs = new EC2ImageFilterSet();
FilterType[] items = fst.getItem();
if (items != null) {
for (FilterType item : items) {
EC2Filter oneFilter = new EC2Filter();
String filterName = item.getName();
oneFilter.setName( filterName );
ValueSetType vft = item.getValueSet();
ValueType[] valueItems = vft.getItem();
for (ValueType valueItem : valueItems) {
oneFilter.addValueEncoded( valueItem.getValue());
}
ifs.addFilter( oneFilter );
}
}
return ifs;
}
// toMethods
public static DescribeVolumesResponse toDescribeVolumesResponse( EC2DescribeVolumesResponse engineResponse )
public static DescribeVolumesResponse toDescribeVolumesResponse( EC2DescribeVolumesResponse engineResponse, EC2Engine engine )
{
DescribeVolumesResponse response = new DescribeVolumesResponse();
DescribeVolumesResponseType param1 = new DescribeVolumesResponseType();
@ -1834,6 +1890,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
param1.setVolumeId( engineResponse.getId().toString());
Long volSize = new Long( engineResponse.getSize());
param1.setSize( volSize.toString());
if (engineResponse.getSnapshotId() != null)
param1.setSnapshotId( engineResponse.getSnapshotId() );
else
param1.setSnapshotId( "" );
param1.setAvailabilityZone( engineResponse.getZoneName());
if ( null != engineResponse.getState())
@ -2462,10 +2521,6 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
}
public ModifyInstanceAttributeResponse modifyInstanceAttribute(ModifyInstanceAttribute modifyInstanceAttribute) {
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
}
public ModifySnapshotAttributeResponse modifySnapshotAttribute(ModifySnapshotAttribute modifySnapshotAttribute) {
throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available");
}

View File

@ -26,6 +26,9 @@ import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2AddressFilterSet {
protected final static Logger logger = Logger.getLogger(EC2KeyPairFilterSet.class);
@ -43,15 +46,8 @@ public class EC2AddressFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value) {
// Changing this to silently ignore
logger.error("Unsupported filter [" + filterName + "] - 1");
return;
}
if (null != value && value.equalsIgnoreCase( "null" )) {
logger.error("Unsupported filter [" + filterName + "] - 2");
return;
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)

View File

@ -26,6 +26,7 @@ import java.util.Map;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2AvailabilityZonesFilterSet {
@ -43,11 +44,9 @@ public class EC2AvailabilityZonesFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
filterSet.add( param );
}

View File

@ -24,6 +24,7 @@ public class EC2DescribeImages {
private List<String> executableBySet = new ArrayList<String>();; // a list of strings identifying users
private List<String> imageSet = new ArrayList<String>(); // a list of AMI id's
private List<String> ownersSet = new ArrayList<String>(); // a list of AMI owner id's
private EC2ImageFilterSet ifs = null;
public EC2DescribeImages() {
}
@ -51,4 +52,13 @@ public class EC2DescribeImages {
public String[] getOwnersSet() {
return ownersSet.toArray(new String[0]);
}
public EC2ImageFilterSet getFilterSet() {
return ifs;
}
public void setFilterSet( EC2ImageFilterSet param ) {
ifs = param;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2GroupFilterSet {
@ -52,11 +53,9 @@ public class EC2GroupFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if ( value == null || value.equalsIgnoreCase("null")) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );

View File

@ -28,10 +28,13 @@ public class EC2Image {
private String name;
private String description;
private String osTypeId;
private boolean isPublic;
private boolean isReady;
private Boolean isPublic;
private String state;
private String accountName;
private String domainId;
private String hypervisor;
private String architecture;
private String imageType;
private List<EC2TagKeyValue> tagsSet;
public EC2Image() {
@ -40,9 +43,12 @@ public class EC2Image {
description = null;
osTypeId = null;
isPublic = false;
isReady = false;
state = null;
accountName = null;
domainId = null;
hypervisor = null;
architecture = null;
imageType = "machine";
tagsSet = new ArrayList<EC2TagKeyValue>();
}
@ -78,20 +84,20 @@ public class EC2Image {
return this.osTypeId;
}
public void setIsPublic( boolean isPublic ) {
public void setIsPublic( Boolean isPublic ) {
this.isPublic = isPublic;
}
public boolean getIsPublic() {
public Boolean getIsPublic() {
return this.isPublic;
}
public void setIsReady( boolean isReady ) {
this.isReady = isReady;
public void setState( String state ) {
this.state = state;
}
public boolean getIsReady() {
return this.isReady;
public String getState() {
return this.state;
}
public String getAccountName() {
@ -110,6 +116,25 @@ public class EC2Image {
this.domainId = domainId;
}
public String getHypervisor() {
return hypervisor;
}
public void setHypervisor(String hypervisor) {
this.hypervisor = hypervisor;
}
public String getArchitecture() {
return architecture;
}
public void setArchitecture(String architecture) {
this.architecture = architecture;
}
public String getImageType() {
return imageType;
}
public void addResourceTag( EC2TagKeyValue param ) {
tagsSet.add( param );

View File

@ -0,0 +1,168 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.bridge.service.core.ec2;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2ImageFilterSet {
protected final static Logger logger = Logger.getLogger(EC2ImageFilterSet.class);
protected List<EC2Filter> filterSet = new ArrayList<EC2Filter>();
private Map<String,String> filterTypes = new HashMap<String,String>();
public EC2ImageFilterSet() {
// -> supported filters
filterTypes.put( "architecture", "string" );
filterTypes.put( "description", "string" );
filterTypes.put( "hypervisor", "string" );
filterTypes.put( "image-id", "string" );
filterTypes.put( "image-type", "string" );
filterTypes.put( "is-public", "Boolean" );
filterTypes.put( "name", "string" );
filterTypes.put( "owner-id", "string" );
filterTypes.put( "state", "string" );
filterTypes.put( "tag-key", "string" );
filterTypes.put( "tag-value", "string" );
}
public void addFilter( EC2Filter param ) {
String filterName = param.getName();
if ( !filterName.startsWith("tag:") ) {
String value = (String) filterTypes.get( filterName );
if ( value == null || value.equalsIgnoreCase("null")) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
}
filterSet.add( param );
}
public EC2Filter[] getFilterSet() {
return filterSet.toArray(new EC2Filter[0]);
}
public EC2DescribeImagesResponse evaluate( EC2DescribeImagesResponse sampleList) throws ParseException {
EC2DescribeImagesResponse resultList = new EC2DescribeImagesResponse();
boolean matched;
EC2Image[] imageSet = sampleList.getImageSet();
EC2Filter[] filterSet = getFilterSet();
for (EC2Image image : imageSet) {
matched = true;
for (EC2Filter filter : filterSet) {
if (!filterMatched(image, filter)) {
matched = false;
break;
}
}
if (matched == true)
resultList.addImage(image);
}
return resultList;
}
private boolean filterMatched( EC2Image image, EC2Filter filter ) throws ParseException {
String filterName = filter.getName();
String[] valueSet = filter.getValueSet();
if ( filterName.equalsIgnoreCase( "architecture" ))
return containsString( image.getArchitecture(), valueSet );
if ( filterName.equalsIgnoreCase( "description" ))
return containsString( image.getDescription(), valueSet );
if ( filterName.equalsIgnoreCase( "hypervisor" ))
return containsString( image.getHypervisor(), valueSet );
if ( filterName.equalsIgnoreCase( "image-id" ))
return containsString( image.getId(), valueSet );
if ( filterName.equalsIgnoreCase( "image-type" ))
return containsString( image.getImageType(), valueSet );
if ( filterName.equalsIgnoreCase( "is-public" ))
return image.getIsPublic().toString().equalsIgnoreCase(valueSet[0]);
if ( filterName.equalsIgnoreCase( "name" ))
return containsString( image.getName(), valueSet );
if ( filterName.equalsIgnoreCase( "owner-id" )) {
String owner = new String( image.getDomainId() + ":" + image.getAccountName());
return containsString( owner, valueSet );
}
if ( filterName.equalsIgnoreCase( "state" ))
return containsString( image.getState(), valueSet );
else if (filterName.equalsIgnoreCase("tag-key"))
{
EC2TagKeyValue[] tagSet = image.getResourceTags();
for (EC2TagKeyValue tag : tagSet)
if (containsString(tag.getKey(), valueSet)) return true;
return false;
}
else if (filterName.equalsIgnoreCase("tag-value"))
{
EC2TagKeyValue[] tagSet = image.getResourceTags();
for (EC2TagKeyValue tag : tagSet){
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
return false;
}
else if (filterName.startsWith("tag:"))
{
String key = filterName.split(":")[1];
EC2TagKeyValue[] tagSet = image.getResourceTags();
for (EC2TagKeyValue tag : tagSet){
if (tag.getKey().equalsIgnoreCase(key)) {
if (tag.getValue() == null) {
if (containsEmptyValue(valueSet)) return true;
}
else {
if (containsString(tag.getValue(), valueSet)) return true;
}
}
}
return false;
}
else return false;
}
private boolean containsString( String lookingFor, String[] set ) {
if (lookingFor == null)
return false;
for (String filter: set) {
if (lookingFor.matches( filter )) return true;
}
return false;
}
private boolean containsEmptyValue( String[] set ) {
for( int i=0; i < set.length; i++ ) {
if (set[i].isEmpty()) return true;
}
return false;
}
}

View File

@ -24,6 +24,7 @@ import java.util.Map;
import com.cloud.bridge.service.EC2SoapServiceImpl;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2InstanceFilterSet {
@ -59,11 +60,10 @@ public class EC2InstanceFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 );
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}

View File

@ -25,6 +25,9 @@ import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2KeyPairFilterSet {
protected final static Logger logger = Logger.getLogger(EC2KeyPairFilterSet.class);
@ -42,15 +45,8 @@ public class EC2KeyPairFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value) {
// Changing this to silently ignore
logger.error("Unsupported filter [" + filterName + "] - 1");
return;
}
if (null != value && value.equalsIgnoreCase( "null" )) {
logger.error("Unsupported filter [" + filterName + "] - 2");
return;
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)

View File

@ -0,0 +1,64 @@
// 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.bridge.service.core.ec2;
public class EC2ModifyInstanceAttribute {
private String instanceId;
private String instanceType;
private String userData;
/**
* @return instanceId
*/
public String getInstanceId() {
return instanceId;
}
/**
* @param instanceId to set
*/
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
/**
* @return instanceType
*/
public String getInstanceType() {
return instanceType;
}
/**
* @param instanceType to set
*/
public void setInstanceType(String instanceType) {
this.instanceType = instanceType;
}
/**
* @return userData
*/
public String getUserData() {
return userData;
}
public void setUserData(String userData) {
this.userData = userData;
}
}

View File

@ -72,7 +72,7 @@ public class EC2RegisterImage {
if (null != param) {
if (!param.contains(":") || param.split(":").length < 4) {
throw new EC2ServiceException( ClientError.InvalidParameterValue, "Supported format for " +
"'architecture' is format:zonename:ostypename:hypervisor" );
"parameter 'architecture' is format:zonename:ostypename:hypervisor" );
}
String parts[] = param.split( ":" );
format = parts[0];
@ -80,9 +80,6 @@ public class EC2RegisterImage {
osTypeName = parts[2];
hypervisor = parts[3];
}
else {
throw new EC2ServiceException(ClientError.Unsupported, "Missing Parameter -" + " architecture");
}
}
public String getFormat() {

View File

@ -27,6 +27,7 @@ import java.util.TimeZone;
import com.cloud.bridge.service.UserContext;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
import com.cloud.bridge.util.DateHelper;
import com.cloud.bridge.util.EC2RestAuth;
@ -56,12 +57,9 @@ public class EC2SnapshotFilterSet {
String filterName = param.getName();
if (!filterName.startsWith("tag:")) {
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );

View File

@ -26,6 +26,7 @@ import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
public class EC2TagsFilterSet {
protected final static Logger logger = Logger.getLogger(EC2TagsFilterSet.class);
@ -45,11 +46,9 @@ public class EC2TagsFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
filterSet.add( param );
}

View File

@ -26,6 +26,7 @@ import java.util.TimeZone;
import java.util.Date;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
import com.cloud.bridge.util.EC2RestAuth;
@ -61,11 +62,9 @@ public class EC2VolumeFilterSet {
String filterName = param.getName();
String value = (String) filterTypes.get( filterName );
if (null == value)
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 1", 501 );
if (null != value && value.equalsIgnoreCase( "null" ))
throw new EC2ServiceException( "Unsupported filter [" + filterName + "] - 2", 501 );
if ( value == null || value.equalsIgnoreCase("null") ) {
throw new EC2ServiceException( ClientError.InvalidFilter, "Filter '" + filterName + "' is invalid");
}
// ToDo we could add checks to make sure the type of a filters value is correct (e.g., an integer)
filterSet.add( param );
}

View File

@ -49,9 +49,11 @@ public class EC2ServiceException extends RuntimeException {
AttachmentLimitExceeded("Client.AttachmentLimitExceeded", 400),
AuthFailure("Client.AuthFailure", 400),
Blocked("Client.Blocked", 400),
DependencyViolation("Client.DependencyViolation", 400),
FilterLimitExceeded("Client.FilterLimitExceeded", 400),
IdempotentParameterMismatch("Client.IdempotentParameterMismatch", 400),
IncorrectState("Client.IncorrectState", 400),
IncorrectInstanceState("Client.IncorrectInstanceState", 400),
InstanceLimitExceeded("Client.InstanceLimitExceeded", 400),
InsufficientInstanceCapacity("Client.InsufficientInstanceCapacity", 400),
InsufficientReservedInstancesCapacity("Client.InsufficientReservedInstancesCapacity", 400),
@ -61,6 +63,7 @@ public class EC2ServiceException extends RuntimeException {
InvalidAMIID_Unavailable("Client.InvalidAMIID.Unavailable", 400),
InvalidAttachment_NotFound("Client.InvalidAttachment.NotFound", 400),
InvalidDevice_InUse("Client.InvalidDevice.InUse", 400),
InvalidFilter("Client.InvalidFilter", 400),
InvalidGroup_Duplicate("Client.InvalidGroup.Duplicate", 400),
InvalidGroup_InUse("Client.InvalidGroup.InUse", 400),
InvalidGroup_NotFound("Client.InvalidGroup.NotFound", 400),
@ -78,7 +81,7 @@ public class EC2ServiceException extends RuntimeException {
InvalidPermission_Malformed("Client.InvalidPermission.Malformed", 400),
InvalidReservationID_Malformed("Client.InvalidReservationID.Malformed", 400),
InvalidReservationID_NotFound("Client.InvalidReservationID.NotFound", 400),
InvalidResourceId_Format("Client.InvalidResourceId.Format", 400),
InvalidSecurity_RequestHasExpired("Client.InvalidSecurity.RequestHasExpired", 400),
InvalidSnapshotID_Malformed("Client.InvalidSnapshotID.Malformed", 400),
InvalidSnapshot_NotFound("Client.InvalidSnapshot.NotFound", 400),
InvalidUserID_Malformed("Client.InvalidUserID.Malformed", 400),
@ -89,13 +92,16 @@ public class EC2ServiceException extends RuntimeException {
InvalidVolume_NotFound("Client.InvalidVolume.NotFound", 400),
InvalidVolumeID_ZoneMismatch("Client.InvalidVolumeID.ZoneMismatch", 400),
InvalidZone_NotFound("Client.InvalidZone.NotFound", 400),
MissingParamter("Client.MissingParamter", 400),
NonEBSInstance("Client.NonEBSInstance", 400),
PendingVerification("Client.PendingVerification", 400),
PendingSnapshotLimitExceeded("Client.PendingSnapshotLimitExceeded", 400),
SignatureDoesNotMatch("Client.SignatureDoesNotMatch", 400),
ReservedInstancesLimitExceeded("Client.ReservedInstancesLimitExceeded", 400),
ResourceLimitExceeded("Client.ResourceLimitExceeded", 400),
SnapshotLimitExceeded("Client.SnapshotLimitExceeded", 400),
UnknownParameter("Client.UnknownParameter", 400),
Unsupported("Client.Unsupported", 400),
Unsupported("Client.UnsupportedOperation", 400),
VolumeLimitExceeded("Client.VolumeLimitExceeded", 400);
private String errorString;

View File

@ -103,8 +103,8 @@ public class CloudStackClient {
int jobStatus = queryAsyncJobResponse.getAsInt("queryasyncjobresultresponse.jobstatus");
switch(jobStatus) {
case 2:
throw new Exception(queryAsyncJobResponse.getAsString("queryasyncjobresultresponse.jobresult.errorcode") + " " +
queryAsyncJobResponse.getAsString("queryasyncjobresultresponse.jobresult.errortext"));
throw new Exception(queryAsyncJobResponse.getAsString("queryasyncjobresultresponse.jobresult.errortext") + " Error Code - " +
queryAsyncJobResponse.getAsString("queryasyncjobresultresponse.jobresult.errorcode") );
case 0 :
try {
@ -179,6 +179,7 @@ public class CloudStackClient {
if(errorMessage == null){
errorMessage = "CloudStack API call HTTP response error, HTTP status code: " + statusCode;
}
errorMessage = errorMessage.concat(" Error Code - " + Integer.toString(statusCode));
throw new IOException(errorMessage);
}

View File

@ -131,6 +131,11 @@
<artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-planner-implicit-dedication</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-host-allocator-random</artifactId>

View File

@ -276,6 +276,8 @@
<bean id="physicalNetworkTrafficTypeDaoImpl" class="com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl" />
<bean id="podVlanDaoImpl" class="com.cloud.dc.dao.PodVlanDaoImpl" />
<bean id="podVlanMapDaoImpl" class="com.cloud.dc.dao.PodVlanMapDaoImpl" />
<bean id="PortableIpDaoImpl" class="org.apache.cloudstack.region.PortableIpDaoImpl" />
<bean id="PortableIpRangeDaoImpl" class="org.apache.cloudstack.region.PortableIpRangeDaoImpl" />
<bean id="portForwardingRulesDaoImpl" class="com.cloud.network.rules.dao.PortForwardingRulesDaoImpl" />
<bean id="portProfileDaoImpl" class="com.cloud.network.dao.PortProfileDaoImpl" />
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
@ -374,7 +376,7 @@
<bean id="vpnUserDaoImpl" class="com.cloud.network.dao.VpnUserDaoImpl" />
<bean id="applicationLbRuleDaoImpl" class="org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl" />
<bean id="networkOfferingDetailsDaoImpl" class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />
<bean id="serviceOfferingDetailsDaoImpl" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"/>
<!--
Checkers
@ -551,6 +553,10 @@
<property name="name" value="UserConcentratedPodPlanner"/>
</bean>
<bean id="ImplicitDedicationPlanner" class="com.cloud.deploy.ImplicitDedicationPlanner">
<property name="name" value="ImplicitDedicationPlanner"/>
</bean>
<bean id="clusterBasedAgentLoadBalancerPlanner" class="com.cloud.cluster.agentlb.ClusterBasedAgentLoadBalancerPlanner">
<property name="name" value="ClusterBasedAgentLoadBalancerPlanner"/>
</bean>

View File

@ -205,6 +205,7 @@ destroySystemVm=1
listSystemVms=3
migrateSystemVm=1
changeServiceForSystemVm=1
scaleSystemVm=1
#### configuration commands
updateConfiguration=1
@ -633,6 +634,11 @@ addCiscoAsa1000vResource=1
deleteCiscoAsa1000vResource=1
listCiscoAsa1000vResources=1
#### portable public IP commands
createPortableIpRange=1
deletePortableIpRange=1
listPortableIpRanges=1
#### Internal LB VM commands
stopInternalLoadBalancerVM=1
startInternalLoadBalancerVM=1
@ -640,3 +646,4 @@ listInternalLoadBalancerVMs=1
### Network Isolation methods listing
listNetworkIsolationMethods=1

View File

@ -156,6 +156,7 @@
<ref bean="FirstFitPlanner" />
<ref bean="UserDispersingPlanner" />
<ref bean="UserConcentratedPodPlanner" />
<ref bean="ImplicitDedicationPlanner" />
<!--
<ref bean="BareMetalPlanner" />
-->

View File

@ -251,7 +251,7 @@
<ref bean="FirstFitPlanner" />
<ref bean="UserDispersingPlanner" />
<ref bean="UserConcentratedPodPlanner" />
<ref bean="ImplicitDedicationPlanner" />
<!--
<ref bean="BareMetalPlanner" />
-->

View File

@ -28,7 +28,6 @@ public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand {
public CreateEntityDownloadURLCommand(String installPath, String uuid) {
super();
this.parent = parent;
this.installPath = installPath;
this.extractLinkUUID = uuid;
}

View File

@ -110,7 +110,7 @@ import java.util.List;
dnsServers = dnsServers+dnsMasqconfigcmd.getDns2()+",";
}
dnsServers = dnsServers +"*";
dnsServers = dnsServers.replace(";*", "");
dnsServers = dnsServers.replace(",*", "");
dnsMasqconf.set(24,"dhcp-option=6,"+dnsServers);
return dnsMasqconf.toArray( new String[dnsMasqconf.size()]);
}

4
debian/rules vendored
View File

@ -34,7 +34,7 @@ build: build-indep
build-indep: build-indep-stamp
build-indep-stamp: configure
mvn package -Pawsapi -DskipTests -Dsystemvm \
mvn clean package -Pawsapi -DskipTests -Dsystemvm \
-Dcs.replace.properties=replace.properties.tmp \
${ACS_BUILD_OPTS}
touch $@
@ -80,6 +80,7 @@ install:
mkdir -p $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps/client
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps7080
mkdir $(DESTDIR)/usr/share/$(PACKAGE)-management/setup
mkdir $(DESTDIR)/var/log/$(PACKAGE)/management
mkdir $(DESTDIR)/var/cache/$(PACKAGE)/management
@ -153,6 +154,7 @@ install:
mkdir $(DESTDIR)/usr/share/$(PACKAGE)-bridge
mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-bridge/webapps/awsapi
mkdir $(DESTDIR)/usr/share/$(PACKAGE)-bridge/setup
ln -s /usr/share/$(PACKAGE)-bridge/webapps/awsapi $(DESTDIR)/usr/share/$(PACKAGE)-management/webapps7080/awsapi
cp -r awsapi/target/cloud-awsapi-$(VERSION)-SNAPSHOT/* $(DESTDIR)/usr/share/$(PACKAGE)-bridge/webapps/awsapi
install -D awsapi-setup/setup/cloud-setup-bridge $(DESTDIR)/usr/bin/cloudstack-setup-bridge
install -D awsapi-setup/setup/cloudstack-aws-api-register $(DESTDIR)/usr/bin/cloudstack-aws-api-register

View File

@ -48,6 +48,7 @@
</bookinfo>
<xi:include href="plugin-niciranvp-about.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="plugin-niciranvp-usage.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="plugin-niciranvp-vpc.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-troubleshooting.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="plugin-niciranvp-revisions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>

View File

@ -4586,7 +4586,7 @@ under the License.
versions of Citrix CloudStack (last version prior to Apache is 3.0.2) and from the releases
made while CloudStack was in the Apache Incubator.</para>
<para>If you run into any issues during upgrades, please feel free to ask questions on
users@apache.cloudstack.org or dev@apache.cloudstack.org.</para>
users@cloudstack.apache.org or dev@cloudstack.apache.org.</para>
<section id="upgrade-from-4.0-to-4.1">
<title>Upgrade from 4.0.x to 4.1.0</title>
<para>This section will guide you from &PRODUCT; 4.0.x versions to &PRODUCT; 4.1.0.</para>
@ -4647,6 +4647,23 @@ under the License.
automatically. (If you're unsure, we recommend making a backup of the original
<filename>components.xml</filename> to be on the safe side.</para>
</listitem>
<listitem>
<para>After upgrading to 4.1, API clients are expected to send plain text passwords for login and user creation, instead of MD5 hash. Incase, api client changes are not acceptable, following changes are to be made for backward compatibility:</para>
<para>Modify componentsContext.xml, and make PlainTextUserAuthenticator as the default authenticator (1st entry in the userAuthenticators adapter list is default)</para>
<programlisting language="XML">
&lt;!-- Security adapters --&gt;
&lt;bean id="userAuthenticators" class="com.cloud.utils.component.AdapterList"&gt;
&lt;property name="Adapters"&gt;
&lt;list&gt;
&lt;ref bean="PlainTextUserAuthenticator"/&gt;
&lt;ref bean="MD5UserAuthenticator"/&gt;
&lt;ref bean="LDAPUserAuthenticator"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
</programlisting>
<para>PlainTextUserAuthenticator works the same way MD5UserAuthenticator worked prior to 4.1.</para>
</listitem>
<listitem id="upgrade-deb-packages">
<para>If you are using Ubuntu, follow this procedure to upgrade your packages. If not,
skip to step <xref linkend="upgrade-rpm-packages"/>.</para>
@ -5110,6 +5127,23 @@ service cloudstack-agent start
node.</para>
</note>
</listitem>
<listitem>
<para>After upgrading to 4.1, API clients are expected to send plain text passwords for login and user creation, instead of MD5 hash. Incase, api client changes are not acceptable, following changes are to be made for backward compatibility:</para>
<para>Modify componentsContext.xml, and make PlainTextUserAuthenticator as the default authenticator (1st entry in the userAuthenticators adapter list is default)</para>
<programlisting language="XML">
&lt;!-- Security adapters --&gt;
&lt;bean id="userAuthenticators" class="com.cloud.utils.component.AdapterList"&gt;
&lt;property name="Adapters"&gt;
&lt;list&gt;
&lt;ref bean="PlainTextUserAuthenticator"/&gt;
&lt;ref bean="MD5UserAuthenticator"/&gt;
&lt;ref bean="LDAPUserAuthenticator"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
</programlisting>
<para>PlainTextUserAuthenticator works the same way MD5UserAuthenticator worked prior to 4.1.</para>
</listitem>
<listitem>
<para>Start the first Management Server. Do not start any other Management Server nodes
yet.</para>
@ -5688,6 +5722,23 @@ service cloudstack-agent start
</listitem>
</orderedlist>
</listitem>
<listitem>
<para>After upgrading to 4.1, API clients are expected to send plain text passwords for login and user creation, instead of MD5 hash. Incase, api client changes are not acceptable, following changes are to be made for backward compatibility:</para>
<para>Modify componentsContext.xml, and make PlainTextUserAuthenticator as the default authenticator (1st entry in the userAuthenticators adapter list is default)</para>
<programlisting language="XML">
&lt;!-- Security adapters --&gt;
&lt;bean id="userAuthenticators" class="com.cloud.utils.component.AdapterList"&gt;
&lt;property name="Adapters"&gt;
&lt;list&gt;
&lt;ref bean="PlainTextUserAuthenticator"/&gt;
&lt;ref bean="MD5UserAuthenticator"/&gt;
&lt;ref bean="LDAPUserAuthenticator"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
</programlisting>
<para>PlainTextUserAuthenticator works the same way MD5UserAuthenticator worked prior to 4.1.</para>
</listitem>
<listitem>
<para>If you have made changes to your existing copy of the
<filename>/etc/cloud/management/db.properties</filename> file in your previous-version

View File

@ -117,5 +117,21 @@
pagesize; projectid (lists objects by project); regionid; tags (lists resources by tags:
key/value pairs)</para>
</listitem>
<listitem>
<para>createPortableIpAddressRange</para>
<para>Creates portable IP addresses from the portable public IP address pool.</para>
<para>The request parameters are region id, start ip, end ip, netmask, gateway, and
vlan.</para>
</listitem>
<listitem>
<para>deletePortableIpAddressRange</para>
<para>Deletes portable IP addresses from the portable public IP address pool.</para>
<para>The request parameters is portable ip address range id.</para>
</listitem>
<listitem>
<para>createPortableIpAddressRange</para>
<para>Lists portable IP addresses in the portable public IP address pool.</para>
<para>The request parameters are elastic ip id and region id.</para>
</listitem>
</itemizedlist>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">

View File

@ -21,27 +21,15 @@
under the License.
-->
<section id="Device-management">
<title>Device-management</title>
<para>In &PRODUCT; 4.0.x each Nicira NVP setup is considered a "device" that can be added and removed from a physical network. To complete the configuration of the Nicira NVP plugin a device needs to be added to the physical network using the "addNiciraNVPDevice" API call. The plugin is now enabled on the physical network and any guest networks created on that network will be provisioned using the Nicira NVP Controller.</para>
<para>The plugin introduces a set of new API calls to manage the devices, see below or refer to the API reference.</para>
<itemizedlist>
<listitem><para>addNiciraNvpDevice</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>physicalnetworkid: the UUID of the physical network on which the device is configured</para></listitem>
<listitem><para>hostname: the IP address of the NVP controller</para></listitem>
<listitem><para>username: the username for access to the NVP API</para></listitem>
<listitem><para>password: the password for access to the NVP API</para></listitem>
<listitem><para>transportzoneuuid: the UUID of the transportzone</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>deleteNiciraNVPDevice</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>nvpdeviceid: the UUID of the device</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>listNiciraNVPDevices</para></listitem>
</itemizedlist>
<title>Device Management</title>
<para>In &PRODUCT; a Nicira NVP setup is considered a "device" that can be added and removed from a physical network. To complete the configuration of the Nicira NVP plugin a device needs to be added to the physical network. Press the "Add NVP Controller" button on the provider panel and enter the configuration details.</para>
<mediaobject>
<imageobject>
<imagedata fileref="./images/nvp-add-controller.png" />
</imageobject>
<textobject>
<phrase>nvp-physical-network-stt.png: a screenshot of the device configuration popup.</phrase>
</textobject>
</mediaobject>
</section>

View File

@ -22,12 +22,63 @@
-->
<section id="Features-of-the-Nicira-NVP-Plugin">
<title>Features of the Nicira NVP Plugin</title>
<para>In &PRODUCT; release 4.0.0-incubating this plugin supports the Connectivity service. This service is responsible for creating Layer 2 networks supporting the networks created by Guests. In other words when an tenant creates a new network, instead of the traditional VLAN a logical network will be created by sending the appropriate calls to the Nicira NVP Controller.</para>
<para>The plugin has been tested with Nicira NVP versions 2.1.0, 2.2.0 and 2.2.1</para>
<note><para>In &PRODUCT; 4.0.0-incubating only the XenServer hypervisor is supported for use in
combination with Nicira NVP.</para>
<para>In &PRODUCT; 4.1.0-incubating both KVM and XenServer hypervisors are
supported.</para></note>
<note><para>In &PRODUCT; 4.0.0-incubating the UI components for this plugin are not complete,
configuration is done by sending commands to the API.</para></note>
<para>The following table lists the CloudStack network services provided by the Nicira NVP Plugin.</para>
<table>
<title>Supported Services</title>
<tgroup cols="3">
<thead>
<row>
<entry>Network Service</entry>
<entry>CloudStack version</entry>
<entry>NVP version</entry>
</row>
</thead>
<tbody>
<row>
<entry>Virtual Networking</entry>
<entry>&gt;= 4.0</entry>
<entry>&gt;= 2.2.1</entry>
</row>
<row>
<entry>Source NAT</entry>
<entry>&gt;= 4.1</entry>
<entry>&gt;= 3.0.1</entry>
</row>
<row>
<entry>Static NAT</entry>
<entry>&gt;= 4.1</entry>
<entry>&gt;= 3.0.1</entry>
</row>
<row>
<entry>Port Forwarding</entry>
<entry>&gt;= 4.1</entry>
<entry>&gt;= 3.0.1</entry>
</row>
</tbody>
</tgroup>
</table>
<note><para>The Virtual Networking service was originally called 'Connectivity' in CloudStack 4.0</para></note>
<para>The following hypervisors are supported by the Nicira NVP Plugin.</para>
<table>
<title>Supported Hypervisors</title>
<tgroup cols="2">
<thead>
<row>
<entry>Hypervisor</entry>
<entry>CloudStack version</entry>
</row>
</thead>
<tbody>
<row>
<entry>XenServer</entry>
<entry>&gt;= 4.0</entry>
</row>
<row>
<entry>KVM</entry>
<entry>&gt;= 4.1</entry>
</row>
</tbody>
</tgroup>
</table>
<note><para>Please refer to the Nicira NVP configuration guide on how to prepare the hypervisors for Nicira NVP integration.</para></note>
</section>

View File

@ -22,5 +22,8 @@
-->
<section id="Introduction-to-the-Nicira-NVP-Plugin">
<title>Introduction to the Nicira NVP Plugin</title>
<para>The Nicira NVP plugin allows CloudStack to use the Nicira solution for virtualized network as a provider for CloudStack networks and services.</para>
<para>The Nicira NVP plugin adds Nicira NVP as one of the available SDN implementations in
CloudStack. With the plugin an exisiting Nicira NVP setup can be used by CloudStack to
implement isolated guest networks and to provide additional services like routing and
NAT.</para>
</section>

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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.
-->
<section id="network-offerings">
<title>Network Offerings</title>
<para>Using the Nicira NVP plugin requires a network offering with Virtual Networking enabled and configured to use the NiciraNvp element. Typical use cases combine services from the Virtual Router appliance and the Nicira NVP plugin.</para>
<table>
<title>Isolated network offering with regular services from the Virtual Router.</title>
<tgroup cols="2">
<thead>
<row>
<entry>Service</entry>
<entry>Provider</entry>
</row>
</thead>
<tbody>
<row>
<entry>VPN</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>DHCP</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>DNS</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Firewall</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Load Balancer</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>User Data</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Source NAT</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Static NAT</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Post Forwarding</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Virtual Networking</entry>
<entry>NiciraNVP</entry>
</row>
</tbody>
</tgroup>
</table>
<mediaobject>
<imageobject>
<imagedata fileref="./images/nvp-network-offering.png" />
</imageobject>
<textobject>
<phrase>nvp-physical-network-stt.png: a screenshot of a network offering.</phrase>
</textobject>
</mediaobject>
<note><para>The tag in the network offering should be set to the name of the physical network with the NVP provider.</para></note>
<para>Isolated network with network services. The virtual router is still required to provide network services like dns and dhcp.</para>
<table>
<title>Isolated network offering with network services</title>
<tgroup cols="2">
<thead>
<row>
<entry>Service</entry>
<entry>Provider</entry>
</row>
</thead>
<tbody>
<row>
<entry>DHCP</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>DNS</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>User Data</entry>
<entry>VirtualRouter</entry>
</row>
<row>
<entry>Source NAT</entry>
<entry>NiciraNVP</entry>
</row>
<row>
<entry>Static NAT</entry>
<entry>NiciraNVP</entry>
</row>
<row>
<entry>Post Forwarding</entry>
<entry>NiciraNVP</entry>
</row>
<row>
<entry>Virtual Networking</entry>
<entry>NiciraNVP</entry>
</row>
</tbody>
</tgroup>
</table>
</section>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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.
-->
<section id="zone-configuration">
<title>Zone Configuration</title>
<para>&PRODUCT; needs to have at least one physical network with the isolation method set to "STT". This network should be enabled for the Guest traffic type.</para>
<note><para>The Guest traffic type should be configured with the traffic label that matches the name of
the Integration Bridge on the hypervisor. See the Nicira NVP User Guide for more details
on how to set this up in XenServer or KVM.</para></note>
<mediaobject>
<imageobject>
<imagedata fileref="./images/nvp-physical-network-stt.png" />
</imageobject>
<textobject>
<phrase>nvp-physical-network-stt.png: a screenshot of a physical network with the STT isolation type</phrase>
</textobject>
</mediaobject>
</section>

View File

@ -23,16 +23,15 @@
<section id="Prerequisites">
<title>Prerequisites</title>
<para>Before enabling the Nicira NVP plugin the NVP Controller needs to be configured. Please review the NVP User Guide on how to do that.</para>
<para>&PRODUCT; needs to have at least one physical network with the isolation method set to "STT". This network should be enabled for the Guest traffic type.</para>
<note><para>The Guest traffic type should be configured with the traffic label that matches the name of
the Integration Bridge on the hypervisor. See the Nicira NVP User Guide for more details
on how to set this up in XenServer or KVM.</para></note>
<para>Make sure you have the following information ready:</para>
<itemizedlist>
<listitem><para>The IP address of the NVP Controller</para></listitem>
<listitem><para>The username to access the API</para></listitem>
<listitem><para>The password to access the API</para></listitem>
<listitem><para>The UUID of the Transport Zone that contains the hypervisors in this Zone</para></listitem>
<listitem><para>The UUID of the Physical Network that will be used for the Guest networks</para></listitem>
<listitem>
<para>The UUID of the Gateway Service used to provide router and NAT services.</para>
</listitem>
</itemizedlist>
<note><para>The gateway service uuid is optional and is used for Layer 3 services only (SourceNat, StaticNat and PortForwarding)</para></note>
</section>

View File

@ -22,21 +22,15 @@
-->
<section id="Enabling-the-service-provider">
<title>Enabling the service provider</title>
<para>To allow CloudStack to use the Nicira NVP Plugin the network service provider needs to be enabled on the physical network. The following sequence of API calls will enable the network service provider</para>
<itemizedlist>
<listitem><para>addNetworkServiceProvider</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>name = "NiciraNvp"</para></listitem>
<listitem><para>physicalnetworkid = &lt;the uuid of the physical network&gt;</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>updateNetworkServiceProvider</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>id = &lt;the provider uuid returned by the previous call&gt;</para></listitem>
<listitem><para>state = "Enabled"</para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>The Nicira NVP provider is disabled by default. Navigate to the "Network Service Providers" configuration of the physical network with the STT isolation type. Navigate to the Nicira NVP provider and press the "Enable Provider" button.</para>
<note><para>CloudStack 4.0 does not have the UI interface to configure the Nicira NVP plugin. Configuration needs to be done using the API directly.</para></note>
<mediaobject>
<imageobject>
<imagedata fileref="./images/nvp-enable-provider.png" />
</imageobject>
<textobject>
<phrase>nvp-physical-network-stt.png: a screenshot of an enabled Nicira NVP provider</phrase>
</textobject>
</mediaobject>
</section>

View File

@ -40,6 +40,20 @@
</simplelist>
</revdescription>
</revision>
<revision>
<revnumber>1-0</revnumber>
<date>Wed May 22 2013</date>
<author>
<firstname>Hugo</firstname>
<surname>Trippaers</surname>
<email>hugo@apache.org</email>
</author>
<revdescription>
<simplelist>
<member>Documentation updated for &PRODUCT; 4.1.0</member>
</simplelist>
</revdescription>
</revision>
</revhistory>
</simpara>
</appendix>

View File

@ -23,29 +23,84 @@
<section id="Database-tables">
<title>Database tables</title>
<para>The following tables are added to the cloud database for the Nicira NVP Plugin</para>
<itemizedlist>
<listitem><para>nicira_nvp_nic_map, contains a mapping from nic to logical switch port</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>id</para></listitem>
<listitem><para>logicalswitch, uuid of the logical switch this port is connected to</para></listitem>
<listitem><para>logicalswitchport, uuid of the logical switch port for this nic</para></listitem>
<listitem><para>nic, the CloudStack uuid for this nic, reference to the nics table</para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem><para>external_nicira_nvp_devices, contains all configured devices</para></listitem>
<listitem>
<itemizedlist>
<listitem><para>id</para></listitem>
<listitem><para>uuid</para></listitem>
<listitem><para>physical_network_id, the physical network this device is configured on</para></listitem>
<listitem><para>provider_name, set to "NiciraNvp"</para></listitem>
<listitem><para>device_name, display name for this device</para></listitem>
<listitem><para>host_id, reference to the host table with the device configuration</para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<table>
<title>nicira_nvp_nic_map</title>
<tgroup cols="2">
<tbody>
<row>
<entry>id</entry>
<entry>auto incrementing id</entry>
</row>
<row>
<entry>logicalswitch</entry>
<entry>uuid of the logical switch this port is connected to</entry>
</row>
<row>
<entry>logicalswitchport</entry>
<entry>uuid of the logical switch port for this nic</entry>
</row>
<row>
<entry>nic</entry>
<entry>the &PRODUCT; uuid for this nic, reference to the nics table</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>external_nicira_nvp_devices</title>
<tgroup cols="2">
<tbody>
<row>
<entry>id</entry>
<entry>auto incrementing id</entry>
</row>
<row>
<entry>uuid</entry>
<entry>UUID identifying this device</entry>
</row>
<row>
<entry>physical_network_id</entry>
<entry>the physical network this device is configured on</entry>
</row>
<row>
<entry>provider_name</entry>
<entry>NiciraNVP</entry>
</row>
<row>
<entry>device_name</entry>
<entry>display name for this device</entry>
</row>
<row>
<entry>host_id</entry>
<entry>reference to the host table with the device configuration</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>nicira_nvp_router_map</title>
<tgroup cols="2">
<tbody>
<row>
<entry>id</entry>
<entry>auto incrementing id</entry>
</row>
<row>
<entry>logicalrouter_uuid</entry>
<entry>uuid of the logical router</entry>
</row>
<row>
<entry>network_id</entry>
<entry>id of the network this router is linked to</entry>
</row>
</tbody>
</tgroup>
</table>
<note>
<para>nicira_nvp_router_map is only available in &PRODUCT; 4.1 and above</para>
</note>
</section>

View File

@ -21,10 +21,13 @@
under the License.
-->
<chapter id="Using-the-Nicira-NVP-Plugin" >
<title>Using the Nicira NVP Plugin</title>
<title>Configuring the Nicira NVP Plugin</title>
<xi:include href="plugin-niciranvp-preparations.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-ui.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-provider.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-devicemanagement.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-physicalnet.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-provider.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="plugin-niciranvp-devicemanagement.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="plugin-niciranvp-networkofferings.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

View File

@ -1,11 +1,10 @@
<?xml version='1.0' encoding='utf-8' ?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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
@ -13,9 +12,7 @@
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
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
@ -23,9 +20,11 @@
specific language governing permissions and limitations
under the License.
-->
<chapter id="niciranvp-plugin-guide">
<title>Plugin Guide for the Nicira NVP Plugin</title>
<xi:include href="plugin-niciranvp-about.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="plugin-niciranvp-usage.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="plugin-niciranvp-troubleshooting.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<chapter id="Using-the-Nicira-NVP-Plugin-With_VPC" >
<title>Using the Nicira NVP plugin with VPC</title>
<xi:include href="plugin-niciranvp-vpcfeatures.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-vpcoffering.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="plugin-niciranvp-vpcnetworkoffering.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
</chapter>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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.
-->
<section id="vpc-features">
<title>Supported VPC features</title>
<para>The Nicira NVP plugin supports &PRODUCT; VPC to a certain extent. Starting with &PRODUCT; version 4.1 VPCs can be deployed using NVP isolated networks.</para>
<para>It is not possible to use a Nicira NVP Logical Router for as a VPC Router</para>
<para>It is not possible to connect a private gateway using a Nicira NVP Logical Switch</para>
</section>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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.
-->
<section id="nvp-vpc-network-offering">
<title>VPC Network Offerings</title>
<para>The VPC needs specific network offerings with the VPC flag enabled. Otherwise these network offerings are identical to regular network offerings. To allow VPC networks with a Nicira NVP isolated network the offerings need to support the Virtual Networking service with the NiciraNVP provider.</para>
<para>In a typical configuration two network offerings need to be created. One with the loadbalancing service enabled and one without loadbalancing.</para>
<table>
<title>VPC Network Offering with Loadbalancing</title>
<tgroup cols="2">
<thead>
<row>
<entry>Service</entry>
<entry>Provider</entry>
</row>
</thead>
<tbody>
<row>
<entry>VPN</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>DHCP</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>DNS</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>Load Balancer</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>User Data</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>Source NAT</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>Static NAT</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>Post Forwarding</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>NetworkACL</entry>
<entry>VpcVirtualRouter</entry>
</row>
<row>
<entry>Virtual Networking</entry>
<entry>NiciraNVP</entry>
</row>
</tbody>
</tgroup>
</table>
</section>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
%xinclude;
]>
<!-- 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.
-->
<section id="nvp-vpc-offering">
<title>VPC Offering with Nicira NVP</title>
<para>To allow a VPC to use the Nicira NVP plugin to provision networks, a new VPC offering needs to be created which allows the Virtual Networking service to be implemented by NiciraNVP.</para>
<para>This is not currently possible with the UI. The API does provide the proper calls to create a VPC offering with Virtual Networking enabled. However due to a limitation in the 4.1 API it is not possible to select the provider for this network service. To configure the VPC offering with the NiciraNVP provider edit the database table 'vpc_offering_service_map' and change the provider to NiciraNvp for the service 'Connectivity'</para>
<para>It is also possible to update the default VPC offering by adding a row to the
'vpc_offering_service_map' with service 'Connectivity' and provider 'NiciraNvp'</para>
<mediaobject>
<imageobject>
<imagedata fileref="./images/nvp-vpc-offering-edit.png" />
</imageobject>
<textobject>
<phrase>nvp-physical-network-stt.png: a screenshot of the mysql table.</phrase>
</textobject>
</mediaobject>
<note><para>When creating a new VPC offering please note that the UI does not allow you to select a VPC offering yet. The VPC needs to be created using the API with the offering UUID.</para></note>
</section>

View File

@ -0,0 +1,30 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
]>
<!-- 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.
-->
<section id="portable-ip">
<title>About Portable IP</title>
<para>Portable IPs in &PRODUCT; are nothing but elastic IPs that can be transferred across
geographically separated zones. As an administrator, you can provision a pool of portable IPs at
region level and are available for user consumption. The users can acquire portable IPs if admin
has provisioned portable public IPs at the region level they are part of. These IPs can be use
for any service within an advanced zone. You can also use portable IPs for EIP service in basic
zones. Additionally, a portable IP can be transferred from one network to another
network.</para>
</section>

View File

@ -21,10 +21,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
public abstract class AbstractScope implements Scope {
@Override
public boolean isSameScope(Scope scope) {
if (this.getScopeType() == scope.getScopeType() && this.getScopeId() == scope.getScopeId()) {
return true;
} else {
return false;
}
return this.getScopeType() == scope.getScopeType() && this.getScopeId().equals(scope.getScopeId());
}
}

View File

@ -24,6 +24,7 @@ import java.util.UUID;
import javax.inject.Inject;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMEntityVO;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO;
import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMEntityDao;
@ -60,6 +61,7 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl;
@ -111,6 +113,9 @@ public class VMEntityManagerImpl implements VMEntityManager {
@Inject
DeploymentPlanningManager _dpMgr;
@Inject
protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
@Override
public VMEntityVO loadVirtualMachine(String vmId) {
// TODO Auto-generated method stub
@ -123,6 +128,16 @@ public class VMEntityManagerImpl implements VMEntityManager {
}
protected boolean areAffinityGroupsAssociated(VirtualMachineProfile<? extends VirtualMachine> vmProfile) {
VirtualMachine vm = vmProfile.getVirtualMachine();
long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
if (vmGroupCount > 0) {
return true;
}
return false;
}
@Override
public String reserveVirtualMachine(VMEntityVO vmEntityVO, String plannerToUse, DeploymentPlan planToDeploy, ExcludeList exclude)
throws InsufficientCapacityException, ResourceUnavailableException {
@ -194,7 +209,8 @@ public class VMEntityManagerImpl implements VMEntityManager {
// call retry it.
return UUID.randomUUID().toString();
}else{
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId());
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile,
DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
}
}

View File

@ -16,22 +16,14 @@
// under the License.
package org.apache.cloudstack.engine.cloud.entity.api.db;
import java.util.Date;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.utils.db.GenericDao;
@Entity
@Table(name = "volume_reservation")
public class VolumeReservationVO implements InternalIdentity{
@ -42,7 +34,7 @@ public class VolumeReservationVO implements InternalIdentity{
private long id;
@Column(name = "vm_reservation_id")
private Long vmReservationId;
private long vmReservationId;
@Column(name = "vm_id")
private long vmId;
@ -53,10 +45,6 @@ public class VolumeReservationVO implements InternalIdentity{
@Column(name="pool_id")
private long poolId;
// VolumeId -> poolId
@Transient
Map<String, String> volumeReservationMap;
/**
* There should never be a public constructor for this class. Since it's
* only here to define the table for the DAO class.
@ -64,7 +52,7 @@ public class VolumeReservationVO implements InternalIdentity{
protected VolumeReservationVO() {
}
public VolumeReservationVO(long vmId, long volumeId, long poolId, Long vmReservationId) {
public VolumeReservationVO(long vmId, long volumeId, long poolId, long vmReservationId) {
this.vmId = vmId;
this.volumeId = volumeId;
this.poolId = poolId;
@ -80,7 +68,7 @@ public class VolumeReservationVO implements InternalIdentity{
return vmId;
}
public Long geVmReservationId() {
public long getVmReservationId() {
return vmReservationId;
}
@ -93,8 +81,4 @@ public class VolumeReservationVO implements InternalIdentity{
}
public Map<String,String> getVolumeReservation(){
return volumeReservationMap;
}
}

View File

@ -49,7 +49,7 @@ public class VolumeReservationDaoImpl extends GenericDaoBase<VolumeReservationVO
VmIdSearch.done();
VmReservationIdSearch = createSearchBuilder();
VmReservationIdSearch.and("vmReservationId", VmReservationIdSearch.entity().geVmReservationId(), SearchCriteria.Op.EQ);
VmReservationIdSearch.and("vmReservationId", VmReservationIdSearch.entity().getVmReservationId(), SearchCriteria.Op.EQ);
VmReservationIdSearch.done();
}

View File

@ -43,6 +43,7 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
AlertSearchByIdsAndType.and("type", AlertSearchByIdsAndType.entity().getType(), Op.EQ);
AlertSearchByIdsAndType.and("createdDateL", AlertSearchByIdsAndType.entity().getCreatedDate(), Op.LT);
AlertSearchByIdsAndType.and("data_center_id", AlertSearchByIdsAndType.entity().getDataCenterId(), Op.EQ);
AlertSearchByIdsAndType.and("archived", AlertSearchByIdsAndType.entity().getArchived(), Op.EQ);
AlertSearchByIdsAndType.done();
}
@ -53,6 +54,7 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
sc.addAnd("type", SearchCriteria.Op.EQ, Short.valueOf(type));
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, Long.valueOf(dataCenterId));
sc.addAnd("archived", SearchCriteria.Op.EQ, false);
if (podId != null) {
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
}
@ -74,6 +76,7 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
sc.addAnd("type", SearchCriteria.Op.EQ, Short.valueOf(type));
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, Long.valueOf(dataCenterId));
sc.addAnd("archived", SearchCriteria.Op.EQ, false);
if (podId != null) {
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
}
@ -101,6 +104,8 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
if(olderThan != null) {
sc.setParameters("createdDateL", olderThan);
}
sc.setParameters("archived", false);
boolean result = true;;
List<AlertVO> alerts = listBy(sc);
if (Ids != null && alerts.size() < Ids.size()) {
@ -135,6 +140,8 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
if(olderThan != null) {
sc.setParameters("createdDateL", olderThan);
}
sc.setParameters("archived", false);
boolean result = true;
List<AlertVO> alerts = listBy(sc);
if (ids != null && alerts.size() < ids.size()) {
@ -150,6 +157,7 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
if (oldTime == null) return null;
SearchCriteria<AlertVO> sc = createSearchCriteria();
sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime);
sc.addAnd("archived", SearchCriteria.Op.EQ, false);
return listIncludingRemovedBy(sc, null);
}

View File

@ -55,4 +55,6 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type);
Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
}

View File

@ -219,4 +219,20 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
return super.persist(resourceCountVO);
}
@Override
public long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType) {
SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
if (ownerType == ResourceOwnerType.Account) {
sc.setParameters("accountId", ownerId);
return remove(sc);
} else if (ownerType == ResourceOwnerType.Domain) {
sc.setParameters("domainId", ownerId);
return remove(sc);
}
return 0;
}
}

View File

@ -32,4 +32,6 @@ public interface ResourceLimitDao extends GenericDao<ResourceLimitVO, Long> {
ResourceCount.ResourceType getLimitType(String type);
ResourceLimitVO findByOwnerIdAndType(long ownerId, ResourceOwnerType ownerType, ResourceCount.ResourceType type);
long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType);
}

View File

@ -97,4 +97,18 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
return null;
}
}
@Override
public long removeEntriesByOwner(Long ownerId, ResourceOwnerType ownerType) {
SearchCriteria<ResourceLimitVO> sc = IdTypeSearch.create();
if (ownerType == ResourceOwnerType.Account) {
sc.setParameters("accountId", ownerId);
return remove(sc);
} else if (ownerType == ResourceOwnerType.Domain) {
sc.setParameters("domainId", ownerId);
return remove(sc);
}
return 0;
}
}

View File

@ -44,6 +44,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
CompletedEventSearch = createSearchBuilder();
CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ);
CompletedEventSearch.and("startId", CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ);
CompletedEventSearch.and("archived", CompletedEventSearch.entity().getArchived(), Op.EQ);
CompletedEventSearch.done();
ToArchiveOrDeleteEventSearch = createSearchBuilder();
@ -51,6 +52,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
ToArchiveOrDeleteEventSearch.and("type", ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ);
ToArchiveOrDeleteEventSearch.and("accountIds", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.IN);
ToArchiveOrDeleteEventSearch.and("createDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT);
ToArchiveOrDeleteEventSearch.and("archived", ToArchiveOrDeleteEventSearch.entity().getArchived(), Op.EQ);
ToArchiveOrDeleteEventSearch.done();
}
@ -64,6 +66,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
if (oldTime == null) return null;
SearchCriteria<EventVO> sc = createSearchCriteria();
sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime);
sc.addAnd("archived", SearchCriteria.Op.EQ, false);
return listIncludingRemovedBy(sc, null);
}
@ -72,6 +75,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
SearchCriteria<EventVO> sc = CompletedEventSearch.create();
sc.setParameters("state", State.Completed);
sc.setParameters("startId", startId);
sc.setParameters("archived", false);
return findOneIncludingRemovedBy(sc);
}
@ -90,6 +94,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
if (accountIds != null && !accountIds.isEmpty()) {
sc.setParameters("accountIds", accountIds.toArray(new Object[accountIds.size()]));
}
sc.setParameters("archived", false);
return search(sc, null);
}

View File

@ -198,7 +198,7 @@ public class ExternalLoadBalancerDeviceVO implements InternalIdentity, Identity
}
public void setGslbProvider(boolean gslbProvider) {
gslbProvider = gslbProvider;
this.gslbProvider = gslbProvider;
}
public void setGslbSitePublicIP(String gslbSitePublicIP) {

Some files were not shown because too many files have changed in this diff Show More