Merge branch 'master' into ui-vm-affinity

Conflicts:
	ui/scripts/instances.js
This commit is contained in:
Brian Federle 2013-04-24 16:02:56 -07:00
commit 25f2f0fcb7
89 changed files with 3467 additions and 1977 deletions

View File

@ -17,6 +17,7 @@
package com.cloud.region.ha;
import com.cloud.network.rules.LoadBalancer;
import org.apache.cloudstack.api.command.user.region.ha.gslb.*;
import java.util.List;
@ -44,4 +45,6 @@ public interface GlobalLoadBalancingRulesService {
List<GlobalLoadBalancerRule> listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd);
List<LoadBalancer> listSiteLoadBalancers(long gslbRuleId);
}

View File

@ -21,9 +21,22 @@ import java.util.Map;
import javax.naming.InsufficientResourcesException;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import com.cloud.dc.DataCenter;
@ -185,8 +198,8 @@ public interface UserVmService {
*/
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp,
String keyboard, List<Long> affinityGroupIdList)
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIp, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
@ -257,8 +270,8 @@ public interface UserVmService {
* @throws InsufficientResourcesException
*/
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, List<Long> securityGroupIdList,
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair,
Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
@ -327,8 +340,8 @@ public interface UserVmService {
*/
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**

View File

@ -335,6 +335,7 @@ public class ApiConstants {
public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate";
public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity";
public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated";
public static final String LOAD_BALANCER_RULE = "loadbalancerrule";
public static final String LOAD_BALANCER_RULE_LIST = "loadbalancerrulelist";
public static final String FIREWALL_DEVICE_ID = "fwdeviceid";
public static final String FIREWALL_DEVICE_NAME = "fwdevicename";

View File

@ -95,6 +95,11 @@ public abstract class BaseCmd {
private Object _responseObject = null;
private Map<String, String> fullUrlParams;
public enum HTTPMethod {
GET, POST, PUT, DELETE
}
private HTTPMethod httpMethod;
@Parameter(name = "response", type = CommandType.STRING)
private String responseType;
@ -140,6 +145,25 @@ public abstract class BaseCmd {
public void configure() {
}
public HTTPMethod getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(String method) {
if (method != null) {
if (method.equalsIgnoreCase("GET"))
httpMethod = HTTPMethod.GET;
else if (method.equalsIgnoreCase("PUT"))
httpMethod = HTTPMethod.PUT;
else if (method.equalsIgnoreCase("POST"))
httpMethod = HTTPMethod.POST;
else if (method.equalsIgnoreCase("DELETE"))
httpMethod = HTTPMethod.DELETE;
} else {
httpMethod = HTTPMethod.GET;
}
}
public String getResponseType() {
if (responseType == null) {
return RESPONSE_TYPE_XML;

View File

@ -16,9 +16,9 @@
// under the License.
package org.apache.cloudstack.api.command.admin.account;
import java.util.Collection;
import java.util.Map;
import com.cloud.user.Account;
import com.cloud.user.UserAccount;
import com.cloud.user.UserContext;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -27,14 +27,12 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
import com.cloud.user.UserAccount;
import com.cloud.user.UserContext;
import java.util.Collection;
import java.util.Map;
@APICommand(name = "createAccount", description="Creates an account", responseObject=UserResponse.class)
@APICommand(name = "createAccount", description="Creates an account", responseObject=AccountResponse.class)
public class CreateAccountCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateAccountCmd.class.getName());

View File

@ -58,7 +58,7 @@ public class MigrateVMCmd extends BaseAsyncCmd {
required=true, description="the ID of the virtual machine")
private Long virtualMachineId;
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.LONG, entityType=StoragePoolResponse.class,
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
required=false, description="Destination storage pool ID to migrate VM volumes to. Required for migrating the root disk volume")
private Long storageId;

View File

@ -128,7 +128,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
@Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, description="the hypervisor on which to deploy the virtual machine")
private String hypervisor;
@Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding.", length=2048)
@Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.", length=32768)
private String userData;
@Parameter(name=ApiConstants.SSH_KEYPAIR, type=CommandType.STRING, description="name of the ssh key pair used to login to the virtual machine")
@ -312,8 +312,8 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
throw new InvalidParameterValueException("Unable to translate and find entity with networkId: " + ips.get("networkid"));
}
}
String requestedIp = (String) ips.get("ip");
String requestedIpv6 = (String) ips.get("ipv6");
String requestedIp = ips.get("ip");
String requestedIpv6 = ips.get("ipv6");
if (requestedIpv6 != null) {
requestedIpv6 = requestedIpv6.toLowerCase();
}
@ -481,18 +481,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
} else {
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
displayName, diskOfferingId, size, group, getHypervisor(), this.getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
}
} else {
if (zone.isSecurityGroupEnabled()) {
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), this.getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
} else {
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
}
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
diskOfferingId, size, group, getHypervisor(), this.getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard, getAffinityGroupIdList());
}
}

View File

@ -75,10 +75,12 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="state of the virtual machine")
private String state;
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
description="the availability zone ID")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, description="the availability zone ID")
private Long zoneId;
@Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to")
private String zoneType;
@Parameter(name=ApiConstants.FOR_VIRTUAL_NETWORK, type=CommandType.BOOLEAN,
description="list by network type; true if need to list vms using Virtual Network, false otherwise")
private Boolean forVirtualNetwork;
@ -147,6 +149,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
public Boolean getForVirtualNetwork() {
return forVirtualNetwork;
}

View File

@ -61,7 +61,7 @@ public class UpdateVMCmd extends BaseCmd{
description="the ID of the OS type that best represents this VM.")
private Long osTypeId;
@Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding.", length=2048)
@Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.", length=32768)
private String userData;

View File

@ -67,6 +67,9 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
description="the ID of the availability zone")
private Long zoneId;
@Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to")
private String zoneType;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -100,6 +103,10 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -46,7 +46,10 @@ public class ClusterResponse extends BaseResponse {
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the cluster")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName("hypervisortype") @Param(description="the hypervisor type of the cluster")
private String hypervisorType;
@ -116,6 +119,10 @@ public class ClusterResponse extends BaseResponse {
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public String getClusterType() {
return clusterType;
}

View File

@ -42,6 +42,9 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the router")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName(ApiConstants.DNS1) @Param(description="the first DNS for the router")
private String dns1;
@ -186,6 +189,14 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView
this.zoneName = zoneName;
}
public String getZoneType() {
return zoneType;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setDns1(String dns1) {
this.dns1 = dns1;
}

View File

@ -23,6 +23,8 @@ import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import java.util.List;
@EntityReference(value= GlobalLoadBalancerRule.class)
public class GlobalLoadBalancerResponse extends BaseResponse implements ControlledEntityResponse {
@ -76,6 +78,10 @@ public class GlobalLoadBalancerResponse extends BaseResponse implements Controll
@Param(description = "the domain of the load balancer rule")
private String domainName;
@SerializedName(ApiConstants.LOAD_BALANCER_RULE)
@Param(description="List of load balancer rules that are part of GSLB rule", responseObject = LoadBalancerResponse.class)
private List<LoadBalancerResponse> siteLoadBalancers;
public void setRegionIdId(Integer regionId) {
this.regionId = regionId;
}
@ -130,4 +136,8 @@ public class GlobalLoadBalancerResponse extends BaseResponse implements Controll
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public void setSiteLoadBalancers(List<LoadBalancerResponse> siteLoadBalancers) {
this.siteLoadBalancers = siteLoadBalancers;
}
}

View File

@ -59,7 +59,10 @@ public class HostResponse extends BaseResponse {
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the host")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID of the host")
private String podId;
@ -209,6 +212,10 @@ public class HostResponse extends BaseResponse {
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setPodId(String podId) {
this.podId = podId;
}

View File

@ -66,6 +66,9 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone the network belongs to")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone the network belongs to")
private String zoneType;
@SerializedName("networkofferingid") @Param(description="network offering id the network is created from")
private String networkOfferingId;
@ -291,6 +294,10 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setCidr(String cidr) {
this.cidr = cidr;
}

View File

@ -36,10 +36,13 @@ public class PodResponse extends BaseResponse {
@SerializedName("zoneid") @Param(description="the Zone ID of the Pod")
private String zoneId;
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the Pod")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName("gateway") @Param(description="the gateway of the Pod")
private String gateway;
@ -86,6 +89,10 @@ public class PodResponse extends BaseResponse {
return zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}

View File

@ -93,6 +93,14 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
@Param(description = "the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage")
private Snapshot.State state;
@SerializedName(ApiConstants.ZONE_NAME)
@Param(description = "name of the availability zone")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE)
@Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class)
private List<ResourceTagResponse> tags;
@ -173,6 +181,14 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
this.projectName = projectName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setTags(List<ResourceTagResponse> tags) {
this.tags = tags;
}

View File

@ -38,12 +38,15 @@ public class StoragePoolResponse extends BaseResponse {
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the storage pool")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName("podid") @Param(description="the Pod ID of the storage pool")
private String podId;
@SerializedName("podname") @Param(description="the Pod name of the storage pool")
private String podName;
private String podName;
@SerializedName("name") @Param(description="the name of the storage pool")
private String name;
@ -126,6 +129,14 @@ public class StoragePoolResponse extends BaseResponse {
this.zoneName = zoneName;
}
public String getZoneType() {
return zoneType;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public String getPodId() {
return podId;
}

View File

@ -46,6 +46,9 @@ public class SystemVmResponse extends BaseResponse {
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the system VM")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName("dns1") @Param(description="the first DNS for the system VM")
private String dns1;
@ -150,7 +153,15 @@ public class SystemVmResponse extends BaseResponse {
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public String getZoneType() {
return zoneType;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public String getDns1() {
return dns1;
}

View File

@ -87,6 +87,9 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe
@SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone for this template")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone for this template")
private String zoneType;
@SerializedName(ApiConstants.STATUS) @Param(description="the status of the template")
private String status;
@ -156,6 +159,10 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}

View File

@ -47,6 +47,10 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity
@SerializedName(ApiConstants.ZONE_NAME)
@Param(description = "name of the availability zone")
private String zoneName;
@SerializedName(ApiConstants.ZONE_TYPE)
@Param(description = "network type of the availability zone")
private String zoneType;
@SerializedName(ApiConstants.TYPE)
@Param(description = "type of the disk volume (ROOT or DATADISK)")
@ -198,6 +202,10 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity
this.zoneName = zoneName;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public void setVolumeType(String volumeType) {
this.volumeType = volumeType;
}

View File

@ -1126,7 +1126,7 @@ public class S3Engine {
SBucketVO sbucket = bucketDao.getByName( bucketName );
if (sbucket == null) {
response.setResultCode(404);
response.setResultDescription("<Code>Bucket dosen't exists</Code><Message>Bucket " + bucketName + " does not exist</Message>");
response.setResultDescription("<Code>Bucket doesn't exists</Code><Message>Bucket " + bucketName + " does not exist</Message>");
return response;
}

File diff suppressed because it is too large Load Diff

View File

@ -18,9 +18,11 @@ package com.cloud.vm;
import java.util.HashMap;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@ -36,7 +38,8 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
@Column(name="iso_id", nullable=true, length=17)
private Long isoId = null;
@Column(name="user_data", updatable=true, nullable=true, length=2048)
@Column(name="user_data", updatable=true, nullable=true, length=32768)
@Basic(fetch = FetchType.LAZY)
private String userData;
@Column(name="display_name", updatable=true, nullable=true)
@ -119,6 +122,7 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
return details != null ? details.get(name) : null;
}
@Override
public void setAccountId(long accountId){
this.accountId = accountId;
}

5
debian/rules vendored
View File

@ -34,8 +34,9 @@ build: build-indep
build-indep: build-indep-stamp
build-indep-stamp: configure
mvn -Pawsapi package -DskipTests -Dsystemvm \
-Dcs.replace.properties=replace.properties.tmp
mvn package -Pawsapi -DskipTests -Dsystemvm \
-Dcs.replace.properties=replace.properties.tmp \
${ACS_BUILD_OPTS}
touch $@
clean:

View File

@ -3,37 +3,62 @@
<!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.
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="about-working-with-vms">
<title>About Working with Virtual Machines</title>
<para>&PRODUCT; provides administrators with complete control over the lifecycle of all guest VMs executing in the cloud. &PRODUCT; provides several guest management operations for end users and administrators. VMs may be stopped, started, rebooted, and destroyed.</para>
<para>Guest VMs have a name and group. VM names and groups are opaque to &PRODUCT; and are available for end users to organize their VMs. Each VM can have three names for use in different contexts. Only two of these names can be controlled by the user:</para>
<itemizedlist>
<listitem><para>Instance name a unique, immutable ID that is generated by &PRODUCT;, and can not be modified by the user. This name conforms to the requirements in IETF RFC 1123.</para></listitem>
<listitem><para>Display name the name displayed in the &PRODUCT; web UI. Can be set by the user. Defaults to instance name.</para></listitem>
<listitem><para>Name host name that the DHCP server assigns to the VM. Can be set by the user. Defaults to instance name</para></listitem>
</itemizedlist>
<para>Guest VMs can be configured to be Highly Available (HA). An HA-enabled VM is monitored by the system. If the system detects that the VM is down, it will attempt to restart the VM, possibly on a different host. For more information, see HA-Enabled Virtual Machines on </para>
<para>Each new VM is allocated one public IP address. When the VM is started, &PRODUCT; automatically creates a static NAT between this public IP address and the private IP address of the VM.</para>
<para>If elastic IP is in use (with the NetScaler load balancer), the IP address initially allocated to the new VM is not marked as elastic. The user must replace the automatically configured IP with a specifically acquired elastic IP, and set up the static NAT mapping between this new IP and the guest VMs private IP. The VMs original IP address is then released and returned to the pool of available public IPs.</para>
<para>&PRODUCT; cannot distinguish a guest VM that was shut down by the user (such as with the “shutdown” command in Linux) from a VM that shut down unexpectedly. If an HA-enabled VM is shut down from inside the VM, &PRODUCT; will restart it. To shut down an HA-enabled VM, you must go through the &PRODUCT; UI or API.</para>
<title>About Working with Virtual Machines</title>
<para>&PRODUCT; provides administrators with complete control over the lifecycle of all guest VMs
executing in the cloud. &PRODUCT; provides several guest management operations for end users and
administrators. VMs may be stopped, started, rebooted, and destroyed.</para>
<para>Guest VMs have a name and group. VM names and groups are opaque to &PRODUCT; and are
available for end users to organize their VMs. Each VM can have three names for use in different
contexts. Only two of these names can be controlled by the user:</para>
<itemizedlist>
<listitem>
<para>Instance name &ndash; a unique, immutable ID that is generated by &PRODUCT; and can not
be modified by the user. This name conforms to the requirements in IETF RFC 1123.</para>
</listitem>
<listitem>
<para>Display name &ndash; the name displayed in the &PRODUCT; web UI. Can be set by the user.
Defaults to instance name.</para>
</listitem>
<listitem>
<para>Name &ndash; host name that the DHCP server assigns to the VM. Can be set by the user.
Defaults to instance name</para>
</listitem>
</itemizedlist>
<note>
<para>You can append the display name of a guest VM to its internal name. For more information,
see <xref linkend="append-displayname-vms"/>.</para>
</note>
<para>Guest VMs can be configured to be Highly Available (HA). An HA-enabled VM is monitored by
the system. If the system detects that the VM is down, it will attempt to restart the VM,
possibly on a different host. For more information, see HA-Enabled Virtual Machines on </para>
<para>Each new VM is allocated one public IP address. When the VM is started, &PRODUCT;
automatically creates a static NAT between this public IP address and the private IP address of
the VM.</para>
<para>If elastic IP is in use (with the NetScaler load balancer), the IP address initially
allocated to the new VM is not marked as elastic. The user must replace the automatically
configured IP with a specifically acquired elastic IP, and set up the static NAT mapping between
this new IP and the guest VMs private IP. The VMs original IP address is then released and
returned to the pool of available public IPs. Optionally, you can also decide not to allocate a
public IP to a VM in an EIP-enabled Basic zone. For more information on Elastic IP, see <xref
linkend="elastic-ip"/>.</para>
<para>&PRODUCT; cannot distinguish a guest VM that was shut down by the user (such as with the
“shutdown” command in Linux) from a VM that shut down unexpectedly. If an HA-enabled VM is shut
down from inside the VM, &PRODUCT; will restart it. To shut down an HA-enabled VM, you must go
through the &PRODUCT; UI or API.</para>
</section>

View File

@ -0,0 +1,84 @@
<?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="append-displayname-vms">
<title>Appending a Display Name to the Guest VMs Internal Name</title>
<para>Every guest VM has an internal name. The host uses the internal name to identify the guest
VMs. &PRODUCT; gives you an option to provide a guest VM with a display name. You can set this
display name as the internal name so that the vCenter can use it to identify the guest VM. A new
global parameter, vm.instancename.flag, has now been added to achieve this functionality.</para>
<para>The default format of the internal name is
i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;, where instance.name is a global
parameter. However, If vm.instancename.flag is set to true, and if a display name is provided
during the creation of a guest VM, the display name is appended to the internal name of the
guest VM on the host. This makes the internal name format as
i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;displayName&gt;. The default value of vm.instancename.flag
is set to false. This feature is intended to make the correlation between instance names and
internal names easier in large data center deployments.</para>
<para>The following table explains how a VM name is displayed in different scenarios.</para>
<informaltable>
<tgroup cols="5" align="left" colsep="1" rowsep="1">
<colspec colnum="1" colname="c1" colwidth="1.0*"/>
<colspec colnum="2" colname="c2" colwidth="1.31*"/>
<colspec colnum="3" colname="c3" colwidth="1.07*"/>
<colspec colnum="4" colname="c4" colwidth="2.6*"/>
<colspec colnum="5" colname="c5" colwidth="4.65*"/>
<thead>
<row>
<entry><para>User-Provided Display Name </para></entry>
<entry><para>vm.instancename.flag</para></entry>
<entry><para>Hostname on the VM</para></entry>
<entry><para>Name on vCenter</para></entry>
<entry><para>Internal Name</para></entry>
</row>
</thead>
<tbody>
<row>
<entry><para>Yes</para></entry>
<entry><para>True</para></entry>
<entry><para>Display name</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-displayName</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-displayName</para></entry>
</row>
<row>
<entry><para>No</para></entry>
<entry><para>True</para></entry>
<entry><para>UUID</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
</row>
<row>
<entry><para>Yes</para></entry>
<entry><para>False</para></entry>
<entry><para>Display name</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
</row>
<row>
<entry><para>No</para></entry>
<entry><para>False</para></entry>
<entry><para>UUID</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
<entry><para>i-&lt;user_id&gt;-&lt;vm_id&gt;-&lt;instance.name&gt;</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>

View File

@ -101,6 +101,22 @@
</itemizedlist>
</entry>
</row>
<row>
<entry><para>UpdatePhysicalNetwork</para></entry>
<entry>
<para>Added the following request parameters:</para>
<itemizedlist>
<listitem>
<para>vlan (adds a new VLAN range to the existing VLAN range)</para>
</listitem>
<listitem>
<para>removelan (removes the specified VLAN range)</para>
</listitem>
</itemizedlist>
<note><para>The removevlan and vlan parameters can be used together. If the VLAN range that you are trying
to remove is in use, the operation will not succeed.</para></note>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>

View File

@ -193,6 +193,51 @@
<para condition="admin">For more information, see <xref linkend="system-service-offerings"/>.</para>
<para condition="install">For more information, see the Administration Guide.</para>
</listitem>
<listitem>
<para><emphasis role="bold">LB Isolation</emphasis>: Specify what type of load balancer
isolation you want for the network: Shared or Dedicated.</para>
<para><emphasis role="bold">Dedicated</emphasis>: If you select dedicated LB isolation, a
dedicated load balancer device is assigned for the network from the pool of dedicated
load balancer devices provisioned in the zone. If no sufficient dedicated load balancer
devices are available in the zone, network creation fails. Dedicated device is a good
choice for the high-traffic networks that make full use of the device's
resources.</para>
<para><emphasis role="bold">Shared</emphasis>: If you select shared LB isolation, a shared
load balancer device is assigned for the network from the pool of shared load balancer
devices provisioned in the zone. While provisioning &PRODUCT; picks the shared load
balancer device that is used by the least number of accounts. Once the device reaches
its maximum capacity, the device will not be allocated to a new account.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Mode</emphasis>: You can select either Inline mode or Side by
Side mode:</para>
<para><emphasis role="bold">Inline mode</emphasis>: Supported only for Juniper SRX
firewall and BigF5 load balancer devices. In inline mode, a firewall device is placed in
front of a load balancing device. The firewall acts as the gateway for all the incoming
traffic, then redirect the load balancing traffic to the load balancer behind it. The
load balancer in this case will not have the direct access to the public network. </para>
<para><emphasis role="bold">Side by Side</emphasis>: In side by side mode, a firewall
device is deployed in parallel with the load balancer device. So the traffic to the load
balancer public IP is not routed through the firewall, and therefore, is exposed to the
public network.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Associate Public IP</emphasis>: Select this option if you want
to assign a public IP address to the VMs deployed in the guest network. This option is
available only if</para>
<itemizedlist>
<listitem>
<para>Guest network is shared.</para>
</listitem>
<listitem>
<para>StaticNAT is enabled.</para>
</listitem>
<listitem>
<para>Elastic IP is enabled.</para>
</listitem>
</itemizedlist>
<para>For information on Elastic IP, see <xref linkend="elastic-ip"/>.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Redundant router capability</emphasis>. Available only when
Virtual Router is selected as the Source NAT provider. Select this option if you want to

90
docs/en-US/elastic-ip.xml Normal file
View File

@ -0,0 +1,90 @@
<?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="elastic-ip">
<title>About Elastic IP</title>
<para>Elastic IP (EIP) addresses are the IP addresses that are associated with an account, and act
as static IP addresses. The account owner has complete control over the Elastic IP addresses
that belong to the account. You can allocate an Elastic IP to a VM of your choice from the EIP
pool of your account. Later if required you can reassign the IP address to a different VM. This
feature is extremely helpful during VM failure. Instead of replacing the VM which is down, the
IP address can be reassigned to a new VM in your account. Elastic IP service provides Static NAT
(1:1) service in an EIP-enabled basic zone. The default network offering,
DefaultSharedNetscalerEIPandELBNetworkOffering, provides your network with EIP and ELB network
services if a NetScaler device is deployed in your zone. Similar to the public IP address,
Elastic IP addresses are also mapped to their associated private IP addresses by using Stactic
NAT.</para>
<para>The EIP work flow is as follows:</para>
<itemizedlist>
<listitem>
<para>When a user VM is deployed, a public IP is automatically acquired from the pool of
public IPs configured in the zone. This IP is owned by the VM's account.</para>
</listitem>
<listitem>
<para>Each VM will have its own private IP. When the user VM starts, Static NAT is provisioned
on the NetScaler device by using the Inbound Network Address Translation (INAT) and Reverse
NAT (RNAT) rules between the public IP and the private IP.</para>
<note>
<para>Inbound NAT (INAT) is a type of NAT supported by NetScaler, in which the destination
IP address is replaced in the packets from the public network, such as the Internet, with
the private IP address of a VM in the private network. Reverse NAT (RNAT) is a type of NAT
supported by NetScaler, in which the source IP address is replaced in the packets
generated by a VM in the private network with the public IP address.</para>
</note>
<para/>
</listitem>
<listitem>
<para>This default public IP will be released in two cases:</para>
<itemizedlist>
<listitem>
<para>When the VM is stopped. When the VM starts, it again receives a new public IP, not
necessarily the same one allocated initially, from the pool of Public IPs.</para>
</listitem>
<listitem>
<para>The user acquires a public IP (Elastic IP). This public IP is associated with the
account, but will not be mapped to any private IP. However, the user can enable Static
NAT to associate this IP to the private IP of a VM in the account. The Static NAT rule
for the public IP can be disabled at any time. When Static NAT is disabled, a new public
IP is allocated from the pool, which is not necessarily be the same one allocated
initially.</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>However, for the deployments where public IPs are limited resources, you have the
flexibility to choose not to allocate a public IP by default. You can use the Associate Public
IP option to turn on or off the automatic public IP assignment in the EIP-enabled Basic zones.
If you turn off the automatic public IP assignment while creating a network offering, only a
private IP is assigned to a VM when the VM is deployed with that network offering. Later, the
user can acquire an IP for the VM and enable static NAT.</para>
<para condition="admin">For more information on the Associate Public IP option, see <xref
linkend="creating-network-offerings"/>.</para>
<para condition="install">For more information on the Associate Public IP option, see the
Administration Guide.</para>
<note>
<para>The Associate Public IP feature is designed only for use with user VMs. The System VMs
continue to get both public IP and private by default, irrespective of the network offering
configuration.</para>
</note>
<para/>
<para>New deployments which use the default shared network offering with EIP and ELB services to
create a shared network in the Basic zone will continue allocating public IPs to each user
VM.</para>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

View File

@ -22,25 +22,66 @@
under the License.
-->
<section id="network-offerings">
<title>Network Offerings</title>
<note><para>For the most up-to-date list of supported network services, see the &PRODUCT; UI or call listNetworkServices.</para></note>
<para>A network offering is a named set of network services, such as:</para>
<itemizedlist>
<listitem><para>DHCP</para></listitem>
<listitem><para>DNS</para></listitem>
<listitem><para>Source NAT</para></listitem>
<listitem><para>Static NAT</para></listitem>
<listitem><para>Port Forwarding</para></listitem>
<listitem><para>Load Balancing</para></listitem>
<listitem><para>Firewall</para></listitem>
<listitem><para>VPN</para></listitem>
<listitem><para>Optional) Name one of several available providers to use for a given service, such as Juniper for the firewall</para></listitem>
<listitem><para>(Optional) Network tag to specify which physical network to use</para></listitem>
</itemizedlist>
<para>When creating a new VM, the user chooses one of the available network offerings, and that determines which network services the VM can use.</para>
<para>The &PRODUCT; administrator can create any number of custom network offerings, in addition to the default network offerings provided by &PRODUCT;. By creating multiple custom network offerings, you can set up your cloud to offer different classes of service on a single multi-tenant physical network. For example, while the underlying physical wiring may be the same for two tenants, tenant A may only need simple firewall protection for their website, while tenant B may be running a web server farm and require a scalable firewall solution, load balancing solution, and alternate networks for accessing the database backend.</para>
<note><para>If you create load balancing rules while using a network service offering that includes an external load balancer device such as NetScaler, and later change the network service offering to one that uses the &PRODUCT; virtual router, you must create a firewall rule on the virtual router for each of your existing load balancing rules so that they continue to function.</para></note>
<para>When creating a new virtual network, the &PRODUCT; administrator chooses which network offering to enable for that network. Each virtual network is associated with one network offering. A virtual network can be upgraded or downgraded by changing its associated network offering. If you do this, be sure to reprogram the physical network to match.</para>
<para>&PRODUCT; also has internal network offerings for use by &PRODUCT; system VMs. These network offerings are not visible to users but can be modified by administrators.</para>
<xi:include href="creating-network-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<title>Network Offerings</title>
<note>
<para>For the most up-to-date list of supported network services, see the &PRODUCT; UI or call
listNetworkServices.</para>
</note>
<para>A network offering is a named set of network services, such as:</para>
<itemizedlist>
<listitem>
<para>DHCP</para>
</listitem>
<listitem>
<para>DNS</para>
</listitem>
<listitem>
<para>Source NAT</para>
</listitem>
<listitem>
<para>Static NAT</para>
</listitem>
<listitem>
<para>Port Forwarding</para>
</listitem>
<listitem>
<para>Load Balancing</para>
</listitem>
<listitem>
<para>Firewall</para>
</listitem>
<listitem>
<para>VPN</para>
</listitem>
<listitem>
<para>(Optional) Name one of several available providers to use for a given service, such as
Juniper for the firewall</para>
</listitem>
<listitem>
<para>(Optional) Network tag to specify which physical network to use</para>
</listitem>
</itemizedlist>
<para>When creating a new VM, the user chooses one of the available network offerings, and that
determines which network services the VM can use.</para>
<para>The &PRODUCT; administrator can create any number of custom network offerings, in addition
to the default network offerings provided by &PRODUCT;. By creating multiple custom network
offerings, you can set up your cloud to offer different classes of service on a single
multi-tenant physical network. For example, while the underlying physical wiring may be the same
for two tenants, tenant A may only need simple firewall protection for their website, while
tenant B may be running a web server farm and require a scalable firewall solution, load
balancing solution, and alternate networks for accessing the database backend.</para>
<note>
<para>If you create load balancing rules while using a network service offering that includes an
external load balancer device such as NetScaler, and later change the network service offering
to one that uses the &PRODUCT; virtual router, you must create a firewall rule on the virtual
router for each of your existing load balancing rules so that they continue to
function.</para>
</note>
<para>When creating a new virtual network, the &PRODUCT; administrator chooses which network
offering to enable for that network. Each virtual network is associated with one network
offering. A virtual network can be upgraded or downgraded by changing its associated network
offering. If you do this, be sure to reprogram the physical network to match.</para>
<para>&PRODUCT; also has internal network offerings for use by &PRODUCT; system VMs. These network
offerings are not visible to users but can be modified by administrators.</para>
<xi:include href="creating-network-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>

View File

@ -45,6 +45,7 @@
<xi:include href="ip-load-balancing.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="dns-dhcp.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="vpn.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="elastic-ip.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="inter-vlan-routing.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="configure-vpc.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="persistent-network.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>

View File

@ -0,0 +1,68 @@
<?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="non-contiguous-vlan">
<title>Non Contiguous VLAN Ranges</title>
<para>&PRODUCT; provides you with the flexibility to add non contiguous VLAN ranges to your
network. The administrator can either update an existing VLAN range or add multiple non
contiguous VLAN ranges while creating a zone. You can also use the UpdatephysicalNetwork API to
extend the VLAN range.</para>
<section id="add-vlan-range">
<title>Adding a New VLAN Range</title>
<orderedlist>
<listitem><para>Log in to the CloudPlatform UI as an administrator or end user.</para></listitem>
<listitem>
<para>Ensure that the VLAN range does not already exist.</para>
</listitem>
<listitem>
<para>Check whether the new VLAN range overlaps with any existing ones. If overlaps, extend
the existing range. If does not overlap, add the new range.</para>
</listitem>
<listitem>
<para>In the left navigation, choose Infrastructure. On Zones, click View More, then click the zone to
which you want to work with.</para>
</listitem>
<listitem>
<para>Click Physical Network.</para>
</listitem>
<listitem>
<para>In the Guest node of the diagram, click Configure.</para>
</listitem>
<listitem>
<para>Click Add VLAN Ranges button <inlinemediaobject>
<imageobject>
<imagedata fileref="./images/add-vlan-icon.png"/>
</imageobject>
<textobject>
<phrase>add-vlan-ico.png: button to add a VLAN range.</phrase>
</textobject>
</inlinemediaobject></para>
<para>The Add VLAN Ranges dialog is displayed.</para>
</listitem>
<listitem>
<para>Specify the start and end of the VLAN range.</para>
</listitem>
<listitem>
<para>Click OK.</para>
</listitem>
</orderedlist>
</section>
</section>

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;
]>
@ -21,11 +21,10 @@
specific language governing permissions and limitations
under the License.
-->
<chapter id="set-up-network-for-users">
<title>Setting Up Networking for Users</title>
<xi:include href="networks-for-users-overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="about-virtual-networks.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="network-service-providers.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="network-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<title>Setting Up Networking for Users</title>
<xi:include href="networks-for-users-overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="about-virtual-networks.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="network-service-providers.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="network-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

View File

@ -3,58 +3,88 @@
<!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.
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="using-netscaler-load-balancers">
<title>About Using a NetScaler Load Balancer</title>
<para>Citrix NetScaler is supported as an external network element for load balancing in zones that use advanced networking (also called advanced zones). Set up an external load balancer when you want to provide load balancing through means other than &PRODUCT;s provided virtual router.</para>
<para>The NetScaler can be set up in direct (outside the firewall) mode. It must be added before any load balancing rules are deployed on guest VMs in the zone.</para>
<para>The functional behavior of the NetScaler with &PRODUCT; is the same as described in the &PRODUCT; documentation for using an F5 external load balancer. The only exception is that the F5 supports routing domains, and NetScaler does not. NetScaler can not yet be used as a firewall.</para>
<para>The Citrix NetScaler comes in three varieties. The following table summarizes how these variants are treated in &PRODUCT;.</para>
<informaltable>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry><para>NetScaler ADC Type</para></entry>
<entry><para>Description of Capabilities</para></entry>
<entry><para>&PRODUCT; Supported Features</para></entry>
</row>
</thead>
<tbody>
<row>
<entry><para>MPX</para></entry>
<entry><para>Physical appliance. Capable of deep packet inspection. Can act as application firewall and load balancer</para></entry>
<entry><para>In advanced zones, load balancer functionality fully supported without limitation. In basic zones, static NAT, elastic IP (EIP), and elastic load balancing (ELB) are also provided</para></entry>
</row>
<row>
<entry><para>VPX</para></entry>
<entry><para>Virtual appliance. Can run as VM on XenServer, ESXi, and Hyper-V hypervisors. Same functionality as MPX</para></entry>
<entry><para>Supported only on ESXi. Same functional support as for MPX. &PRODUCT; will treat VPX and MPX as the same device type</para></entry>
</row>
<row>
<entry><para>SDX</para></entry>
<entry><para>Physical appliance. Can create multiple fully isolated VPX instances on a single appliance to support multi-tenant usage</para></entry>
<entry><para>&PRODUCT; will dynamically provision, configure, and manage the lifecycle of VPX instances on the SDX. Provisioned instances are added into &PRODUCT; automatically no manual configuration by the administrator is required. Once a VPX instance is added into &PRODUCT;, it is treated the same as a VPX on an ESXi host.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<title>About Using a NetScaler Load Balancer</title>
<para>Citrix NetScaler is supported as an external network element for load balancing in zones
that use isolated networking in advanced zones. Set up an external load balancer when you want
to provide load balancing through means other than &PRODUCT;s provided virtual router.</para>
<note>
<para>In a Basic zone, load balancing service is supported only if Elastic IP or Elastic LB
services are enabled.</para>
</note>
<para>When NetScaler load balancer is used to provide EIP or ELB services in a Basic zone, ensure
that all guest VM traffic must enter and exit through the NetScaler device. When inbound traffic
goes through the NetScaler device, traffic is routed by using the NAT protocol depending on the
EIP/ELB configured on the public IP to the private IP. The traffic that is originated from the
guest VMs usually goes through the layer 3 router. To ensure that outbound traffic goes through
NetScaler device providing EIP/ELB, layer 3 router must have a policy-based routing. A
policy-based route must be set up so that all traffic originated from the guest VM's are
directed to NetScaler device. This is required to ensure that the outbound traffic from the
guest VM's is routed to a public IP by using NAT.For more information on Elastic IP, see <xref
linkend="elastic-ip"/>. </para>
<para>The NetScaler can be set up in direct (outside the firewall) mode. It must be added before
any load balancing rules are deployed on guest VMs in the zone.</para>
<para>The functional behavior of the NetScaler with &PRODUCT; is the same as described in the
&PRODUCT; documentation for using an F5 external load balancer. The only exception is that the
F5 supports routing domains, and NetScaler does not. NetScaler can not yet be used as a
firewall.</para>
<para>To install and enable an external load balancer for &PRODUCT; management, see <phrase
condition="install"><xref linkend="external-guest-lb-integration"/>.</phrase>
<phrase condition="admin">External Guest Load Balancer Integration in the Installation
Guide.</phrase>
</para>
<para>The Citrix NetScaler comes in three varieties. The following table summarizes how these
variants are treated in &PRODUCT;.</para>
<informaltable>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<thead>
<row>
<entry><para>NetScaler ADC Type</para></entry>
<entry><para>Description of Capabilities</para></entry>
<entry><para>&PRODUCT; Supported Features</para></entry>
</row>
</thead>
<tbody>
<row>
<entry><para>MPX</para></entry>
<entry><para>Physical appliance. Capable of deep packet inspection. Can act as application
firewall and load balancer</para></entry>
<entry><para>In advanced zones, load balancer functionality fully supported without
limitation. In basic zones, static NAT, elastic IP (EIP), and elastic load balancing
(ELB) are also provided.</para></entry>
</row>
<row>
<entry><para>VPX</para></entry>
<entry><para>Virtual appliance. Can run as VM on XenServer, ESXi, and Hyper-V hypervisors.
Same functionality as MPX</para></entry>
<entry><para>Supported on ESXi and XenServer. Same functional support as for MPX.
&PRODUCT; will treat VPX and MPX as the same device type.</para></entry>
</row>
<row>
<entry><para>SDX</para></entry>
<entry><para>Physical appliance. Can create multiple fully isolated VPX instances on a
single appliance to support multi-tenant usage</para></entry>
<entry><para>&PRODUCT; will dynamically provision, configure, and manage the life cycle of
VPX instances on the SDX. Provisioned instances are added into &PRODUCT; automatically
no manual configuration by the administrator is required. Once a VPX instance is
added into &PRODUCT;, it is treated the same as a VPX on an ESXi host.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>

View File

@ -28,6 +28,7 @@
<xi:include href="stopping-and-starting-vms.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="vm-snapshots.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="changing-vm-name-os-group.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="append-displayname-vms.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="changing-service-offering-for-vm.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="manual-live-migration.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="deleting-vms.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>

View File

@ -40,4 +40,6 @@
different physical NIC and use the same set of VLANs if you run out of VLANs. Another advantage
is that you can use the same set of IPs for different customers, each one with their own routers
and the guest networks on different physical NICs.</para>
<xi:include href="vlan-allocation-eg.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="non-contiguous-vlan.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>

View File

@ -24,8 +24,8 @@
<section id="vm-snapshots">
<title>Virtual Machine Snapshots for VMware</title>
<para>(VMware hosts only)
In addition to the existing &PRODUCT; ability to snapshot VM volumes,
you can now take a VM snapshot to preserve all of the VM's state and data.
In addition to the existing &PRODUCT; ability to snapshot individual VM volumes,
you can now take a VM snapshot to preserve all the VM's data volumes as well as (optionally) its CPU/memory state.
This is useful for quick restore of a VM.
For example, you can snapshot a VM, then make changes such as software upgrades.
If anything goes wrong, simply restore the VM to its previous state using the previously saved VM snapshot.
@ -51,7 +51,9 @@
<listitem><para>If a VM has some stored snapshots, you can't attach new volume to the VM
or delete any existing volumes.
If you change the volumes on the VM, it would become impossible to restore the VM snapshot
which was created with the previous volume structure.</para></listitem>
which was created with the previous volume structure.
If you want to attach a volume to such a VM, first delete its snapshots.
</para></listitem>
<listitem><para>VM snapshots which include both data volumes and memory can't be kept if you change the VM's
service offering. Any existing VM snapshots of this type will be discarded.</para></listitem>
<listitem>
@ -72,7 +74,7 @@
<section id="vm-snapshot-configure">
<title>Configuring VM Snapshots</title>
<para>The cloud administrator can use global configuration variables to control the behavior of VM snapshots.
To set these variables, go through the Global Settings are of the UI.</para>
To set these variables, go through the Global Settings area of the &PRODUCT; UI.</para>
<informaltable>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<thead>

View File

@ -75,6 +75,7 @@ if echo $VERSION | grep SNAPSHOT ; then
DEFPRE="-D_prerelease 1"
DEFREL="-D_rel SNAPSHOT"
else
REALVER=`echo $VERSION`
DEFVER="-D_ver $REALVER"
DEFPRE=
DEFREL=

View File

@ -519,7 +519,7 @@ setup_sshd(){
local ip=$1
local eth=$2
[ -f /etc/ssh/sshd_config ] && sed -i -e "s/^[#]*ListenAddress.*$/ListenAddress $ip/" /etc/ssh/sshd_config
sed -i "/3922/s/eth./$eth/" /etc/iptables/rules
sed -i "/3922/s/eth./$eth/" /etc/iptables/rules.v4
}
@ -691,7 +691,7 @@ setup_router() {
disable_rpfilter_domR
enable_fwding 1
chkconfig nfs-common off
cp /etc/iptables/iptables-router /etc/iptables/rules
cp /etc/iptables/iptables-router /etc/iptables/rules.v4
setup_sshd $ETH1_IP "eth1"
}
@ -763,7 +763,7 @@ EOF
enable_svc cloud 0
disable_rpfilter
enable_fwding 1
cp /etc/iptables/iptables-vpcrouter /etc/iptables/rules
cp /etc/iptables/iptables-vpcrouter /etc/iptables/rules.v4
setup_sshd $ETH0_IP "eth0"
cp /etc/vpcdnsmasq.conf /etc/dnsmasq.conf
cp /etc/cloud-nic.rules /etc/udev/rules.d/cloud-nic.rules
@ -789,7 +789,7 @@ setup_dhcpsrvr() {
enable_svc cloud 0
enable_fwding 0
chkconfig nfs-common off
cp /etc/iptables/iptables-router /etc/iptables/rules
cp /etc/iptables/iptables-router /etc/iptables/rules.v4
if [ "$SSHONGUEST" == "true" ]
then
setup_sshd $ETH0_IP "eth0"
@ -824,7 +824,7 @@ setup_secstorage() {
[ "$ETH2_IP" == "0.0.0.0" ] && public_ip=$ETH1_IP
echo "$public_ip $NAME" >> /etc/hosts
cp /etc/iptables/iptables-secstorage /etc/iptables/rules
cp /etc/iptables/iptables-secstorage /etc/iptables/rules.v4
if [ "$hyp" == "vmware" ]; then
setup_sshd $ETH1_IP "eth1"
else
@ -848,7 +848,7 @@ setup_console_proxy() {
[ "$ETH2_IP" == "0.0.0.0" ] && public_ip=$ETH1_IP
sed -i /gateway/d /etc/hosts
echo "$public_ip $NAME" >> /etc/hosts
cp /etc/iptables/iptables-consoleproxy /etc/iptables/rules
cp /etc/iptables/iptables-consoleproxy /etc/iptables/rules.v4
if [ "$hyp" == "vmware" ]; then
setup_sshd $ETH1_IP "eth1"
else
@ -873,7 +873,7 @@ setup_elbvm() {
[ "$ETH2_IP" == "0.0.0.0" ] || [ "$ETH2_IP" == "" ] && public_ip=$ETH0_IP
echo "$public_ip $NAME" >> /etc/hosts
cp /etc/iptables/iptables-elbvm /etc/iptables/rules
cp /etc/iptables/iptables-elbvm /etc/iptables/rules.v4
if [ "$SSHONGUEST" == "true" ]
then
setup_sshd $ETH0_IP "eth0"

View File

@ -61,13 +61,19 @@ public class LibvirtConnection {
static public Connect getConnectionByVmName(String vmName) throws LibvirtException {
HypervisorType[] hypervisors = new HypervisorType[] {HypervisorType.KVM, Hypervisor.HypervisorType.LXC};
for (HypervisorType hypervisor : hypervisors) {
Connect conn = LibvirtConnection.getConnectionByType(hypervisor.toString());
if (conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())) != null) {
return conn;
}
try {
Connect conn = LibvirtConnection.getConnectionByType(hypervisor.toString());
if (conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())) != null) {
return conn;
}
} catch (Exception e) {
s_logger.debug("can't find connection: " + hypervisor.toString() + ", for vm: " + vmName + ", continue");
}
}
s_logger.debug("can't find which hypervisor the vm used , then use the default hypervisor");
// return the default connection
return getConnection();
}

View File

@ -25,6 +25,8 @@ import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.region.ha.GlobalLoadBalancingRulesService;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
@ -388,6 +390,7 @@ public class ApiDBUtils {
static VpcProvisioningService _vpcProvSvc;
static AffinityGroupDao _affinityGroupDao;
static AffinityGroupJoinDao _affinityGroupJoinDao;
static GlobalLoadBalancingRulesService _gslbService;
@Inject private ManagementServer ms;
@Inject public AsyncJobManager asyncMgr;
@ -494,6 +497,7 @@ public class ApiDBUtils {
@Inject private VpcProvisioningService vpcProvSvc;
@Inject private AffinityGroupDao affinityGroupDao;
@Inject private AffinityGroupJoinDao affinityGroupJoinDao;
@Inject private GlobalLoadBalancingRulesService gslbService;
@PostConstruct
void init() {
@ -599,6 +603,7 @@ public class ApiDBUtils {
_vpcProvSvc = vpcProvSvc;
_affinityGroupDao = affinityGroupDao;
_affinityGroupJoinDao = affinityGroupJoinDao;
_gslbService = gslbService;
// Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
_statsCollector = StatsCollector.getInstance();
}
@ -1630,4 +1635,8 @@ public class ApiDBUtils {
public static AffinityGroupResponse fillAffinityGroupDetails(AffinityGroupResponse resp, AffinityGroupJoinVO group) {
return _affinityGroupJoinDao.setAffinityGroupResponse(resp, group);
}
public static List<? extends LoadBalancer> listSiteLoadBalancers(long gslbRuleId) {
return _gslbService.listSiteLoadBalancers(gslbRuleId);
}
}

View File

@ -27,7 +27,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
@ -56,21 +55,14 @@ import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.async.AsyncCommandQueued;
import com.cloud.async.AsyncJobManager;
import com.cloud.dao.EntityManager;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.UserContext;
import com.cloud.utils.DateUtil;
import com.cloud.utils.ReflectUtil;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.exception.CSExceptionErrorCode;
import com.cloud.utils.exception.CloudRuntimeException;
@ -160,7 +152,6 @@ public class ApiDispatcher {
}
}
}
cmd.execute();
}

View File

@ -443,6 +443,12 @@ public class ApiResponseHelper implements ResponseGenerator {
snapshotResponse.setVolumeId(volume.getUuid());
snapshotResponse.setVolumeName(volume.getName());
snapshotResponse.setVolumeType(volume.getVolumeType().name());
DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
if (zone != null) {
snapshotResponse.setZoneName(zone.getName());
snapshotResponse.setZoneType(zone.getNetworkType().toString());
}
}
snapshotResponse.setCreated(snapshot.getCreated());
snapshotResponse.setName(snapshot.getName());
@ -792,6 +798,14 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setId(globalLoadBalancerRule.getUuid());
populateOwner(response, globalLoadBalancerRule);
response.setObjectName("globalloadbalancer");
List<LoadBalancerResponse> siteLbResponses = new ArrayList<LoadBalancerResponse>();
List<? extends LoadBalancer> siteLoadBalaners = ApiDBUtils.listSiteLoadBalancers(globalLoadBalancerRule.getId());
for (LoadBalancer siteLb : siteLoadBalaners) {
LoadBalancerResponse siteLbResponse = createLoadBalancerResponse(siteLb);
siteLbResponses.add(siteLbResponse);
}
response.setSiteLoadBalancers(siteLbResponses);
return response;
}
@ -811,6 +825,7 @@ public class ApiResponseHelper implements ResponseGenerator {
if (zone != null) {
podResponse.setZoneId(zone.getUuid());
podResponse.setZoneName(zone.getName());
podResponse.setZoneType(zone.getNetworkType().toString());
}
podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize()));
podResponse.setStartIp(ipRange[0]);
@ -955,6 +970,7 @@ public class ApiResponseHelper implements ResponseGenerator {
if (dc != null) {
clusterResponse.setZoneId(dc.getUuid());
clusterResponse.setZoneName(dc.getName());
clusterResponse.setZoneType(dc.getNetworkType().toString());
}
clusterResponse.setHypervisorType(cluster.getHypervisorType().toString());
clusterResponse.setClusterType(cluster.getClusterType().toString());
@ -1159,6 +1175,7 @@ public class ApiResponseHelper implements ResponseGenerator {
if (zone != null) {
vmResponse.setZoneId(zone.getUuid());
vmResponse.setZoneName(zone.getName());
vmResponse.setZoneType(zone.getNetworkType().toString());
vmResponse.setDns1(zone.getDns1());
vmResponse.setDns2(zone.getDns2());
}
@ -1449,6 +1466,7 @@ public class ApiResponseHelper implements ResponseGenerator {
// Add the zone ID
templateResponse.setZoneId(datacenter.getUuid());
templateResponse.setZoneName(datacenter.getName());
templateResponse.setZoneType(datacenter.getNetworkType().toString());
}
boolean isAdmin = false;
@ -1737,6 +1755,7 @@ public class ApiResponseHelper implements ResponseGenerator {
if (datacenter != null) {
isoResponse.setZoneId(datacenter.getUuid());
isoResponse.setZoneName(datacenter.getName());
isoResponse.setZoneType(datacenter.getNetworkType().toString());
}
// If the user is an admin, add the template download status
@ -2354,6 +2373,7 @@ public class ApiResponseHelper implements ResponseGenerator {
if (zone != null) {
response.setZoneId(zone.getUuid());
response.setZoneName(zone.getName());
response.setZoneType(zone.getNetworkType().toString());
}
if (network.getPhysicalNetworkId() != null) {
PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId());

View File

@ -16,30 +16,51 @@
// under the License.
package com.cloud.api;
import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.async.AsyncCommandQueued;
import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationVO;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.event.ActionEventUtils;
import com.cloud.exception.*;
import com.cloud.user.*;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.cloudstack.acl.APIChecker;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
@ -61,7 +82,13 @@ import org.apache.cloudstack.api.response.ExceptionResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.region.RegionManager;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.*;
import org.apache.http.ConnectionClosedException;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpServerConnection;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.DefaultHttpResponseFactory;
@ -72,29 +99,54 @@ import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.*;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.*;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.async.AsyncCommandQueued;
import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationVO;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.event.ActionEventUtils;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.CloudAuthenticationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.RequestLimitException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.user.UserContext;
import com.cloud.user.UserVO;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
public class ApiServer implements HttpRequestHandler, ApiServerService {
@ -113,7 +165,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
@Inject List<PluggableService> _pluggableServices;
@Inject List<APIChecker> _apiAccessCheckers;
@Inject private RegionManager _regionMgr = null;
@Inject private final RegionManager _regionMgr = null;
private static int _workerCount = 0;
private static ApiServer s_instance = null;
@ -227,6 +279,9 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
parameterMap.put(param.getName(), new String[] { param.getValue() });
}
// Get the type of http method being used.
parameterMap.put("httpmethod", new String[] { request.getRequestLine().getMethod() });
// Check responseType, if not among valid types, fallback to JSON
if (!(responseType.equals(BaseCmd.RESPONSE_TYPE_JSON) || responseType.equals(BaseCmd.RESPONSE_TYPE_XML)))
responseType = BaseCmd.RESPONSE_TYPE_XML;
@ -254,10 +309,12 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
}
}
@Override
@SuppressWarnings("rawtypes")
public String handleRequest(Map params, String responseType, StringBuffer auditTrailSb) throws ServerApiException {
String response = null;
String[] command = null;
try {
command = (String[]) params.get("command");
if (command == null) {
@ -299,6 +356,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
cmdObj.configure();
cmdObj.setFullUrlParams(paramMap);
cmdObj.setResponseType(responseType);
cmdObj.setHttpMethod(paramMap.get("httpmethod").toString());
// This is where the command is either serialized, or directly dispatched
response = queueCommand(cmdObj, paramMap);
@ -530,6 +588,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
}
}
@Override
public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId) throws ServerApiException {
try {
String apiKey = null;
@ -692,10 +751,12 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
return false;
}
@Override
public Long fetchDomainId(String domainUUID) {
return _domainMgr.getDomain(domainUUID).getId();
}
@Override
public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress ,Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
// We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist
// we will default to ROOT
@ -770,11 +831,13 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials");
}
@Override
public void logoutUser(long userId) {
_accountMgr.logoutUser(Long.valueOf(userId));
return;
}
@Override
public boolean verifyUser(Long userId) {
User user = _accountMgr.getUserIncludingRemoved(userId);
Account account = null;
@ -931,6 +994,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
}
}
@Override
public String getSerializedApiError(int errorCode, String errorText, Map<String, Object[]> apiCommandParams, String responseType) {
String responseName = null;
Class<?> cmdClass = null;
@ -965,6 +1029,7 @@ public class ApiServer implements HttpRequestHandler, ApiServerService {
return responseText;
}
@Override
public String getSerializedApiError(ServerApiException ex, Map<String, Object[]> apiCommandParams, String responseType) {
String responseName = null;
Class<?> cmdClass = null;

View File

@ -21,6 +21,7 @@ import java.util.Map;
import javax.servlet.http.HttpSession;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.CloudAuthenticationException;
public interface ApiServerService {

View File

@ -299,8 +299,10 @@ public class ApiServlet extends HttpServlet {
auditTrailSb.insert(0, "(userId=" + UserContext.current().getCallerUserId() + " accountId="
+ UserContext.current().getCaller().getId() + " sessionId=" + (session != null ? session.getId() : null) + ")");
String response = _apiServer.handleRequest(params, responseType, auditTrailSb);
writeResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType);
// Add the HTTP method (GET/POST/PUT/DELETE) as well into the params map.
params.put("httpmethod", new String[] { req.getMethod() });
String response = _apiServer.handleRequest(params, responseType, auditTrailSb);
writeResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType);
} else {
if (session != null) {
try {

View File

@ -632,6 +632,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
c.addCriteria(Criteria.NAME, cmd.getInstanceName());
c.addCriteria(Criteria.STATE, cmd.getState());
c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId());
c.addCriteria(Criteria.DATACENTERTYPE, cmd.getZoneType());
c.addCriteria(Criteria.GROUPID, cmd.getGroupId());
c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, cmd.getForVirtualNetwork());
c.addCriteria(Criteria.NETWORKID, cmd.getNetworkId());
@ -680,7 +681,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Object name = c.getCriteria(Criteria.NAME);
Object state = c.getCriteria(Criteria.STATE);
Object notState = c.getCriteria(Criteria.NOTSTATE);
Object zone = c.getCriteria(Criteria.DATACENTERID);
Object zoneId = c.getCriteria(Criteria.DATACENTERID);
Object zoneType = c.getCriteria(Criteria.DATACENTERTYPE);
Object pod = c.getCriteria(Criteria.PODID);
Object hostId = c.getCriteria(Criteria.HOSTID);
Object hostName = c.getCriteria(Criteria.HOSTNAME);
@ -703,6 +705,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN);
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ);
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
@ -809,13 +812,18 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sc.setParameters("stateNIN", "Destroyed", "Expunging");
}
if (zone != null) {
sc.setParameters("dataCenterId", zone);
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
if (state == null) {
sc.setParameters("stateNEQ", "Destroyed");
}
}
if (zoneType != null) {
sc.setParameters("dataCenterType", zoneType);
}
if (pod != null) {
sc.setParameters("podId", pod);
@ -1514,6 +1522,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Map<String, String> tags = cmd.getTags();
Long zoneId = cmd.getZoneId();
String zoneType = cmd.getZoneType();
Long podId = null;
if (_accountMgr.isAdmin(caller.getType())) {
podId = cmd.getPodId();
@ -1541,6 +1550,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ);
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
// Only return volumes that are not destroyed
sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
@ -1600,6 +1610,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
if (zoneType != null) {
sc.setParameters("dataCenterType", zoneType);
}
if (podId != null) {
sc.setParameters("podId", podId);
}

View File

@ -148,6 +148,7 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
routerResponse.setDomainName(router.getDomainName());
routerResponse.setZoneName(router.getDataCenterName());
routerResponse.setZoneType(router.getDataCenterType());
routerResponse.setDns1(router.getDns1());
routerResponse.setDns2(router.getDns2());

View File

@ -99,6 +99,7 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
hostResponse.setOsCategoryId(host.getOsCategoryUuid());
hostResponse.setOsCategoryName(host.getOsCategoryName());
hostResponse.setZoneName(host.getZoneName());
hostResponse.setZoneType(host.getZoneType().toString());
hostResponse.setPodName(host.getPodName());
if ( host.getClusterId() > 0) {
hostResponse.setClusterName(host.getClusterName());

View File

@ -77,6 +77,7 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
poolResponse.setIpAddress(pool.getHostAddress());
poolResponse.setZoneId(pool.getZoneUuid());
poolResponse.setZoneName(pool.getZoneName());
poolResponse.setZoneType(pool.getZoneType());
if (pool.getPoolType() != null) {
poolResponse.setType(pool.getPoolType().toString());
}

View File

@ -86,7 +86,8 @@ public class VolumeJoinDaoImpl extends GenericDaoBase<VolumeJoinVO, Long> implem
volResponse.setZoneId(volume.getDataCenterUuid());
volResponse.setZoneName(volume.getDataCenterName());
volResponse.setZoneType(volume.getDataCenterType());
volResponse.setVolumeType(volume.getVolumeType().toString());
volResponse.setDeviceId(volume.getDeviceId());

View File

@ -101,6 +101,9 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
@Column(name="data_center_name")
private String dataCenterName = null;
@Column(name="data_center_type")
private String dataCenterType;
@Column(name="dns1")
private String dns1 = null;
@ -447,6 +450,15 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
this.dataCenterName = zoneName;
}
public String getDataCenterType() {
return dataCenterType;
}
public void setDataCenterType(String dataCenterType) {
this.dataCenterType = dataCenterType;
}
public Long getHostId() {
return hostId;

View File

@ -130,6 +130,9 @@ public class HostJoinVO extends BaseViewVO implements InternalIdentity, Identity
@Column(name="data_center_name")
private String zoneName;
@Column(name="data_center_type")
private String zoneType;
@Column(name="pod_id")
private long podId;
@ -231,7 +234,15 @@ public class HostJoinVO extends BaseViewVO implements InternalIdentity, Identity
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public String getZoneType() {
return zoneType;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public String getName() {
return name;
}

View File

@ -97,6 +97,9 @@ public class StoragePoolJoinVO extends BaseViewVO implements InternalIdentity, I
@Column(name="data_center_name")
private String zoneName;
@Column(name="data_center_type")
private String zoneType;
@Column(name="pod_id")
private long podId;
@ -283,6 +286,14 @@ public class StoragePoolJoinVO extends BaseViewVO implements InternalIdentity, I
this.zoneName = zoneName;
}
public String getZoneType() {
return zoneType;
}
public void setZoneType(String zoneType) {
this.zoneType = zoneType;
}
public long getPodId() {
return podId;
}

View File

@ -117,6 +117,9 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
@Column(name="data_center_name")
private String dataCenterName;
@Column(name="data_center_type")
private String dataCenterType;
@Column(name="vm_id")
private long vmId;
@ -1004,8 +1007,20 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
this.dataCenterName = dataCenterName;
}
public String getDataCenterType() {
return dataCenterType;
}
public void setDataCenterType(String dataCenterType) {
this.dataCenterType = dataCenterType;
}
public long getPodId() {
return podId;
}

View File

@ -16,7 +16,10 @@
// under the License.
package com.cloud.configuration;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
@ -26,6 +29,7 @@ import com.cloud.ha.HighAvailabilityManager;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.vpc.VpcManager;
import com.cloud.server.ManagementServer;
import com.cloud.storage.StorageManager;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
@ -34,10 +38,6 @@ import com.cloud.template.TemplateManager;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.snapshot.VMSnapshotManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public enum Config {
// Alert
@ -400,7 +400,10 @@ public enum Config {
VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", "default", " DNS name of the cloud", null);
CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", "default", " DNS name of the cloud", null),
BlacklistedRoutes("Advanced", VpcManager.class, String.class, "blacklisted.routes", null, "Routes that are blacklisted, can not be used for Static Routes creation for the VPC Private Gateway",
"routes", ConfigurationParameterScope.zone.toString());
private final String _category;
@ -532,6 +535,8 @@ public enum Config {
return "StorageManager";
} else if (_componentClass == TemplateManager.class) {
return "TemplateManager";
} else if (_componentClass == VpcManager.class) {
return "VpcManager";
}else {
return "none";
}

View File

@ -342,7 +342,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
DcDetailVO dcDetailVO = _zoneDetailsDao.findDetail(resourceId, name.toLowerCase());
if (dcDetailVO == null) {
dcDetailVO = new DcDetailVO(dcDetailVO.getId(), name, value);
dcDetailVO = new DcDetailVO(zone.getId(), name, value);
_zoneDetailsDao.persist(dcDetailVO);
} else {
dcDetailVO.setValue(value);
@ -584,6 +584,17 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (!NetUtils.verifyInstanceName(value)) {
return "Instance name can not contain hyphen, spaces and plus sign";
}
} else if (range.equals("routes")) {
String[] routes = value.split(",");
for (String route : routes) {
if (route != null) {
String routeToVerify = route.trim();
if (!NetUtils.isValidCIDR(routeToVerify)) {
throw new InvalidParameterValueException("Invalid value for blacklisted route: " + route + ". Valid format is list" +
" of cidrs separated by coma. Example: 10.1.1.0/24,192.168.0.0/24");
}
}
}
} else {
String[] options = range.split(",");
for (String option : options) {

View File

@ -77,4 +77,6 @@ public interface DataCenterDao extends GenericDao<DataCenterVO, Long> {
List<DataCenterVO> findZonesByDomainId(Long domainId, String keyword);
List<DataCenterVO> findByKeyword(String keyword);
List<DataCenterVO> listAllZones();
}

View File

@ -401,4 +401,12 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
txn.commit();
return result;
}
@Override
public List<DataCenterVO> listAllZones(){
SearchCriteria<DataCenterVO> sc = NameSearch.create();
List<DataCenterVO> dcs = listBy(sc);
return dcs;
}
}

View File

@ -725,7 +725,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl
}
}
if (lowestVlanTag == null) {
throw new InvalidParameterValueException ("The vlan tag dose not belong to any of the existing vlan ranges");
throw new InvalidParameterValueException ("The vlan tag does not belong to any of the existing vlan ranges");
}
return vlanTag - lowestVlanTag;
}

View File

@ -2529,7 +2529,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
if (temp == 0){
throw new InvalidParameterValueException("The vlan range you are trying to delete dose not exist.");
throw new InvalidParameterValueException("The vlan range you are trying to delete does not exist.");
}
if(existingRanges.get(i).first() > existingRanges.get(i).second()){
existingRanges.remove(i);

View File

@ -284,7 +284,7 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
}
}
if (lowestVlanTag == null) {
throw new InvalidParameterValueException ("The vlan tag dose not belong to any of the existing vlan ranges");
throw new InvalidParameterValueException ("The vlan tag does not belong to any of the existing vlan ranges");
}
return vlanTag - lowestVlanTag;
}

View File

@ -44,6 +44,7 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.event.ActionEvent;
@ -92,6 +93,7 @@ import com.cloud.offerings.NetworkOfferingServiceMapVO;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.org.Grouping;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.server.ConfigurationServer;
import com.cloud.server.ResourceTag.TaggedResourceType;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
@ -115,7 +117,6 @@ import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.ReservationContextImpl;
import com.cloud.vm.dao.DomainRouterDao;
@ -175,12 +176,16 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
ResourceLimitService _resourceLimitMgr;
@Inject
VpcServiceMapDao _vpcSrvcDao;
@Inject
DataCenterDao _dcDao;
@Inject
ConfigurationServer _configServer;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
private List<VpcProvider> vpcElements = null;
private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp);
int _cleanupInterval;
int _maxNetworks;
SearchBuilder<IPAddressVO> IpAddressSearch;
@ -1653,6 +1658,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR());
}
//3) Verify against blacklisted routes
if (isCidrBlacklisted(cidr, vpc.getZoneId())) {
throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
}
Transaction txn = Transaction.currentTxn();
txn.start();
@ -1673,6 +1683,23 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return newRoute;
}
protected boolean isCidrBlacklisted(String cidr, long zoneId) {
String routesStr = _configServer.getConfigValue(Config.BlacklistedRoutes.key(), Config.ConfigurationParameterScope.zone.toString(), zoneId);
if (routesStr != null && !routesStr.isEmpty()) {
String[] cidrBlackList = routesStr.split(",");
if (cidrBlackList != null && cidrBlackList.length > 0) {
for (String blackListedRoute : cidrBlackList) {
if (NetUtils.isNetworksOverlap(blackListedRoute, cidr)) {
return true;
}
}
}
}
return false;
}
@Override
public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(ListStaticRoutesCmd cmd) {
Long id = cmd.getId();

View File

@ -32,6 +32,7 @@ public class Criteria {
public static final String NOTSTATE = "notState";
public static final String STATE = "state";
public static final String DATACENTERID = "dataCenterId";
public static final String DATACENTERTYPE = "dataCenterType";
public static final String DESCRIPTION = "description";
public static final String PODID = "podId";
public static final String CLUSTERID = "clusterId";

View File

@ -32,15 +32,27 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.api.ApiDBUtils;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
@ -67,6 +79,7 @@ import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.async.AsyncJobManager;
@ -405,6 +418,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
private int _createprivatetemplatefromvolumewait;
private int _createprivatetemplatefromsnapshotwait;
private final int MAX_VM_NAME_LEN = 80;
private final int MAX_HTTP_GET_LENGTH = 2 * MAX_USER_DATA_LENGTH_BYTES;
private final int MAX_HTTP_POST_LENGTH = 16 * MAX_USER_DATA_LENGTH_BYTES;
@Inject
protected OrchestrationService _orchSrvc;
@ -1505,6 +1520,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@Override
public void run() {
UserContext.registerContext(_accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount(), null, false);
GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
try {
if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
@ -1604,7 +1620,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
if (userData != null) {
// check and replace newlines
userData = userData.replace("\\n", "");
validateUserData(userData);
validateUserData(userData, cmd.getHttpMethod());
// update userData on domain router.
updateUserdata = true;
} else {
@ -1926,10 +1942,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@Override
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group,
HypervisorType hypervisor, HTTPMethod httpmethod, String userData, String sshKeyPair,
Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard,
List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -1979,18 +1995,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller,
requestedIps, defaultIps, keyboard, affinityGroupIdList);
diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor,
caller, requestedIps, defaultIps, keyboard, affinityGroupIdList);
}
@Override
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
StorageUnavailableException,
ResourceAllocationException {
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId,
Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard,
List<Long> affinityGroupIdList) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
List<NetworkVO> networkList = new ArrayList<NetworkVO>();
@ -2096,15 +2111,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller,
requestedIps, defaultIps, keyboard, affinityGroupIdList);
diskSize, networkList, securityGroupIdList, group, httpmethod, userData, sshKeyPair, hypervisor,
caller, requestedIps, defaultIps, keyboard, affinityGroupIdList);
}
@Override
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList)
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2213,8 +2228,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps,
keyboard, affinityGroupIdList);
diskSize, networkList, null, group, httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps,
defaultIps, keyboard, affinityGroupIdList);
}
@ -2227,9 +2242,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
@DB @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId,
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, String userData,
String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod,
String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
_accountMgr.checkAccess(caller, null, true, owner);
@ -2337,7 +2352,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
// check if the user data is correct
validateUserData(userData);
validateUserData(userData, httpmethod);
// Find an SSH public key corresponding to the key pair name, if one is
// given
@ -2601,22 +2616,36 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
return vm;
}
private void validateUserData(String userData) {
private void validateUserData(String userData, HTTPMethod httpmethod) {
byte[] decodedUserData = null;
if (userData != null) {
if (!Base64.isBase64(userData)) {
throw new InvalidParameterValueException(
"User data is not base64 encoded");
}
if (userData.length() >= 2 * MAX_USER_DATA_LENGTH_BYTES) {
throw new InvalidParameterValueException(
"User data is too long");
}
decodedUserData = Base64.decodeBase64(userData.getBytes());
if (decodedUserData.length > MAX_USER_DATA_LENGTH_BYTES) {
throw new InvalidParameterValueException(
"User data is too long");
// If GET, use 4K. If POST, support upto 32K.
if (httpmethod.equals(HTTPMethod.GET)) {
if (userData.length() >= MAX_HTTP_GET_LENGTH) {
throw new InvalidParameterValueException(
"User data is too long for an http GET request");
}
decodedUserData = Base64.decodeBase64(userData.getBytes());
if (decodedUserData.length > MAX_HTTP_GET_LENGTH) {
throw new InvalidParameterValueException(
"User data is too long for GET request");
}
} else if (httpmethod.equals(HTTPMethod.POST)) {
if (userData.length() >= MAX_HTTP_POST_LENGTH) {
throw new InvalidParameterValueException(
"User data is too long for an http POST request");
}
decodedUserData = Base64.decodeBase64(userData.getBytes());
if (decodedUserData.length > MAX_HTTP_POST_LENGTH) {
throw new InvalidParameterValueException(
"User data is too long for POST request");
}
}
if (decodedUserData.length < 1) {
throw new InvalidParameterValueException(
"User data is too short");
@ -4096,7 +4125,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
needRestart = true;
}
List<VolumeVO> rootVols = _volsDao.findByInstance(vmId);
List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
if (rootVols.isEmpty()) {
InvalidParameterValueException ex = new InvalidParameterValueException(
"Can not find root volume for VM " + vm.getUuid());

View File

@ -1159,7 +1159,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_workDao.update(work.getId(), work);
}
return stateTransitTo(vm, Event.OperationSucceeded, null, null);
return stateTransitTo(vm, Event.OperationSucceeded, null);
} catch (NoTransitionException e) {
s_logger.warn(e.getMessage());
return false;

View File

@ -511,6 +511,20 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR
return null;
}
@Override
public List<LoadBalancer> listSiteLoadBalancers(long gslbRuleId) {
List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
List<LoadBalancer> siteLoadBalancers = new ArrayList<LoadBalancer>();
if (gslbLbMapVos != null) {
for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
siteLoadBalancers.add(loadBalancer);
}
return siteLoadBalancers;
}
return null;
}
private boolean applyGlobalLoadBalancerRuleConfig(long gslbRuleId, boolean revoke) throws ResourceUnavailableException {
GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);

View File

@ -23,9 +23,22 @@ import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.*;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.springframework.stereotype.Component;
@ -40,13 +53,13 @@ import com.cloud.dc.DataCenter;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network;
@ -59,10 +72,9 @@ import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
@Component
@Local(value = { UserVmManager.class, UserVmService.class })
@ -329,10 +341,10 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
@Override
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIp,
String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIp, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;
@ -340,21 +352,21 @@ public class MockUserVmManagerImpl extends ManagerBase implements UserVmManager,
@Override
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
StorageUnavailableException, ResourceAllocationException {
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize,
String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}
@Override
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
ResourceAllocationException {
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
IpAddresses defaultIps, String keyboard, List<Long> affinityGroupIdList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}

View File

@ -17,45 +17,54 @@
package com.cloud.vm;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyFloat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.util.List;
import com.cloud.api.ApiDBUtils;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.user.*;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.storage.StorageManager;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserContext;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao;
import static org.mockito.Mockito.*;
import com.cloud.vm.dao.VMInstanceDao;
public class UserVmManagerTest {
@ -127,7 +136,7 @@ public class UserVmManagerTest {
doReturn(VirtualMachine.State.Stopped).when(_vmMock).getState();
when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
when(_volsDao.findByInstanceAndType(314L,Volume.Type.ROOT)).thenReturn(_rootVols);
doReturn(false).when(_rootVols).isEmpty();
when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
doReturn(3L).when(_volumeMock).getTemplateId();
@ -150,7 +159,7 @@ public class UserVmManagerTest {
doReturn(VirtualMachine.State.Running).when(_vmMock).getState();
when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
when(_volsDao.findByInstanceAndType(314L,Volume.Type.ROOT)).thenReturn(_rootVols);
doReturn(false).when(_rootVols).isEmpty();
when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
doReturn(3L).when(_volumeMock).getTemplateId();
@ -174,7 +183,7 @@ public class UserVmManagerTest {
ConcurrentOperationException, ResourceAllocationException {
doReturn(VirtualMachine.State.Running).when(_vmMock).getState();
when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
when(_volsDao.findByInstanceAndType(314L,Volume.Type.ROOT)).thenReturn(_rootVols);
doReturn(false).when(_rootVols).isEmpty();
when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
doReturn(3L).when(_volumeMock).getTemplateId();
@ -361,6 +370,6 @@ public class UserVmManagerTest {
return serviceOffering;
}
}

View File

@ -20,24 +20,47 @@ import javax.inject.Inject;
import junit.framework.TestCase;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Test;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
public class UserVmDaoImplTest extends TestCase {
@Inject UserVmDao dao;
public void testPersist() {
dao.expunge(1000l);
UserVmVO vo = new UserVmVO(1000l, "instancename", "displayname", 1, HypervisorType.XenServer, 1, true, true, 1, 1, 1, "userdata", "name", null);
public void makeAndVerifyEntry(Long vmId, String instanceName, String displayName, long templateId, boolean userdataFlag, Hypervisor.HypervisorType hypervisor,
long guestOsId, boolean haEnabled, boolean limitCpuUse, long domainId, long accountId, long serviceOfferingId, String name, Long diskOfferingId) {
dao.expunge(vmId);
String userdata;
if (userdataFlag) {
// Generate large userdata to simulate 32k of random string data for userdata submitted through HTTP POST requests.
userdata = RandomStringUtils.randomAlphanumeric(32*1024);
} else {
// Generate normal sized userdata to simulate 2k of random string data.
userdata = RandomStringUtils.randomAlphanumeric(2*1024);
}
// Persist the data.
UserVmVO vo = new UserVmVO(vmId, instanceName, displayName, templateId, hypervisor, guestOsId, haEnabled, limitCpuUse, domainId, accountId, serviceOfferingId, userdata, name, diskOfferingId);
dao.persist(vo);
vo = dao.findById(1000l);
vo = dao.findById(vmId);
assert (vo.getType() == VirtualMachine.Type.User) : "Incorrect type " + vo.getType();
// Check whether the userdata matches what we generated.
assert (vo.getUserData().equals(userdata)) : "User data retrieved does not match userdata generated as input";
}
@Test
public void testPersist() {
Long vmId = 2222l;
makeAndVerifyEntry(vmId, "vm1", "vmdisp1", 1l, false, Hypervisor.HypervisorType.KVM, 1l, false, true, 1l, 1l, 1l, "uservm1", 1l);
makeAndVerifyEntry(vmId, "vm1", "vmdisp1", 1l, true, Hypervisor.HypervisorType.KVM, 1l, false, true, 1l, 1l, 1l, "uservm1", 1l);
}
}

View File

@ -0,0 +1,50 @@
// 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
// 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.vm.dao;
import java.io.IOException;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import com.cloud.utils.component.SpringComponentScanUtils;
@Configuration
@ComponentScan(basePackageClasses={
UserVmDaoImpl.class},
includeFilters={@Filter(value=UserVmDaoTestConfiguration.Library.class, type=FilterType.CUSTOM)},
useDefaultFilters=false
)
public class UserVmDaoTestConfiguration {
public static class Library implements TypeFilter {
@Override
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
mdr.getClassMetadata().getClassName();
ComponentScan cs = UserVmDaoTestConfiguration.class.getAnnotation(ComponentScan.class);
return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
}
}
}

View File

@ -0,0 +1,44 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for additional
information regarding copyright ownership. The ASF licenses this file to
you under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<!-- @DB support -->
<bean id="componentContext" class="com.cloud.utils.component.ComponentContext" />
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
<bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
<bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
<property name="Interceptors">
<list>
<ref bean="transactionContextBuilder" />
<ref bean="actionEventInterceptor" />
</list>
</property>
</bean>
<bean id="UVMTestConfiguration"
class="com.cloud.vm.dao.UserVmDaoTestConfiguration" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" >
<property name="requiredParameterValue" value="false" />
</bean>
</beans>

View File

@ -1291,6 +1291,17 @@ SecondaryStorageResource {
if (!found && f.getName().equals("template.properties")) {
found = true;
}
// KVM HA monitor makes a mess in the templates with its heartbeat tests
// Don't let this stop us from cleaning up the template
if (f.isDirectory() && f.getName().equals("KVMHA")) {
s_logger.debug("Deleting KVMHA directory contents from template location");
File[] haFiles = f.listFiles();
for (File haFile : haFiles) {
haFile.delete();
}
}
if (!f.delete()) {
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path "
+ relativeTemplatePath);
@ -1339,6 +1350,17 @@ SecondaryStorageResource {
if (!found && f.getName().equals("volume.properties")) {
found = true;
}
// KVM HA monitor makes a mess in the templates with its heartbeat tests
// Don't let this stop us from cleaning up the template
if (f.isDirectory() && f.getName().equals("KVMHA")) {
s_logger.debug("Deleting KVMHA directory contents from template location");
File[] haFiles = f.listFiles();
for (File haFile : haFiles) {
haFile.delete();
}
}
if (!f.delete()) {
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
+ relativeVolumePath);

View File

@ -296,6 +296,8 @@ UPDATE configuration SET value='KVM,XenServer,VMware,BareMetal,Ovm,LXC' WHERE na
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
VALUES (10, 'routing-10', 'SystemVM Template (LXC)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2', '2755de1f9ef2ce4d6f2bee2efbb4da92', 0, 'SystemVM Template (LXC)', 'QCOW2', 15, 0, 1, 'LXC');
ALTER TABLE `cloud`.`user_vm` MODIFY user_data TEXT(32768);
-- END: support for LXC
CREATE TABLE `cloud`.`vm_snapshots` (
@ -544,6 +546,336 @@ CREATE VIEW `cloud`.`affinity_group_view` AS
left join
`cloud`.`user_vm` ON user_vm.id = vm_instance.id;
DROP VIEW IF EXISTS `cloud`.`host_view`;
CREATE VIEW `cloud`.`host_view` AS
select
host.id,
host.uuid,
host.name,
host.status,
host.disconnected,
host.type,
host.private_ip_address,
host.version,
host.hypervisor_type,
host.hypervisor_version,
host.capabilities,
host.last_ping,
host.created,
host.removed,
host.resource_state,
host.mgmt_server_id,
host.cpus,
host.speed,
host.ram,
cluster.id cluster_id,
cluster.uuid cluster_uuid,
cluster.name cluster_name,
cluster.cluster_type,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
data_center.networktype data_center_type,
host_pod_ref.id pod_id,
host_pod_ref.uuid pod_uuid,
host_pod_ref.name pod_name,
host_tags.tag,
guest_os_category.id guest_os_category_id,
guest_os_category.uuid guest_os_category_uuid,
guest_os_category.name guest_os_category_name,
mem_caps.used_capacity memory_used_capacity,
mem_caps.reserved_capacity memory_reserved_capacity,
cpu_caps.used_capacity cpu_used_capacity,
cpu_caps.reserved_capacity cpu_reserved_capacity,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id
from
`cloud`.`host`
left join
`cloud`.`cluster` ON host.cluster_id = cluster.id
left join
`cloud`.`data_center` ON host.data_center_id = data_center.id
left join
`cloud`.`host_pod_ref` ON host.pod_id = host_pod_ref.id
left join
`cloud`.`host_details` ON host.id = host_details.id
and host_details.name = 'guest.os.category.id'
left join
`cloud`.`guest_os_category` ON guest_os_category.id = CONVERT( host_details.value , UNSIGNED)
left join
`cloud`.`host_tags` ON host_tags.host_id = host.id
left join
`cloud`.`op_host_capacity` mem_caps ON host.id = mem_caps.host_id
and mem_caps.capacity_type = 0
left join
`cloud`.`op_host_capacity` cpu_caps ON host.id = cpu_caps.host_id
and cpu_caps.capacity_type = 1
left join
`cloud`.`async_job` ON async_job.instance_id = host.id
and async_job.instance_type = 'Host'
and async_job.job_status = 0;
DROP VIEW IF EXISTS `cloud`.`volume_view`;
CREATE VIEW `cloud`.`volume_view` AS
select
volumes.id,
volumes.uuid,
volumes.name,
volumes.device_id,
volumes.volume_type,
volumes.size,
volumes.created,
volumes.state,
volumes.attached,
volumes.removed,
volumes.pod_id,
account.id account_id,
account.uuid account_uuid,
account.account_name account_name,
account.type account_type,
domain.id domain_id,
domain.uuid domain_uuid,
domain.name domain_name,
domain.path domain_path,
projects.id project_id,
projects.uuid project_uuid,
projects.name project_name,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
data_center.networktype data_center_type,
vm_instance.id vm_id,
vm_instance.uuid vm_uuid,
vm_instance.name vm_name,
vm_instance.state vm_state,
vm_instance.vm_type,
user_vm.display_name vm_display_name,
volume_host_ref.size volume_host_size,
volume_host_ref.created volume_host_created,
volume_host_ref.format,
volume_host_ref.download_pct,
volume_host_ref.download_state,
volume_host_ref.error_str,
disk_offering.id disk_offering_id,
disk_offering.uuid disk_offering_uuid,
disk_offering.name disk_offering_name,
disk_offering.display_text disk_offering_display_text,
disk_offering.use_local_storage,
disk_offering.system_use,
storage_pool.id pool_id,
storage_pool.uuid pool_uuid,
storage_pool.name pool_name,
cluster.hypervisor_type,
vm_template.id template_id,
vm_template.uuid template_uuid,
vm_template.extractable,
vm_template.type template_type,
resource_tags.id tag_id,
resource_tags.uuid tag_uuid,
resource_tags.key tag_key,
resource_tags.value tag_value,
resource_tags.domain_id tag_domain_id,
resource_tags.account_id tag_account_id,
resource_tags.resource_id tag_resource_id,
resource_tags.resource_uuid tag_resource_uuid,
resource_tags.resource_type tag_resource_type,
resource_tags.customer tag_customer,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id
from
`cloud`.`volumes`
inner join
`cloud`.`account` ON volumes.account_id = account.id
inner join
`cloud`.`domain` ON volumes.domain_id = domain.id
left join
`cloud`.`projects` ON projects.project_account_id = account.id
left join
`cloud`.`data_center` ON volumes.data_center_id = data_center.id
left join
`cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id
left join
`cloud`.`user_vm` ON user_vm.id = vm_instance.id
left join
`cloud`.`volume_host_ref` ON volumes.id = volume_host_ref.volume_id
and volumes.data_center_id = volume_host_ref.zone_id
left join
`cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id
left join
`cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id
left join
`cloud`.`cluster` ON storage_pool.cluster_id = cluster.id
left join
`cloud`.`vm_template` ON volumes.template_id = vm_template.id
left join
`cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id
and resource_tags.resource_type = 'Volume'
left join
`cloud`.`async_job` ON async_job.instance_id = volumes.id
and async_job.instance_type = 'Volume'
and async_job.job_status = 0;
DROP VIEW IF EXISTS `cloud`.`storage_pool_view`;
CREATE VIEW `cloud`.`storage_pool_view` AS
select
storage_pool.id,
storage_pool.uuid,
storage_pool.name,
storage_pool.status,
storage_pool.path,
storage_pool.pool_type,
storage_pool.host_address,
storage_pool.created,
storage_pool.removed,
storage_pool.capacity_bytes,
storage_pool.scope,
cluster.id cluster_id,
cluster.uuid cluster_uuid,
cluster.name cluster_name,
cluster.cluster_type,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
data_center.networktype data_center_type,
host_pod_ref.id pod_id,
host_pod_ref.uuid pod_uuid,
host_pod_ref.name pod_name,
storage_pool_details.name tag,
op_host_capacity.used_capacity disk_used_capacity,
op_host_capacity.reserved_capacity disk_reserved_capacity,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id
from
`cloud`.`storage_pool`
left join
`cloud`.`cluster` ON storage_pool.cluster_id = cluster.id
left join
`cloud`.`data_center` ON storage_pool.data_center_id = data_center.id
left join
`cloud`.`host_pod_ref` ON storage_pool.pod_id = host_pod_ref.id
left join
`cloud`.`storage_pool_details` ON storage_pool_details.pool_id = storage_pool.id
and storage_pool_details.value = 'true'
left join
`cloud`.`op_host_capacity` ON storage_pool.id = op_host_capacity.host_id
and op_host_capacity.capacity_type = 3
left join
`cloud`.`async_job` ON async_job.instance_id = storage_pool.id
and async_job.instance_type = 'StoragePool'
and async_job.job_status = 0;
DROP VIEW IF EXISTS `cloud`.`domain_router_view`;
CREATE VIEW `cloud`.`domain_router_view` AS
select
vm_instance.id id,
vm_instance.name name,
account.id account_id,
account.uuid account_uuid,
account.account_name account_name,
account.type account_type,
domain.id domain_id,
domain.uuid domain_uuid,
domain.name domain_name,
domain.path domain_path,
projects.id project_id,
projects.uuid project_uuid,
projects.name project_name,
vm_instance.uuid uuid,
vm_instance.created created,
vm_instance.state state,
vm_instance.removed removed,
vm_instance.pod_id pod_id,
vm_instance.instance_name instance_name,
host_pod_ref.uuid pod_uuid,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
data_center.networktype data_center_type,
data_center.dns1 dns1,
data_center.dns2 dns2,
data_center.ip6_dns1 ip6_dns1,
data_center.ip6_dns2 ip6_dns2,
host.id host_id,
host.uuid host_uuid,
host.name host_name,
vm_template.id template_id,
vm_template.uuid template_uuid,
service_offering.id service_offering_id,
disk_offering.uuid service_offering_uuid,
disk_offering.name service_offering_name,
nics.id nic_id,
nics.uuid nic_uuid,
nics.network_id network_id,
nics.ip4_address ip_address,
nics.ip6_address ip6_address,
nics.ip6_gateway ip6_gateway,
nics.ip6_cidr ip6_cidr,
nics.default_nic is_default_nic,
nics.gateway gateway,
nics.netmask netmask,
nics.mac_address mac_address,
nics.broadcast_uri broadcast_uri,
nics.isolation_uri isolation_uri,
vpc.id vpc_id,
vpc.uuid vpc_uuid,
networks.uuid network_uuid,
networks.name network_name,
networks.network_domain network_domain,
networks.traffic_type traffic_type,
networks.guest_type guest_type,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id,
domain_router.template_version template_version,
domain_router.scripts_version scripts_version,
domain_router.is_redundant_router is_redundant_router,
domain_router.redundant_state redundant_state,
domain_router.stop_pending stop_pending
from
`cloud`.`domain_router`
inner join
`cloud`.`vm_instance` ON vm_instance.id = domain_router.id
inner join
`cloud`.`account` ON vm_instance.account_id = account.id
inner join
`cloud`.`domain` ON vm_instance.domain_id = domain.id
left join
`cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id
left join
`cloud`.`projects` ON projects.project_account_id = account.id
left join
`cloud`.`data_center` ON vm_instance.data_center_id = data_center.id
left join
`cloud`.`host` ON vm_instance.host_id = host.id
left join
`cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id
left join
`cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id
left join
`cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id
left join
`cloud`.`volumes` ON vm_instance.id = volumes.instance_id
left join
`cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id
left join
`cloud`.`nics` ON vm_instance.id = nics.instance_id
left join
`cloud`.`networks` ON nics.network_id = networks.id
left join
`cloud`.`vpc` ON domain_router.vpc_id = vpc.id
left join
`cloud`.`async_job` ON async_job.instance_id = vm_instance.id
and async_job.instance_type = 'DomainRouter'
and async_job.job_status = 0;
CREATE TABLE `cloud`.`external_cisco_vnmc_devices` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uuid` varchar(255) UNIQUE,
@ -777,4 +1109,4 @@ CREATE VIEW `cloud`.`account_view` AS
and async_job.instance_type = 'Account'
and async_job.job_status = 0;
alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL;
alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL;

View File

@ -91,7 +91,7 @@ class TestDeployVmWithAffinityGroup(cloudstackTestCase):
domainid=cls.domain.id
)
cls.services["account"] = cls.account.account.name
cls.services["account"] = cls.account.name
cls.service_offering = ServiceOffering.create(
cls.api_client,
@ -120,8 +120,8 @@ class TestDeployVmWithAffinityGroup(cloudstackTestCase):
self.api_client,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.account.name,
domainid=self.account.account.domainid,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
affinitygroupnames=[self.ag.name]
)
@ -153,8 +153,8 @@ class TestDeployVmWithAffinityGroup(cloudstackTestCase):
self.api_client,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.account.name,
domainid=self.account.account.domainid,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
affinitygroupnames=[self.ag.name]
)

View File

@ -0,0 +1,144 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.integration.lib.base import *
from marvin.integration.lib.common import get_template, get_zone, list_virtual_machines, cleanup_resources
from nose.plugins.attrib import attr
import random
import string
class Services:
def __init__(self):
self.services = {
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "test",
"password": "password",
},
"virtual_machine": {
"displayname": "Test VM",
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"ostype": 'CentOS 5.3 (64-bit)',
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100,
"memory": 256,
},
}
class TestDeployVmWithUserData(cloudstackTestCase):
"""Tests for UserData
"""
@classmethod
def setUpClass(cls):
cls.apiClient = super(TestDeployVmWithUserData, cls).getClsTestClient().getApiClient()
cls.services = Services().services
cls.zone = get_zone(cls.apiClient, cls.services)
if cls.zone.localstorageenabled:
#For devcloud since localstroage is enabled
cls.services["service_offering"]["storagetype"] = "local"
cls.service_offering = ServiceOffering.create(
cls.apiClient,
cls.services["service_offering"]
)
cls.account = Account.create(cls.apiClient, services=cls.services["account"])
cls.template = get_template(
cls.apiClient,
cls.zone.id,
cls.services["ostype"]
)
cls.debug("Successfully created account: %s, id: \
%s" % (cls.account.name,\
cls.account.id))
cls.cleanup = [cls.account]
# Generate userdata of 2500 bytes. This is larger than the 2048 bytes limit.
# CS however allows for upto 4K bytes in the code. So this must succeed.
# Overall, the query length must not exceed 4K, for then the json decoder
# will fail this operation at the marvin client side itcls.
user_data = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(2500))
cls.services["virtual_machine"]["userdata"] = user_data
@attr(tags=["simulator", "devcloud", "basic", "advanced"])
def test_deployvm_userdata_post(self):
"""Test userdata as POST, size > 2k
"""
deployVmResponse = VirtualMachine.create(
self.apiClient,
services=self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
templateid=self.template.id,
zoneid=self.zone.id,
method='POST'
)
vms = list_virtual_machines(
self.apiClient,
account=self.account.name,
domainid=self.account.domainid
)
self.assert_(len(vms) > 0, "There are no Vms deployed in the account %s" % self.account.name)
vm = vms[0]
self.assert_(vm.id == str(deployVmResponse.id), "Vm deployed is different from the test")
self.assert_(vm.state == "Running", "VM is not in Running state")
@attr(tags=["simulator", "devcloud", "basic", "advanced"])
def test_deployvm_userdata(self):
"""Test userdata as GET, size > 2k
"""
deployVmResponse = VirtualMachine.create(
self.apiClient,
services=self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
templateid=self.template.id,
zoneid=self.zone.id
)
vms = list_virtual_machines(
self.apiClient,
account=self.account.name,
domainid=self.account.domainid
)
self.assert_(len(vms) > 0, "There are no Vms deployed in the account %s" % self.account.name)
vm = vms[0]
self.assert_(vm.id == str(deployVmResponse.id), "Vm deployed is different from the test")
self.assert_(vm.state == "Running", "VM is not in Running state")
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.apiClient, cls.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)

View File

@ -139,8 +139,8 @@ class TesDedicatePublicIPRange(cloudstackTestCase):
dedicate_public_ip_range_response = PublicIpRange.dedicate(
self.apiclient,
self.public_ip_range.vlan.id,
account=self.account.account.name,
domainid=self.account.account.domainid
account=self.account.name,
domainid=self.account.domainid
)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
@ -149,7 +149,7 @@ class TesDedicatePublicIPRange(cloudstackTestCase):
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.account,
self.account.account.name,
self.account.name,
"Check account name is in listVlanIpRanges as the account public ip range is dedicated to"
)

View File

@ -172,8 +172,8 @@ class TestDeployVM(cloudstackTestCase):
cls.virtual_machine = VirtualMachine.create(
cls.apiclient,
cls.services["small"],
accountid=cls.account.account.name,
domainid=cls.account.account.domainid,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id,
mode=cls.services['mode']
)
@ -250,12 +250,12 @@ class TestDeployVM(cloudstackTestCase):
3. Has a linklocalip, publicip and a guestip
@return:
"""
routers = list_routers(self.apiclient, account=self.account.account.name)
routers = list_routers(self.apiclient, account=self.account.name)
self.assertTrue(len(routers) > 0, msg = "No virtual router found")
router = routers[0]
self.assertEqual(router.state, 'Running', msg="Router is not in running state")
self.assertEqual(router.account, self.account.account.name, msg="Router does not belong to the account")
self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
#Has linklocal, public and guest ips
self.assertIsNotNone(router.linklocalip, msg="Router has no linklocal ip")
@ -271,12 +271,12 @@ class TestDeployVM(cloudstackTestCase):
2. is in the account the VM was deployed in
@return:
"""
routers = list_routers(self.apiclient, account=self.account.account.name)
routers = list_routers(self.apiclient, account=self.account.name)
self.assertTrue(len(routers) > 0, msg = "No virtual router found")
router = routers[0]
self.assertEqual(router.state, 'Running', msg="Router is not in running state")
self.assertEqual(router.account, self.account.account.name, msg="Router does not belong to the account")
self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
def tearDown(self):
pass
@ -334,24 +334,24 @@ class TestVMLifeCycle(cloudstackTestCase):
cls.small_virtual_machine = VirtualMachine.create(
cls.api_client,
cls.services["small"],
accountid=cls.account.account.name,
domainid=cls.account.account.domainid,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.small_offering.id,
mode=cls.services["mode"]
)
cls.medium_virtual_machine = VirtualMachine.create(
cls.api_client,
cls.services["medium"],
accountid=cls.account.account.name,
domainid=cls.account.account.domainid,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.medium_offering.id,
mode=cls.services["mode"]
)
cls.virtual_machine = VirtualMachine.create(
cls.api_client,
cls.services["small"],
accountid=cls.account.account.name,
domainid=cls.account.account.domainid,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.small_offering.id,
mode=cls.services["mode"]
)
@ -939,8 +939,8 @@ class TestVMLifeCycle(cloudstackTestCase):
iso = Iso.create(
self.apiclient,
self.services["iso"],
account=self.account.account.name,
domainid=self.account.account.domainid
account=self.account.name,
domainid=self.account.domainid
)
self.debug("Successfully created ISO with ID: %s" % iso.id)

View File

@ -110,16 +110,15 @@ class cloudConnection(object):
self.logging.info("Computed Signature by Marvin: %s" % signature)
return signature
def request(self, command, auth=True, payload={}, data={}):
def request(self, command, auth=True, payload={}, method='GET'):
"""
Makes requests using auth or over integration port
@param command: cloudstack API command name
eg: deployVirtualMachineCommand
@param auth: Authentication (apikey,secretKey) => True
else False for integration.api.port
@param payload: GET param data composed as a dictionary
of key,value pairs
@param data: POST data as a dictionary
@param payload: request data composed as a dictionary
@param method: GET/POST via HTTP
@return:
"""
payload["command"] = command
@ -131,9 +130,8 @@ class cloudConnection(object):
payload["signature"] = signature
try:
if data:
response = requests.get(self.baseurl, params=payload,
data=data)
if method == 'POST':
response = requests.post(self.baseurl, params=payload)
else:
response = requests.get(self.baseurl, params=payload)
except ConnectionError, c:
@ -161,7 +159,7 @@ class cloudConnection(object):
requests = {}
required = []
for attribute in dir(cmd):
if attribute != "__doc__" and attribute != "__init__" and \
if attribute != "__doc__" and attribute != "__init__" and\
attribute != "__module__":
if attribute == "isAsync":
isAsync = getattr(cmd, attribute)
@ -193,26 +191,20 @@ class cloudConnection(object):
i = i + 1
return cmdname, isAsync, requests
def marvin_request(self, cmd, data={}, response_type=None):
def marvin_request(self, cmd, response_type=None, method='GET'):
"""
Requester for marvin command objects
@param cmd: marvin's command from cloudstackAPI
@param data: any data to be sent in as POST
@param response_type: response type of the command in cmd
@param raw:
@param method: HTTP GET/POST, defaults to GET
@return:
"""
cmdname, isAsync, payload = self.sanitize_command(cmd)
self.logging.info("sending command: %s %s" % (cmdname, str(payload)))
if self.auth:
response = self.request(
cmdname, auth=True, payload=payload, data=data)
else:
response = self.request(
cmdname, auth=False, payload=payload, data=data)
self.logging.info("Request: %s Response: %s" %
(response.url, response.text))
self.logging.debug("sending %s request: %s %s" % (method, cmdname, str(payload)))
response = self.request(
cmdname, self.auth, payload=payload, method=method)
self.logging.debug("Request: %s Response: %s" %
(response.url, response.text))
response = jsonHelper.getResultObj(response.json(), response_type)
if isAsync == "false":

View File

@ -184,9 +184,9 @@ class codeGenerator:
body += "\n"
for cmdName in self.cmdsName:
body += self.space + 'def %s(self, command, postdata={}):\n'%cmdName
body += self.space + 'def %s(self, command, method="GET"):\n'%cmdName
body += self.space + self.space + 'response = %sResponse()\n'%cmdName
body += self.space + self.space + 'response = self.connection.marvin_request(command, data=postdata, response_type=response)\n'
body += self.space + self.space + 'response = self.connection.marvin_request(command, response_type=response, method=method)\n'
body += self.space + self.space + 'return response\n'
body += '\n'

View File

@ -102,7 +102,7 @@ class Account:
def delete(self, apiclient):
"""Delete an account"""
cmd = deleteAccount.deleteAccountCmd()
cmd.id = self.account.id
cmd.id = self.id
apiclient.deleteAccount(cmd)
@classmethod
@ -220,7 +220,7 @@ class VirtualMachine:
def create(cls, apiclient, services, templateid=None, accountid=None,
domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
securitygroupids=None, projectid=None, startvm=None,
diskofferingid=None, affinitygroupnames=None, hostid=None, mode='basic'):
diskofferingid=None, affinitygroupnames=None, hostid=None, mode='basic', method='GET'):
"""Create the instance"""
cmd = deployVirtualMachine.deployVirtualMachineCmd()
@ -262,8 +262,6 @@ class VirtualMachine:
if securitygroupids:
cmd.securitygroupids = [str(sg_id) for sg_id in securitygroupids]
if "userdata" in services:
cmd.userdata = base64.b64encode(services["userdata"])
if "affinitygroupnames" in services:
cmd.affinitygroupnames = services["affinitygroupnames"]
@ -279,7 +277,10 @@ class VirtualMachine:
if hostid:
cmd.hostid = hostid
virtual_machine = apiclient.deployVirtualMachine(cmd)
if "userdata" in services:
cmd.userdata = base64.b64encode(services["userdata"])
virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
# VM should be in Running state after deploy
timeout = 10

View File

@ -11866,13 +11866,24 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
}
.addVlanRange .icon {
background-position: -168px -31px;
background-position: -37px -62px;
}
.addVlanRange:hover .icon {
background-position: -168px -613px;
background-position: -37px -62px;
}
.removeVlanRange .icon {
background-position: 1px -92px;
}
.removeVlanRange:hover .icon{
background-position: 1px -92px;
}
.resize .icon,
.updateResourceCount .icon {
background-position: -167px -66px;
@ -11898,18 +11909,21 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
background-position: -168px -31px;
}
.reset .icon,
.scaleUp .icon {
.reset .icon {
background-position: -168px -31px;
}
.scaleUp .icon{
background-position: -167px -66px;
}
.restoreVM:hover .icon,
.restore:hover .icon {
background-position: -168px -613px;
}
.reset:hover .icon,
.scaleUp:hover .icon {
.reset:hover .icon {
background-position: -168px -613px;
}

View File

@ -204,34 +204,22 @@
affinitygroupid: args.context.affinityGroups[0].id
});
}
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
$.extend(data, {
zonetype: args.context.zoneType
});
}
$.ajax({
url: createURL('listVirtualMachines'),
data: data,
success: function(json) {
var items = json.listvirtualmachinesresponse.virtualmachine;
// Code for hiding "Expunged VMs"
/* if(items != null) {
var i=0;
for( i=0;i< items.length;i++){
if(items[i].state == 'Expunging')
args.response.success ({
});
else {
var items = json.listvirtualmachinesresponse.virtualmachine;
args.response.success({
actionFilter: vmActionfilter,
data: items[i]
});
}
}
}
else {*/
args.response.success({
actionFilter: vmActionfilter,
data: items
});
});
}
});
},
@ -1450,10 +1438,15 @@
{
name: { label: 'label.name', header: true },
networkname: {label: 'Network Name' },
ipaddress: { label: 'label.ip.address' },
type: { label: 'label.type' },
ipaddress: { label: 'label.ip.address' },
gateway: { label: 'label.gateway' },
netmask: { label: 'label.netmask' },
ip6address: { label: 'IPv6 IP Address' },
ip6gateway: { label: 'IPv6 Gateway' },
ip6cidr: { label: 'IPv6 CIDR' },
isdefault: {
label: 'label.is.default',
converter: function(data) {

View File

@ -382,7 +382,7 @@
detailView: {
name: 'GSLB details',
viewAll: { path: 'regions.lbUnderGSLB', label: 'load balancer rules' },
viewAll: { path: 'regions.lbUnderGSLB', label: 'assigned load balancing' },
actions: {
remove: {
label: 'delete GSLB',
@ -452,77 +452,82 @@
}
},
lbUnderGSLB: {
lbUnderGSLB: {
id: 'lbUnderGSLB',
type: 'select',
title: 'assigned load balancer rules',
title: 'assigned load balancing',
listView: {
section: 'lbUnderGSLB',
id: 'lbUnderGSLB',
label: 'assigned load balancer rules',
label: 'assigned load balancing',
fields: {
name: { label: 'label.name' },
'name': { label: 'label.name' },
publicport: { label: 'label.public.port' },
privateport: { label: 'label.private.port' },
algorithm: { label: 'label.algorithm' }
privateport: { label: 'label.private.port' },
algorithm: { label: 'label.algorithm' }
},
dataProvider: function(args) {
var data = {
globalloadbalancerruleid: args.context.GSLB[0].id,
listAll: true
};
$.ajax({
url: createURL('listLoadBalancerRules'),
data: data,
success: function(json) {
var items = json.listloadbalancerrulesresponse.loadbalancerrule;
args.response.success({
data: items
});
}
dataProvider: function(args) {
var items = args.context.GSLB[0].loadbalancerrule;
args.response.success({
data: items
});
},
actions: {
actions: {
add: {
label: 'assign load balancer rule to GSLB',
messages: {
confirm: function(args) {
return 'Please confirm you want to assign load balancer rule to GSLB';
},
label: 'assign more load balancing',
messages: {
notification: function(args) {
return 'assign load balancer rule to GSLB';
return 'assign more load balancing';
}
},
createForm: {
title: 'assign load balancer rule to GSLB',
title: 'assign more load balancing',
fields: {
loadbalancerrule: {
label: 'load balancer rule',
label: 'load balancing rule',
select: function(args) {
var data = {
globalloadbalancerruleid: args.context.GSLB[0].id,
listAll: true
};
$.ajax({
url: createURL('listLoadBalancerRules'),
data: data,
success: function(json) {
var items = json.listloadbalancerrulesresponse.loadbalancerrule;
args.response.success({
data: items,
descriptionField: 'name'
});
}
});
var data = {
globalloadbalancerruleid: args.context.GSLB[0].id,
listAll: true
};
$.ajax({
url: createURL('listLoadBalancerRules'),
data: data,
success: function(json) {
var allLbRules = json.listloadbalancerrulesresponse.loadbalancerrule;
var assignedLbRules = args.context.GSLB[0].loadbalancerrule;
var items = [];
if(allLbRules != null) {
for(var i = 0; i < allLbRules.length; i++) {
var isAssigned = false;
if(assignedLbRules != null) {
for(var k = 0; k < assignedLbRules.length; k++) {
if(allLbRules[i].id == assignedLbRules[k].id) {
isAssigned = true;
break;
}
}
}
if(isAssigned == false) {
items.push(allLbRules[i]);
}
}
}
args.response.success({
data: items,
descriptionField: 'name'
});
}
});
}
}
}
},
action: function(args) {
var data = {
id: args.context.GSLB[0].id,
loadbalancerrulelist: args.data.loadbalancerrule
};
var data = {
id: args.context.GSLB[0].id,
loadbalancerrulelist: args.data.loadbalancerrule
};
$.ajax({
url: createURL('assignToGlobalLoadBalancerRule'),
data: data,
@ -547,16 +552,16 @@
},
detailView: {
name: 'load balancer rule details',
name: 'load balancing details',
actions: {
remove: {
label: 'remove load balancer rule from this GSLB',
label: 'remove load balancing from this GSLB',
messages: {
notification: function() {
return 'remove load balancer rule from GSLB';
return 'remove load balancing from GSLB';
},
confirm: function() {
return 'Please confirm you want to remove load balancer rule from GSLB';
return 'Please confirm you want to remove load balancing from GSLB';
}
},
action: function(args) {

View File

@ -398,12 +398,18 @@
if(args.context != null) {
if("instances" in args.context) {
$.extend(data, {
virtualMachineId: args.context.instances[0].id
});
$.extend(data, {
virtualMachineId: args.context.instances[0].id
});
}
}
if(args.context.zoneType != null && args.context.zoneType.length > 0) { //Basic type or Advanced type
$.extend(data, {
zonetype: args.context.zoneType
});
}
$.ajax({
url: createURL('listVolumes'),
data: data,

View File

@ -1028,7 +1028,13 @@
updateTrafficLabels(trafficType, args.data, function() {
args.response.success({ _custom: { jobId: jobId }});
});
},
error:function(json){
args.response.error(parseXMLHttpResponse(json));
}
});
@ -1036,8 +1042,56 @@
notification:{poll:pollAsyncJobResult}
}
},
removeVlanRange:{
label:'Remove VLAN Range',
messages: {
confirm: function(args) {
return 'Are you sure you want to remove an existing VLAN Range from this guest network?';
},
notification: function(args) {
return 'VLAN Range removed';
}
},
createForm:{
title:'Remove VLAN Range',
fields:{
startvlan: {label:'Vlan Start', validation:{required:true}},
endvlan:{label:'Vlan End', validation:{required:true}}
}
},
action:function(args){
var array1=[];
if(args.data.startvlan != "" && args.data.endvlan != ""){
array1.push("&removevlan=" + args.data.startvlan + "-" + args.data.endvlan);
}
$.ajax({
url: createURL("updatePhysicalNetwork&id=" + selectedPhysicalNetworkObj.id + array1.join("")),
dataType: "json",
success: function(json) {
var jobId = json.updatephysicalnetworkresponse.jobid;
var trafficType = getTrafficType(selectedPhysicalNetworkObj, 'Guest');
updateTrafficLabels(trafficType, args.data, function() {
args.response.success({ _custom: { jobId: jobId }});
});
},
error:function(json){
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification:{poll:pollAsyncJobResult}
}
},
@ -1056,23 +1110,24 @@
preFilter: function(args) {
var hiddenFields = [];
if(selectedZoneObj.networktype == "Basic") {
hiddenFields.push("startVlan");
hiddenFields.push("endVlan");
hiddenFields.push("vlan");
// hiddenFields.push("endVlan");
}
return hiddenFields;
},
fields: [
{ //updatePhysicalNetwork API
state: { label: 'label.state' },
startVlan: {
label: 'label.start.vlan',
vlan: {
label: 'VLAN Range(s)',
isEditable: true
},
endVlan: {
/* endVlan: {
label: 'label.end.vlan',
isEditable: true
},
tags: { label: 'Tags', isEditable: true },
},*/
tags: { label: 'Tags', isEditable: true },
broadcastdomainrange: { label: 'label.broadcast.domain.range' }
},
{ //updateTrafficType API
@ -1094,9 +1149,9 @@
success: function(json) {
selectedPhysicalNetworkObj = json.listphysicalnetworksresponse.physicalnetwork[0];
var startVlan, endVlan;
// var startVlan, endVlan;
var vlan = selectedPhysicalNetworkObj.vlan;
if(vlan != null && vlan.length > 0) {
/* if(vlan != null && vlan.length > 0) {
if(vlan.indexOf("-") != -1) {
var vlanArray = vlan.split("-");
startVlan = vlanArray[0];
@ -1107,7 +1162,7 @@
}
selectedPhysicalNetworkObj["startVlan"] = startVlan;
selectedPhysicalNetworkObj["endVlan"] = endVlan;
}
}*/
//traffic type
var xentrafficlabel, kvmtrafficlabel, vmwaretrafficlabel;
@ -1120,7 +1175,7 @@
args.response.success({
actionFilter: function() {
var allowedActions = ['edit' , 'addVlanRange'];
var allowedActions = ['edit' , 'addVlanRange','removeVlanRange'];
return allowedActions;
},
data: selectedPhysicalNetworkObj
@ -4893,14 +4948,16 @@
var array1 = [];
array1.push("&name=" +todb(args.data.name));
array1.push("&dns1=" + todb(args.data.dns1));
array1.push("&dns2=" + todb(args.data.dns2)); //dns2 can be empty ("") when passed to API
array1.push("&dns2=" + todb(args.data.dns2)); //dns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
array1.push("&ip6dns1=" + todb(args.data.ip6dns1)); //p6dns1 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
array1.push("&ip6dns2=" + todb(args.data.ip6dns2)); //ip6dns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
if (selectedZoneObj.networktype == "Advanced" && args.data.guestcidraddress) {
array1.push("&guestcidraddress=" + todb(args.data.guestcidraddress));
}
array1.push("&internaldns1=" + todb(args.data.internaldns1));
array1.push("&internaldns2=" + todb(args.data.internaldns2)); //internaldns2 can be empty ("") when passed to API
array1.push("&internaldns2=" + todb(args.data.internaldns2)); //internaldns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
array1.push("&domain=" + todb(args.data.domain));
array1.push("&localstorageenabled=" + (args.data.localstorageenabled == 'on'));
$.ajax({
@ -4938,6 +4995,8 @@
allocationstate: { label: 'label.allocation.state' },
dns1: { label: 'label.dns.1', isEditable: true, validation: { required: true } },
dns2: { label: 'label.dns.2', isEditable: true },
ip6dns1: { label: 'IPv6 DNS1', isEditable: true },
ip6dns2: { label: 'IPv6 DNS2', isEditable: true },
internaldns1: { label: 'label.internal.dns.1', isEditable: true, validation: { required: true } },
internaldns2: { label: 'label.internal.dns.2', isEditable: true },
domainname: { label: 'label.domain' },
@ -4950,8 +5009,8 @@
localstorageenabled: {
label: 'label.local.storage.enabled',
isBoolean: true,
isEditable: true,
converter:cloudStack.converters.toBooleanText
isEditable: true,
converter:cloudStack.converters.toBooleanText
}
}
],

View File

@ -323,23 +323,30 @@
preFilter: function(args) {
var $form = args.$form;
if (args.data['network-model'] == 'Basic') {
if (args.data['network-model'] == 'Basic') { //Basic zone
args.$form.find('[rel=networkOfferingId]').show();
args.$form.find('[rel=guestcidraddress]').hide();
args.$form.find('[rel=ip6dns1]').hide();
args.$form.find('[rel=ip6dns2]').hide();
args.$form.find('[rel=ip6dns1]').hide();
args.$form.find('[rel=ip6dns2]').hide();
}
else { //args.data['network-model'] == 'Advanced'
else { //Advanced zone
args.$form.find('[rel=networkOfferingId]').hide();
if(args.data["zone-advanced-sg-enabled"] != "on")
if(args.data["zone-advanced-sg-enabled"] != "on") { //Advanced SG-disabled zone
args.$form.find('[rel=guestcidraddress]').show();
else //args.data["zone-advanced-sg-enabled"] == "on
args.$form.find('[rel=guestcidraddress]').hide();
args.$form.find('[rel=ip6dns1]').show();
args.$form.find('[rel=ip6dns2]').show();
}
args.$form.find('[rel=ip6dns1]').show();
args.$form.find('[rel=ip6dns2]').show();
}
else { //Advanced SG-enabled zone
args.$form.find('[rel=guestcidraddress]').hide();
args.$form.find('[rel=ip6dns1]').hide();
args.$form.find('[rel=ip6dns2]').hide();
}
}
setTimeout(function() {
if ($form.find('input[name=ispublic]').is(':checked')) {