Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cloudstack into disk_io_throttling

This commit is contained in:
Wei Zhou 2013-06-17 09:52:24 +02:00
commit 635974e1f9
55 changed files with 908 additions and 1188 deletions

View File

@ -74,9 +74,6 @@ public class ListHostsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
description="the Zone ID for the host")
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.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
required=false, description="lists hosts in the same cluster as this VM and flag hosts with enough CPU/RAm to host this VM")
@ -126,10 +123,6 @@ public class ListHostsCmd extends BaseListCmd {
public Long getZoneId() {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
public Long getVirtualMachineId() {
return virtualMachineId;

View File

@ -43,10 +43,9 @@ public class LDAPConfigCmd extends BaseCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.LIST_ALL, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com")
private String listall;
@Parameter(name=ApiConstants.LIST_ALL, type=CommandType.BOOLEAN, description="If true return current LDAP configuration")
private Boolean listAll;
@Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com")
private String hostname;
@ -78,10 +77,10 @@ public class LDAPConfigCmd extends BaseCmd {
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getListAll() {
return listall == null ? "false" : listall;
public Boolean getListAll() {
return listAll == null ? Boolean.FALSE : listAll;
}
public String getBindPassword() {
return bindPassword;
}
@ -156,16 +155,15 @@ public class LDAPConfigCmd extends BaseCmd {
InsufficientCapacityException, ServerApiException,
ConcurrentOperationException, ResourceAllocationException {
try {
if ("true".equalsIgnoreCase(getListAll())){
if (getListAll()){
// return the existing conf
LDAPConfigCmd cmd = _configService.listLDAPConfig(this);
LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(),
cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN());
LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN());
lr.setResponseName(getCommandName());
this.setResponseObject(lr);
}
else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) {
throw new InvalidParameterValueException("You need to provide hostname, serachbase and queryfilter to configure your LDAP server");
throw new InvalidParameterValueException("You need to provide hostname, searchbase and queryfilter to configure your LDAP server");
}
else {
boolean result = _configService.updateLDAP(this);

View File

@ -59,9 +59,6 @@ public class ListStoragePoolsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
description="the Zone ID for the storage pool")
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.ID, type=CommandType.UUID, entityType = StoragePoolResponse.class,
description="the ID of the storage pool")
@ -95,10 +92,6 @@ public class ListStoragePoolsCmd extends BaseListCmd {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
public Long getId() {
return id;
}

View File

@ -78,9 +78,6 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
@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;
@ -149,10 +146,6 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
public Boolean getForVirtualNetwork() {
return forVirtualNetwork;
}

View File

@ -67,8 +67,6 @@ 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 ///////////////////////
@ -103,9 +101,6 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
return zoneId;
}
public String getZoneType() {
return zoneType;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -370,6 +370,7 @@
<property name="Adapters">
<list>
<ref bean="HostAntiAffinityProcessor" />
<ref bean="ExplicitDedicationProcessor"/>
</list>
</property>
</bean>

View File

@ -50,5 +50,6 @@
<xi:include href="gsoc-imduffy15.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="gsoc-dharmesh.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="gsoc-meng.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="gsoc-shiva.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>

View File

@ -25,16 +25,16 @@
External LB is nothing but a LB rule created to redirect the traffic received at a public IP of
the VPC virtual router. The traffic is load balanced within a tier based on your configuration.
Citrix NetScaler and VPC virtual router are supported for external LB. When you use internal LB
service, traffic received at a tier is load balanced across different tiers within the VPC. For
example, traffic reached at Web tier is redirected to Application tier. External load balancing
devices are not supported for internal LB. The service is provided by a internal LB VM
service, traffic received at a tier is load balanced across different VMs within that tier. For
example, traffic reached at Web tier is redirected to another VM in that tier. External load
balancing devices are not supported for internal LB. The service is provided by a internal LB VM
configured on the target tier.</para>
<section id="curent-lb-vpc">
<title>Load Balancing Within a Tier (External LB)</title>
<para>A &PRODUCT; user or administrator may create load balancing rules that balance traffic
received at a public IP to one or more VMs that belong to a network tier that provides load
balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the
rule to a set of VMs within a VPC.</para>
rule to a set of VMs within a tier.</para>
<orderedlist>
<listitem>
<para>Log in to the &PRODUCT; UI as an administrator or end user.</para>

View File

@ -20,6 +20,7 @@
-->
<section id="create-vpn-connection-vpc">
<title>Creating a VPN Connection</title>
<note><para>&PRODUCT; supports creating up to 8 VPN connections.</para></note>
<orderedlist>
<listitem>
<para>Log in to the &PRODUCT; UI as an administrator or end user.</para>
@ -38,19 +39,37 @@
</listitem>
<listitem>
<para>Click the Settings icon.</para>
<para>The following options are displayed.</para>
<para>For each tier, the following options are displayed:</para>
<itemizedlist>
<listitem>
<para>IP Addresses</para>
<para>Internal LB</para>
</listitem>
<listitem>
<para>Gateways</para>
<para>Public LB IP</para>
</listitem>
<listitem>
<para>Site-to-Site VPN</para>
<para>Static NAT</para>
</listitem>
<listitem>
<para>Network ASLs</para>
<para>Virtual Machines</para>
</listitem>
<listitem>
<para>CIDR</para>
</listitem>
</itemizedlist>
<para>The following router information is displayed:</para>
<itemizedlist>
<listitem>
<para>Private Gateways</para>
</listitem>
<listitem>
<para>Public IP Addresses</para>
</listitem>
<listitem>
<para>Site-to-Site VPNs</para>
</listitem>
<listitem>
<para>Network ACL Lists</para>
</listitem>
</itemizedlist>
</listitem>
@ -100,4 +119,4 @@
</itemizedlist>
</listitem>
</orderedlist>
</section>
</section>

View File

@ -38,19 +38,37 @@
</listitem>
<listitem>
<para>Click the Settings icon.</para>
<para>The following options are displayed.</para>
<para>For each tier, the following options are displayed:</para>
<itemizedlist>
<listitem>
<para>IP Addresses</para>
<para>Internal LB</para>
</listitem>
<listitem>
<para>Gateways</para>
<para>Public LB IP</para>
</listitem>
<listitem>
<para>Site-to-Site VPN</para>
<para>Static NAT</para>
</listitem>
<listitem>
<para>Network ACLs</para>
<para>Virtual Machines</para>
</listitem>
<listitem>
<para>CIDR</para>
</listitem>
</itemizedlist>
<para>The following router information is displayed:</para>
<itemizedlist>
<listitem>
<para>Private Gateways</para>
</listitem>
<listitem>
<para>Public IP Addresses</para>
</listitem>
<listitem>
<para>Site-to-Site VPNs</para>
</listitem>
<listitem>
<para>Network ACL Lists</para>
</listitem>
</itemizedlist>
</listitem>
@ -77,4 +95,4 @@
</itemizedlist>
</listitem>
</orderedlist>
</section>
</section>

View File

@ -38,19 +38,37 @@
</listitem>
<listitem>
<para>Click the Settings icon.</para>
<para>The following options are displayed.</para>
<para>For each tier, the following options are displayed:</para>
<itemizedlist>
<listitem>
<para>IP Addresses</para>
<para>Internal LB</para>
</listitem>
<listitem>
<para>Gateways</para>
<para>Public LB IP</para>
</listitem>
<listitem>
<para>Site-to-Site VPN</para>
<para>Static NAT</para>
</listitem>
<listitem>
<para>Network ASLs</para>
<para>Virtual Machines</para>
</listitem>
<listitem>
<para>CIDR</para>
</listitem>
</itemizedlist>
<para>The following router information is displayed:</para>
<itemizedlist>
<listitem>
<para>Private Gateways</para>
</listitem>
<listitem>
<para>Public IP Addresses</para>
</listitem>
<listitem>
<para>Site-to-Site VPNs</para>
</listitem>
<listitem>
<para>Network ACL Lists</para>
</listitem>
</itemizedlist>
</listitem>

70
docs/en-US/gsoc-shiva.xml Normal file
View File

@ -0,0 +1,70 @@
<?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_GSoC_Guide.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.
-->
<chapter id="gsoc-shiva">
<title>Shiva Teja's 2013 GSoC Proposal</title>
<para>This chapter describes Shiva Teja's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal.</para>
<section id="gsoc-abstract-shiva">
<title>Abstract</title>
<para>
The aim of this project is to create a new modular UI for Apache CloudStack using Bootstrap by Twitter and Backbone.js. To achieve this easily, I'll be creating a RESTful wrapper API on top of the current CloudStack API. I hope this project will make custom UIs for CloudStack very easy.</para>
<para>Why does CloudStack need a new UI?</para>
<para>The current UI cannot be reused easliy to make a custom UI. The UI I will be making using backbone.js can be reused very easily to make custom UIs. The models, views, routers etc can remain the same in all the UIs. The user interface can be changed just by changing the templates. Check the implementation details below for further details.</para>
<para>Why does it need a RESTful wrapper API ?</para>
<para>Backbone.js heavily depends on RESTful architecture. Making a new UI with backbone.js using a query based API might not be easy.</para>
</section>
<section id="gsoc-deliverables-shiva">
<title>List of deliverables</title>
<orderedlist>
<listitem><para>A new UI for CloudStack(with almost all features in the current UI and new ones, if any).</para></listitem>
<listitem><para>A RESTful wrapper API on top of the CloudStack API</para></listitem>
<listitem><para>Some documentation about using this UI to make a custom UI.</para></listitem>
</orderedlist>
</section>
<section id="gsoc-approach-shiva">
<title>Approach</title>
<para>Wrapper API: Backbone.js, by default, uses four HTTP methods(GET, PUT, POST, DELETE) for communicating with the server. It uses GET to fetch a resource from the server, POST to create a resource, PUT to update the resource and DELETE to delete the resource. A query based API can probably be used to make the UI by overriding backbone's<ulink url="http://backbonejs.org/#Sync"><citetitle> default sync function</citetitle></ulink>. But it makes more sense to have an API which supports the above mentioned method and is resource based. This RESTful API works on top of the CloudStack API. The main task is to map the combinations of these HTTP methods and the resources to appropriate CloudStack API command. The other task is to decide on how the URLs should look like. Say for starting a virtual machine, for it to be RESTful, we have to use POST as we are creating a resource, or a PUT as we are changing the state of a virtual machine. So the possible options on the URL could be to do a POST /runningvirtualmachines and respond with 201 Created code or a PUT on /virtualmachines/id and respond with 200 OK. If these are decided, the wrapper can be generated or be written manually, which can use defined patters to map to appropriate CloudStack API commands(Similar to what cloudmonkey does. See this <ulink url="https://github.com/shivateja/cloudstack-restful-api"><citetitle>prototype</citetitle></ulink>. I can use cloudmonkey's code to generate the required API entity verb relationships. Each verb will have a set of rules saying what method should be used in the RESTful API and how should it look like in the URL. Another possible way could be to group entities first manually and write the wrapper manually(something like zone/pods/cluster). Some possibilities have been discussed in <ulink url="http://mail-archives.apache.org/mod_mbox/cloudstack-dev/201304.mbox/%3CCAJrLSbaqa08uHw_xETt7Q59Nex%3DThQzvqEJyoXK8Q-OwN04Suw%40mail.gmail.com%3E"><citetitle>this thread</citetitle></ulink>.</para>
<para>UI: It will be a single page app. It'll use <ulink url="http://underscorejs.org/#template">client side templating</ulink> for rendering. This makes it very easy to make a custom UI because it can be achieved just by changing the templates. Backbone views will make use of these templates to render the appropriate models/collections. A completely new interface can be written just by changing the templates. Javascript code can completely remain the same. The views will take care of appropriate DOM events. Such event will correspond to appropriate model/collection chages, thus causing appropriate API calls.</para>
</section>
<section id="gsoc-schedule-shiva">
<title>Approximate Schedle</title>
<para>Till June 17 - Decide on how the RESTful API should look like and design algorithms to generate the wrapper.</para>
<para>July 5(soft deadline), July 10(hard deadline) : Wrapper API will be ready.</para>
<para>July 12(soft) - July 15(hard): Make basic wireframes and designs for the website and get them approved.</para>
<para>July 29(mid term evaluation) : All the basic models, views, routes of the UI should be ready along with a few templates.</para>
<para>August 15(hard deadline, shouldn't take much time actually) - A basic usable UI where users can just list all the entities which are present in the current UI's main navigation( Like Instances, Templates, Accounts etc)</para>
<para>September 1(hard) - From this UI, users should be able to launch instances, edit settings of most of the entities.</para>
<para>September 16(Pencil down!) - Fix some design tweaks and finish a completely usable interface with functions similar to current UI.</para>
<para>September 23 - Finish the documentation on how to use this UI to make custom UIs.</para>
</section>
<section id="gsoc-aboutme-shiva">
<title>About Me</title>
<para> I am a 2nd year computer science undergrad studying at IIT Mandi, India. I've been using Python for an year and a half now. I've used Django, Flask and Tornado for my small projects. Along with Python, I use C++ for competitive programming. Recently, I fell in love with Haskell. I've always been fascinated about web technologies.</para>
</section>
</chapter>

View File

@ -32,14 +32,10 @@
<para>Isolate VMs in a shared networks by using Private VLANs.</para>
</listitem>
<listitem>
<para>Supported in both VPC and non-VPC deployments.</para>
<para>Supported on KVM, XenServer, and VMware hypervisors</para>
</listitem>
<listitem>
<para>Supported on all hypervisors.</para>
</listitem>
<listitem>
<para>Allow end users to deploy VMs in an isolated networks, or a VPC, or a Private
VLAN-enabled shared network.</para>
<para>PVLAN-enabled shared network can be a part of multiple networks of a guest VM.</para>
</listitem>
</itemizedlist>
<section id="about-pvlan">
@ -121,55 +117,16 @@
switch, connect the switch to upper switch by using cables. The number of cables should be
greater than the number of PVLANs used.</para>
</listitem>
<listitem>
<para>If your Catalyst switch supports PVLAN, but not PVLAN promiscuous trunk mode, perform
the following: </para>
<orderedlist numeration="loweralpha">
<listitem>
<para>Configure one of the switch port as trunk for management network (management
VLAN).</para>
</listitem>
<listitem>
<para>For each PVLAN, perform the following:</para>
<orderedlist numeration="lowerroman">
<listitem>
<para>Connect a port of the Catalyst switch to the upper switch.</para>
</listitem>
<listitem>
<para>Set the port in the Catalyst Switch in promiscuous mode for one pair of
PVLAN.</para>
</listitem>
<listitem>
<para>Set the port in the upper switch to access mode, and allow only the traffic of
the primary VLAN of the PVLAN pair.</para>
</listitem>
</orderedlist>
</listitem>
</orderedlist>
</listitem>
<listitem>
<para>Configure private VLAN on your physical switches out-of-band.</para>
</listitem>
<listitem>
<para>Open vSwitch (OVS) used by XenServer and KVM does not support PVLAN. Therefore,
simulate PVLAN on OVS for XenServer and KVM by modifying the flow table to achieve the
following:</para>
<itemizedlist>
<listitem>
<para>For every traffic leaving user VMs, tag with the secondary isolated VLAN
ID.</para>
</listitem>
<listitem>
<para>Change the VLAN ID to primary VLAN ID.</para>
<para>This allows the traffic which is tagged with the secondary isolated VLAN ID reach
the DHCP server. </para>
</listitem>
<listitem>
<para>The gateway is PVLAN-unaware; therefore, the switch connected to the gateway
should translate all the secondary VLAN to primary VLAN for communicating with the
gateway.</para>
</listitem>
</itemizedlist>
<para>Before you use PVLAN on XenServer and KVM, enable Open vSwitch (OVS) .</para>
<note>
<para>OVS on XenServer and KVM does not support PVLAN. Therefore, simulate PVLAN on OVS
for XenServer and KVM by modifying the flow table and tagging every traffic leaving
guest VMs with the secondary VLAN ID.</para>
</note>
</listitem>
</itemizedlist>
</section>
@ -208,41 +165,83 @@
<para>Specify the following:</para>
<itemizedlist>
<listitem>
<para>Name:</para>
<para><emphasis role="bold">Name</emphasis>: The name of the network. This will be
visible to the user.</para>
</listitem>
<listitem>
<para>Description:</para>
<para><emphasis role="bold">Description</emphasis>: The short description of the network
that can be displayed to users.</para>
</listitem>
<listitem>
<para>VLAN ID:</para>
<para><emphasis role="bold">VLAN ID</emphasis>: The unique ID of the VLAN.</para>
</listitem>
<listitem>
<para>Private VLAN ID:</para>
<para><emphasis role="bold">Isolated VLAN ID</emphasis>: The unique ID of the Secondary
Isolated VLAN. </para>
<para>For the description on Secondary Isolated VLAN, see <xref linkend="about-pvlan"
/>.</para>
</listitem>
<listitem>
<para>Scope:</para>
<para><emphasis role="bold">Scope</emphasis>: The available scopes are Domain, Account,
Project, and All.</para>
<itemizedlist>
<listitem>
<para><emphasis role="bold">Domain</emphasis>: Selecting Domain limits the scope of
this guest network to the domain you specify. The network will not be available
for other domains. If you select Subdomain Access, the guest network is available
to all the sub domains within the selected domain.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Account</emphasis>: The account for which the guest
network is being created for. You must specify the domain the account belongs
to.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Project</emphasis>: The project for which the guest
network is being created for. You must specify the domain the project belongs
to.</para>
</listitem>
<listitem>
<para><emphasis role="bold">All</emphasis>: The guest network is available for all
the domains, account, projects within the selected zone. </para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Network Offering:</para>
<para><emphasis role="bold">Network Offering</emphasis>: If the administrator has
configured multiple network offerings, select the one you want to use for this
network.</para>
</listitem>
<listitem>
<para>Gateway:</para>
<para><emphasis role="bold">Gateway</emphasis>: The gateway that the guests should
use.</para>
</listitem>
<listitem>
<para>Netmask:</para>
<para><emphasis role="bold">Netmask</emphasis>: The netmask in use on the subnet the
guests will use.</para>
</listitem>
<listitem>
<para>IP Range:</para>
<para><emphasis role="bold">IP Range</emphasis>: A range of IP addresses that are
accessible from the Internet and are assigned to the guest VMs.</para>
<para>If one NIC is used, these IPs should be in the same CIDR in the case of
IPv6.</para>
</listitem>
<listitem>
<para>IPv6 CIDR:</para>
<para><emphasis role="bold">IPv6 CIDR</emphasis>: The network prefix that defines the
guest network subnet. This is the CIDR that describes the IPv6 addresses in use in the
guest networks in this zone. To allot IP addresses from within a particular address
block, enter a CIDR.</para>
</listitem>
<listitem>
<para>Network Domain:</para>
<para><emphasis role="bold">Network Domain</emphasis>: A custom DNS suffix at the level
of a network. If you want to assign a special domain name to the guest VM network,
specify a DNS suffix.</para>
</listitem>
</itemizedlist>
</listitem>
<listitem><para>Click OK to confirm.</para></listitem>
<listitem>
<para>Click OK to confirm.</para>
</listitem>
</orderedlist>
</section>
</section>

View File

@ -3310,7 +3310,9 @@ ServerResource {
ConsoleDef console = new ConsoleDef("pty", null, null, (short) 0);
devices.addDevice(console);
GraphicDef grap = new GraphicDef("vnc", (short) 0, true, null, null,
//add the VNC port passwd here, get the passwd from the vmInstance.
String passwd = vmTO.getVncPassword();
GraphicDef grap = new GraphicDef("vnc", (short) 0, true, null, passwd,
null);
devices.addDevice(grap);

View File

@ -991,7 +991,7 @@ public class LibvirtVMDef {
if (_listenAddr != null) {
graphicBuilder.append(" listen='" + _listenAddr + "'");
} else {
graphicBuilder.append(" listen='' ");
graphicBuilder.append(" listen=''");
}
if (_passwd != null) {
graphicBuilder.append(" passwd='" + _passwd + "'");

View File

@ -80,7 +80,7 @@ public class LibvirtComputingResourceTest {
vmStr += "<serial type='pty'>\n";
vmStr += "<target port='0'/>\n";
vmStr += "</serial>\n";
vmStr += "<graphics type='vnc' autoport='yes' listen='" + vncAddr + "' />\n";
vmStr += "<graphics type='vnc' autoport='yes' listen='" + vncAddr + "' passwd='" + vncPassword + "'/>\n";
vmStr += "<console type='pty'>\n";
vmStr += "<target port='0'/>\n";
vmStr += "</console>\n";
@ -156,7 +156,7 @@ public class LibvirtComputingResourceTest {
vmStr += "<serial type='pty'>\n";
vmStr += "<target port='0'/>\n";
vmStr += "</serial>\n";
vmStr += "<graphics type='vnc' autoport='yes' listen='" + vncAddr + "' />\n";
vmStr += "<graphics type='vnc' autoport='yes' listen='" + vncAddr + "' passwd='" + vncPassword + "'/>\n";
vmStr += "<console type='pty'>\n";
vmStr += "<target port='0'/>\n";
vmStr += "</console>\n";

View File

@ -636,8 +636,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
c.addCriteria(Criteria.ID, cmd.getId());
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.DATACENTERID, cmd.getZoneId());
c.addCriteria(Criteria.GROUPID, cmd.getGroupId());
c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, cmd.getForVirtualNetwork());
c.addCriteria(Criteria.NETWORKID, cmd.getNetworkId());
@ -686,8 +685,7 @@ 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 zoneId = c.getCriteria(Criteria.DATACENTERID);
Object zoneType = c.getCriteria(Criteria.DATACENTERTYPE);
Object zoneId = c.getCriteria(Criteria.DATACENTERID);
Object pod = c.getCriteria(Criteria.PODID);
Object hostId = c.getCriteria(Criteria.HOSTID);
Object hostName = c.getCriteria(Criteria.HOSTNAME);
@ -709,8 +707,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
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("dataCenterId", sb.entity().getDataCenterId(), 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);
@ -824,11 +821,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sc.setParameters("stateNEQ", "Destroyed");
}
}
if (zoneType != null) {
sc.setParameters("dataCenterType", zoneType);
}
if (pod != null) {
sc.setParameters("podId", pod);
@ -1422,8 +1415,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
public Pair<List<HostJoinVO>, Integer> searchForServersInternal(ListHostsCmd cmd) {
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
String zoneType = cmd.getZoneType();
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
Object name = cmd.getHostName();
Object type = cmd.getType();
Object state = cmd.getState();
@ -1444,8 +1436,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
sb.and("dataCenterType", sb.entity().getZoneType(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
@ -1489,10 +1480,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
if (zoneType != null) {
sc.setParameters("dataCenterType", zoneType);
}
}
if (pod != null) {
sc.setParameters("podId", pod);
}
@ -1549,8 +1537,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
String type = cmd.getType();
Map<String, String> tags = cmd.getTags();
Long zoneId = cmd.getZoneId();
String zoneType = cmd.getZoneType();
Long zoneId = cmd.getZoneId();
Long podId = null;
if (_accountMgr.isAdmin(caller.getType())) {
podId = cmd.getPodId();
@ -1577,8 +1564,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
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("dataCenterId", sb.entity().getDataCenterId(), 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);
@ -1637,10 +1623,7 @@ 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);
}
@ -1886,8 +1869,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
private Pair<List<StoragePoolJoinVO>, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) {
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
String zoneType = cmd.getZoneType();
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
Object id = cmd.getId();
Object name = cmd.getStoragePoolName();
Object path = cmd.getPath();
@ -1906,8 +1888,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
sb.and("dataCenterType", sb.entity().getZoneType(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
@ -1937,10 +1918,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
if (zoneType != null) {
sc.setParameters("dataCenterType", zoneType);
}
}
if (pod != null) {
sc.setParameters("podId", pod);
}

View File

@ -4187,8 +4187,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault);
}
if (specifyVlan != null) {
// only root admin can list network offering with specifyVlan = true
if (specifyVlan != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {
sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, specifyVlan);
}else{
specifyVlan = false;
}
if (availability != null) {

View File

@ -1202,9 +1202,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
+ Network.GuestType.Isolated + " with a service " + Service.SourceNat.getName() + " enabled");
}
// Don't allow to specify vlan if the caller is a regular user
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getSpecifyVlan() || vlanId != null)) {
throw new InvalidParameterValueException("Regular user is not allowed to specify vlanId");
// Don't allow to specify vlan if the caller is not ROOT admin
if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && (ntwkOff.getSpecifyVlan() || vlanId != null)) {
throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId");
}
if (ipv4) {

View File

@ -3144,6 +3144,16 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
vlanIpMap.put(vlanTag, ipList);
}
List<NicVO> nics = _nicDao.listByVmId(router.getId());
String baseMac = null;
for (NicVO nic : nics) {
NetworkVO nw = _networkDao.findById(nic.getNetworkId());
if (nw.getTrafficType() == TrafficType.Public) {
baseMac = nic.getMacAddress();
break;
}
}
for (Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
List<PublicIpAddress> ipAddrList = vlanAndIp.getValue();
// Source nat ip address should always be sent first
@ -3175,7 +3185,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
String vlanId = ipAddr.getVlanTag();
String vlanGateway = ipAddr.getGateway();
String vlanNetmask = ipAddr.getNetmask();
String vifMacAddress = ipAddr.getMacAddress();
String vifMacAddress = null;
// For non-source nat IP, set the mac to be something based on first public nic's MAC
// We cannot depends on first ip because we need to deal with first ip of other nics
if (!ipAddr.isSourceNat() && ipAddr.getVlanId() != 0) {
vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId());
} else {
vifMacAddress = ipAddr.getMacAddress();
}
IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP,
sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, networkRate, ipAddr.isOneToOneNat());
@ -3336,7 +3353,12 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
// password should be set only on default network element
if (password != null && nic.isDefaultNic()) {
final String encodedPassword = PasswordGenerator.rot13(password);
String encodedPassword = PasswordGenerator.rot13(password);
// We would unset password for BACKUP router in the RvR, to prevent user from accidently reset the
// password again after BACKUP become MASTER
if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER) {
encodedPassword = PasswordGenerator.rot13("saved_password");
}
SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName());
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId()));

View File

@ -294,6 +294,10 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
throw new InvalidParameterValueException("Start port can't be bigger than end port");
}
// start port and end port must be null for protocol = 'all'
if ((portStart != null || portEnd != null ) && protocol != null && protocol.equalsIgnoreCase("all"))
throw new InvalidParameterValueException("start port and end port must be null if protocol = 'all'");
if (sourceCidrList != null) {
for (String cidr: sourceCidrList){
if (!NetUtils.isValidCIDR(cidr)){

View File

@ -146,6 +146,17 @@ X11_KEY_TILDE = 0x7e; // ~
X11_KEY_CIRCUMFLEX_ACCENT = 0x5e; // ^
X11_KEY_YEN_MARK = 0xa5; // Japanese YEN mark
X11_KEY_ASTERISK = 0x2a;
X11_KEY_KP_0 = 0xFFB0;
X11_KEY_KP_1 = 0xFFB1;
X11_KEY_KP_2 = 0xFFB2;
X11_KEY_KP_3 = 0xFFB3;
X11_KEY_KP_4 = 0xFFB4;
X11_KEY_KP_5 = 0xFFB5;
X11_KEY_KP_6 = 0xFFB6;
X11_KEY_KP_7 = 0xFFB7;
X11_KEY_KP_8 = 0xFFB8;
X11_KEY_KP_9 = 0xFFB9;
X11_KEY_KP_Decimal = 0xFFAE;
KEY_DOWN = 5;
KEY_UP = 6;
@ -248,17 +259,17 @@ var keyboardTables = [
{keycode: JS_KEY_FORWARD_SLASH, entry : X11_KEY_FORWARD_SLASH},
{keycode: JS_KEY_DASH, entry : X11_KEY_DASH},
{keycode: JS_KEY_SEMI_COLON, entry : X11_KEY_SEMI_COLON},
{keycode: JS_KEY_NUMPAD0, entry : X11_KEY_NUMPAD0},
{keycode: JS_KEY_NUMPAD1, entry : X11_KEY_NUMPAD1},
{keycode: JS_KEY_NUMPAD2, entry : X11_KEY_NUMPAD2},
{keycode: JS_KEY_NUMPAD3, entry : X11_KEY_NUMPAD3},
{keycode: JS_KEY_NUMPAD4, entry : X11_KEY_NUMPAD4},
{keycode: JS_KEY_NUMPAD5, entry : X11_KEY_NUMPAD5},
{keycode: JS_KEY_NUMPAD6, entry : X11_KEY_NUMPAD6},
{keycode: JS_KEY_NUMPAD7, entry : X11_KEY_NUMPAD7},
{keycode: JS_KEY_NUMPAD8, entry : X11_KEY_NUMPAD8},
{keycode: JS_KEY_NUMPAD9, entry : X11_KEY_NUMPAD9},
{keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_DECIMAL_POINT},
{keycode: JS_KEY_NUMPAD0, entry : X11_KEY_KP_0},
{keycode: JS_KEY_NUMPAD1, entry : X11_KEY_KP_1},
{keycode: JS_KEY_NUMPAD2, entry : X11_KEY_KP_2},
{keycode: JS_KEY_NUMPAD3, entry : X11_KEY_KP_3},
{keycode: JS_KEY_NUMPAD4, entry : X11_KEY_KP_4},
{keycode: JS_KEY_NUMPAD5, entry : X11_KEY_KP_5},
{keycode: JS_KEY_NUMPAD6, entry : X11_KEY_KP_6},
{keycode: JS_KEY_NUMPAD7, entry : X11_KEY_KP_7},
{keycode: JS_KEY_NUMPAD8, entry : X11_KEY_KP_8},
{keycode: JS_KEY_NUMPAD9, entry : X11_KEY_KP_9},
{keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_KP_Decimal},
{keycode: JS_KEY_DIVIDE, entry : 0xffaf},
{keycode: JS_KEY_MULTIPLY, entry : 0xffaa},
{keycode: JS_KEY_ADD, entry : 0xffab},
@ -289,9 +300,12 @@ var keyboardTables = [
]
}
}, {tindex: 2, keyboardType: KEYBOARD_TYPE_UK, mappingTable:
{X11: [],
keyPress: [
//[34 = "]
{X11: [
//[223 = `¬¦]
{keycode: 223, entry : 0x60, browser: "IE"},
],
keyPress: [
//[34 = "]
{keycode: 34, entry:
[{type : KEY_DOWN, code : 0x40, modifiers : 64, shift : true}]
},

View File

@ -1,136 +0,0 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Health check script for the Secondary Storage VM
# DNS server is specified.
CMDLINE=/var/cache/cloud/cmdline
for i in `cat $CMDLINE`
do
key=`echo $i | cut -d= -f1`
value=`echo $i | cut -d= -f2`
case $key in
host)
MGMTSERVER=$value
;;
esac
done
# ping dns server
echo ================================================
DNSSERVER=`egrep '^nameserver' /etc/resolv.conf | awk '{print $2}'| head -1`
echo "First DNS server is " $DNSSERVER
ping -c 2 $DNSSERVER
if [ $? -eq 0 ]
then
echo "Good: Can ping DNS server"
else
echo "WARNING: cannot ping DNS server"
echo "route follows"
route -n
fi
# check dns resolve
echo ================================================
nslookup download.cloud.com 1> /tmp/dns 2>&1
grep 'no servers could' /tmp/dns 1> /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "ERROR: DNS not resolving download.cloud.com"
echo resolv.conf follows
cat /etc/resolv.conf
exit 2
else
echo "Good: DNS resolves download.cloud.com"
fi
# check to see if we have the NFS volume mounted
echo ================================================
mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "NFS is currently mounted"
# check for write access
for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'`
do
if [ $MOUNTPT != "/proc/xen" ] # mounted by xen
then
echo Mount point is $MOUNTPT
touch $MOUNTPT/foo
if [ $? -eq 0 ]
then
echo "Good: Can write to mount point"
rm $MOUNTPT/foo
else
echo "ERROR: Cannot write to mount point"
echo "You need to export with norootsquash"
fi
fi
done
else
echo "ERROR: NFS is not currently mounted"
echo "Try manually mounting from inside the VM"
NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'`
echo "NFS server is " $NFSSERVER
ping -c 2 $NFSSERVER
if [ $? -eq 0 ]
then
echo "Good: Can ping NFS server"
else
echo "WARNING: cannot ping NFS server"
echo routing table follows
route -n
fi
fi
# check for connectivity to the management server
echo ================================================
echo Management server is $MGMTSERVER. Checking connectivity.
socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1)
if [ $? -eq 0 ]
then
echo "Good: Can connect to management server port 8250"
else
echo "ERROR: Cannot connect to $MGMTSERVER port 8250"
echo $socatout
exit 4
fi
# check for the java process running
echo ================================================
ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Good: Java process is running"
else
echo "ERROR: Java process not running. Try restarting the SSVM."
exit 3
fi
echo ================================================
echo Tests Complete. Look for ERROR or WARNING above.
exit 0

View File

@ -36,6 +36,15 @@
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
</fileSet>
<fileSet>
<directory>../../secondary-storage/scripts/</directory>
<outputDirectory></outputDirectory>
<directoryMode>555</directoryMode>
<fileMode>555</fileMode>
<includes>
<include>ssvm-check.sh</include>
</includes>
</fileSet>
<fileSet>
<directory>../../../scripts/storage/secondary/</directory>
<outputDirectory>scripts/storage/secondary</outputDirectory>

View File

@ -665,6 +665,7 @@ ALTER TABLE `cloud`.`dc_storage_network_ip_range` ADD COLUMN `gateway` varchar(1
ALTER TABLE `cloud`.`volumes` ADD COLUMN `last_pool_id` bigint unsigned;
UPDATE `cloud`.`volumes` SET `last_pool_id` = `pool_id`;
UPDATE `cloud`.`volumes` SET `path` = SUBSTRING_INDEX(`path`, '/', -1);
UPDATE `cloud`.`template_spool_ref` SET `local_path` = SUBSTRING_INDEX(`local_path`, '/', -1);
ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN `is_system` int(1) unsigned NOT NULL default '0';
ALTER TABLE `cloud`.`volumes` ADD COLUMN `update_count` bigint unsigned NOT NULL DEFAULT 0;

View File

@ -0,0 +1,21 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""
Tests that put hosts, zones, resources in to maintenance mode are here.
These will have to be run sequentiall when resources are available so as not disrupt other tests
"""

View File

@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
""" P1 tests for dedicated Host high availability
""" P1 tests for dedicated Host high availability
"""
#Import Local Modules
from nose.plugins.attrib import attr
@ -142,7 +142,6 @@ class TestHostHighAvailability(cloudstackTestCase):
try:
#Clean up, terminate the created accounts, domains etc
cleanup_resources(self.apiclient, self.cleanup)
self.testClient.close()
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
@ -158,7 +157,7 @@ class TestHostHighAvailability(cloudstackTestCase):
# Validations,
#1. Ensure that the offering is created and that in the UI the 'Offer HA' field is enabled (Yes)
#The listServiceOffering API should list 'offerha' as true.
#2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected.
#2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected.
# Also, check that the HA Enabled field is enabled 'Yes'.
#list and validate above created service offering with Ha enabled
@ -258,7 +257,7 @@ class TestHostHighAvailability(cloudstackTestCase):
self.debug("Deployed VM on host: %s" % vm.hostid)
#validate the virtual machine created is host Ha enabled
#validate the virtual machine created is host Ha enabled
list_hosts_response = list_hosts(
self.apiclient,
id=vm.hostid
@ -594,7 +593,7 @@ class TestHostHighAvailability(cloudstackTestCase):
vm_with_ha_enabled = vms[0]
#Verify the virtual machine got created on non HA host
#Verify the virtual machine got created on non HA host
list_hosts_response = list_hosts(
self.apiclient,
id=vm_with_ha_enabled.hostid
@ -726,7 +725,7 @@ class TestHostHighAvailability(cloudstackTestCase):
vm_with_ha_disabled = vms[0]
#Verify the virtual machine got created on non HA host
#Verify the virtual machine got created on non HA host
list_hosts_response = list_hosts(
self.apiclient,
id=vm_with_ha_disabled.hostid

View File

@ -558,332 +558,4 @@ class TestVMLifeCycleHostmaintenance(cloudstackTestCase):
"Router state should be running"
)
# TODO: Check for the network connectivity
return
class TestVPCNetworkRules(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestVPCNetworkRules,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering_1 = ServiceOffering.create(
cls.api_client,
cls.services["service_offering_1"]
)
cls.service_offering_2 = ServiceOffering.create(
cls.api_client,
cls.services["service_offering_2"]
)
cls.vpc_off = VpcOffering.create(
cls.api_client,
cls.services["vpc_offering"]
)
cls.vpc_off.update(cls.api_client, state='Enabled')
cls.account = Account.create(
cls.api_client,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
cls.vpc_off = VpcOffering.create(
cls.api_client,
cls.services["vpc_offering"]
)
cls.vpc_off.update(cls.api_client, state='Enabled')
cls.services["vpc"]["cidr"] = '10.1.1.1/16'
cls.vpc = VPC.create(
cls.api_client,
cls.services["vpc"],
vpcofferingid=cls.vpc_off.id,
zoneid=cls.zone.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls.nw_off = NetworkOffering.create(
cls.api_client,
cls.services["network_offering"],
conservemode=False
)
# Enable Network offering
cls.nw_off.update(cls.api_client, state='Enabled')
# Creating network using the network offering created
cls.network_1 = Network.create(
cls.api_client,
cls.services["network"],
accountid=cls.account.name,
domainid=cls.account.domainid,
networkofferingid=cls.nw_off.id,
zoneid=cls.zone.id,
gateway='10.1.1.1',
vpcid=cls.vpc.id
)
cls.nw_off_no_lb = NetworkOffering.create(
cls.api_client,
cls.services["network_offering_no_lb"],
conservemode=False
)
# Enable Network offering
cls.nw_off_no_lb.update(cls.api_client, state='Enabled')
# Creating network using the network offering created
cls.network_2 = Network.create(
cls.api_client,
cls.services["network"],
accountid=cls.account.name,
domainid=cls.account.domainid,
networkofferingid=cls.nw_off_no_lb.id,
zoneid=cls.zone.id,
gateway='10.1.2.1',
vpcid=cls.vpc.id
)
# Spawn an instance in that network
cls.vm_1 = VirtualMachine.create(
cls.api_client,
cls.services["virtual_machine"],
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering_1.id,
networkids=[str(cls.network_1.id)]
)
# Spawn an instance in that network
cls.vm_2 = VirtualMachine.create(
cls.api_client,
cls.services["virtual_machine"],
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering_2.id,
networkids=[str(cls.network_1.id)]
)
cls.vm_3 = VirtualMachine.create(
cls.api_client,
cls.services["virtual_machine"],
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering_1.id,
networkids=[str(cls.network_2.id)]
)
cls.vm_4 = VirtualMachine.create(
cls.api_client,
cls.services["virtual_machine"],
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering_2.id,
networkids=[str(cls.network_2.id)]
)
cls._cleanup = [
cls.service_offering_1,
cls.service_offering_2,
cls.nw_off,
cls.nw_off_no_lb,
]
return
@classmethod
def tearDownClass(cls):
try:
cls.account.delete(cls.api_client)
wait_for_cleanup(cls.api_client, ["account.cleanup.interval"])
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
# Waiting for network cleanup to delete vpc offering
wait_for_cleanup(cls.api_client, ["network.gc.wait",
"network.gc.interval"])
cls.vpc_off.delete(cls.api_client)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
return
def tearDown(self):
try:
#Clean up, terminate the created network offerings
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def validate_vm_deployment(self):
"""Validates VM deployment on different hosts"""
vms = VirtualMachine.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
networkid=self.network_1.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs shall return a valid response"
)
host_1 = vms[0].hostid
self.debug("Host for network 1: %s" % vms[0].hostid)
vms = VirtualMachine.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
networkid=self.network_2.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs shall return a valid response"
)
host_2 = vms[0].hostid
self.debug("Host for network 2: %s" % vms[0].hostid)
self.assertNotEqual(
host_1,
host_2,
"Both the virtual machines should be deployed on diff hosts "
)
return
@attr(tags=["advanced", "intervlan"])
def test_list_pf_rules_for_vpc(self):
""" Test List Port Forwarding Rules & vms belonging to a VPC
"""
# Validate the following
# 1. Create a VPC with cidr - 10.1.1.1/16
# 2. Add network1(10.1.1.1/24) and network2(10.1.2.1/24) to this VPC.
# 3. Deploy vm1 and vm2 in network1 and vm3 and vm4 in network2.
# Make sure vm1 and vm3 are deployed on one host in the cluster
# while vm2 and vm4 are deployed on the other host in the cluster.
# This can be done using host's tags and service offerings with
# host tags.
# 4. Create a PF rule for vms in network1.
# 5. Create a PF rule for vms in network2.
# Steps:
# 1. List all the Port Forwarding Rules belonging to a VPC
# 2. Successfully List the Port Forwarding Rules belonging to the VPC
# 3. List the VMs on network1 for selection for the PF Rule
# 4. Successfully list the VMs for Port Forwarding Rule creation
self.debug("Associating public IP for network: %s" %
self.network_1.name)
public_ip_1 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=self.network_1.id,
vpcid=self.vpc.id
)
self.debug("Associated %s with network %s" % (
public_ip_1.ipaddress.ipaddress,
self.network_1.id
))
nat_rule_1 = NATRule.create(
self.apiclient,
self.vm_1,
self.services["natrule"],
ipaddressid=public_ip_1.ipaddress.id,
openfirewall=False,
networkid=self.network_1.id,
vpcid=self.vpc.id
)
self.debug("Associating public IP for network: %s" %
self.network_2.name)
public_ip_2 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=self.network_2.id,
vpcid=self.vpc.id
)
self.debug("Associated %s with network %s" % (
public_ip_2.ipaddress.ipaddress,
self.network_2.id
))
nat_rule_2 = NATRule.create(
self.apiclient,
self.vm_3,
self.services["natrule"],
ipaddressid=public_ip_2.ipaddress.id,
openfirewall=False,
networkid=self.network_2.id,
vpcid=self.vpc.id
)
self.debug("Listing all the PF rules belonging to VPC")
nat_rules = NATRule.list(
self.apiclient,
vpcid=self.vpc.id,
listall=True
)
self.assertEqual(
isinstance(nat_rules, list),
True,
"List NAT rules should return the valid list"
)
self.assertEqual(
len(nat_rules),
2,
"List NAT for VPC shall return all NAT rules belonging to VPC"
)
for nat_rule in nat_rules:
self.assertEqual(
nat_rule.vpcid,
self.vpc.id,
"NAT rules should belong to VPC"
)
self.debug(
"Listing all the VMs belonging to VPC for network: %s" %
self.network_1.name)
vms = VirtualMachine.list(
self.apiclient,
networkid=self.network_1.id,
vpcid=self.vpc.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List virtual machines should return the valid list"
)
for vm in vms:
self.assertEqual(
vm.networkid,
self.network_1.id,
"List VMs should return vms belonging to network_1"
)
return
return

View File

@ -0,0 +1,323 @@
# 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 nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
class Services:
"""Test VPC services
"""
def __init__(self):
self.services = {
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "test",
# Random characters are appended for unique
# username
"password": "password",
},
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100,
"memory": 128,
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"virtual_machine": {
"displayname": "Test VM",
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
# Hypervisor type should be same as
# hypervisor type of cluster
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"ostype": 'CentOS 5.3 (64-bit)',
# Cent OS 5.3 (64 bit)
"sleep": 60,
"timeout": 10
}
class TestVPCHostMaintenance(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestVPCHostMaintenance,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.services["mode"] = cls.zone.networktype
cls.service_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offering"]
)
cls.vpc_off = VpcOffering.create(
cls.api_client,
cls.services["vpc_offering"]
)
cls.vpc_off.update(cls.api_client, state='Enabled')
hosts = Host.list(
cls.api_client,
zoneid=cls.zone.id,
listall=True,
type='Routing'
)
if isinstance(hosts, list):
for host in hosts:
Host.enableMaintenance(
cls.api_client,
id=host.id
)
timeout = cls.services["timeout"]
while True:
time.sleep(cls.services["sleep"])
hosts_states = Host.list(
cls.api_client,
id=host.id,
listall=True
)
if hosts_states[0].resourcestate == 'PrepareForMaintenance':
# Wait for sometimetill host goes in maintenance state
time.sleep(cls.services["sleep"])
elif hosts_states[0].resourcestate == 'Maintenance':
time.sleep(cls.services["sleep"])
break
elif timeout == 0:
raise unittest.SkipTest(
"Failed to enable maintenance mode on %s" % host.name)
timeout = timeout - 1
cls._cleanup = [
cls.service_offering,
cls.vpc_off
]
return
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
hosts = Host.list(
cls.api_client,
zoneid=cls.zone.id,
listall=True,
type='Routing'
)
if isinstance(hosts, list):
for host in hosts:
Host.cancelMaintenance(
cls.api_client,
id=host.id
)
hosts_states = Host.list(
cls.api_client,
id=host.id,
listall=True
)
if hosts_states[0].resourcestate != 'Enabled':
raise Exception(
"Failed to cancel maintenance mode on %s" % (host.name))
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.account = Account.create(
self.apiclient,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = [self.account]
return
def tearDown(self):
try:
#Clean up, terminate the created network offerings
cleanup_resources(self.apiclient, self.cleanup)
interval = list_configurations(
self.apiclient,
name='network.gc.interval'
)
wait = list_configurations(
self.apiclient,
name='network.gc.wait'
)
# Sleep to ensure that all resources are deleted
time.sleep(int(interval[0].value) + int(wait[0].value))
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def validate_vpc_offering(self, vpc_offering):
"""Validates the VPC offering"""
self.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
self.assertEqual(
isinstance(vpc_offs, list),
True,
"List VPC offerings should return a valid list"
)
self.assertEqual(
vpc_offering.name,
vpc_offs[0].name,
"Name of the VPC offering should match with listVPCOff data"
)
self.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def validate_vpc_network(self, network, state=None):
"""Validates the VPC network"""
self.debug("Check if the VPC network is created successfully?")
vpc_networks = VPC.list(
self.apiclient,
id=network.id
)
self.assertEqual(
isinstance(vpc_networks, list),
True,
"List VPC network should return a valid list"
)
self.assertEqual(
network.name,
vpc_networks[0].name,
"Name of the VPC network should match with listVPC data"
)
if state:
self.assertEqual(
vpc_networks[0].state,
state,
"VPC state should be '%s'" % state
)
self.debug("VPC network validated - %s" % network.name)
return
@attr(tags=["advanced", "intervlan"])
def test_01_create_vpc_host_maintenance(self):
""" Test VPC when host is in maintenance mode
"""
# Validate the following
# 1. Put the host in maintenance mode.
# 2. Attempt to Create a VPC with cidr - 10.1.1.1/16
# 3. VPC will be created but will be in "Disabled" state
self.debug("creating a VPC network in the account: %s" %
self.account.name)
self.services["vpc"]["cidr"] = '10.1.1.1/16'
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=self.vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.validate_vpc_network(vpc, state='Disabled')
return
@attr(tags=["advanced", "intervlan"])
def test_02_create_vpc_wait_gc(self):
""" Test VPC when host is in maintenance mode and wait till nw gc
"""
# Validate the following
# 1. Put the host in maintenance mode.
# 2. Attempt to Create a VPC with cidr - 10.1.1.1/16
# 3. Wait for the VPC GC thread to run.
# 3. VPC will be created but will be in "Disabled" state and should
# get deleted
self.debug("creating a VPC network in the account: %s" %
self.account.name)
self.services["vpc"]["cidr"] = '10.1.1.1/16'
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=self.vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.validate_vpc_network(vpc, state='Disabled')
interval = list_configurations(
self.apiclient,
name='network.gc.interval'
)
wait = list_configurations(
self.apiclient,
name='network.gc.wait'
)
self.debug("Sleep till network gc thread runs..")
# Sleep to ensure that all resources are deleted
time.sleep(int(interval[0].value) + int(wait[0].value))
vpcs = VPC.list(
self.apiclient,
id=vpc.id,
listall=True
)
self.assertEqual(
vpcs,
None,
"List VPC should not return anything after network gc"
)
return

View File

@ -84,6 +84,7 @@ class Services:
"isfeatured": True,
"ispublic": True,
"isextractable": True,
"ostype": 'CentOS 5.3 (64-bit)',
},
"natrule": {
"publicport": 22,

View File

@ -300,7 +300,7 @@ class TestInstanceNameFlagTrue(cloudstackTestCase):
"Running",
"Vm state should be running after deployment"
)
self.assertEqual(
self.assertNotEqual(
vm.displayname,
vm.id,
"Vm display name should not match the given name"

View File

@ -18,16 +18,12 @@
""" Component tests for VPC functionality
"""
#Import Local Modules
import marvin
import unittest
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from marvin.remoteSSHClient import remoteSSHClient
import datetime
class Services:
@ -331,7 +327,7 @@ class TestVPC(cloudstackTestCase):
@attr(tags=["advanced", "intervlan"])
def test_02_restart_vpc_with_networks(self):
""" Test restart VPC having with networks
""" Test restart VPC having networks
"""
# Validate the following
@ -2474,250 +2470,4 @@ class TestVPC(cloudstackTestCase):
"Updation of VPC display text failed.")
class TestVPCHostMaintenance(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestVPCHostMaintenance,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offering"]
)
cls.vpc_off = VpcOffering.create(
cls.api_client,
cls.services["vpc_offering"]
)
cls.vpc_off.update(cls.api_client, state='Enabled')
hosts = Host.list(
cls.api_client,
zoneid=cls.zone.id,
listall=True,
type='Routing'
)
if isinstance(hosts, list):
for host in hosts:
Host.enableMaintenance(
cls.api_client,
id=host.id
)
timeout = cls.services["timeout"]
while True:
time.sleep(cls.services["sleep"])
hosts_states = Host.list(
cls.api_client,
id=host.id,
listall=True
)
if hosts_states[0].resourcestate == 'PrepareForMaintenance':
# Wait for sometimetill host goes in maintenance state
time.sleep(cls.services["sleep"])
elif hosts_states[0].resourcestate == 'Maintenance':
time.sleep(cls.services["sleep"])
break
elif timeout == 0:
raise unittest.SkipTest(
"Failed to enable maintenance mode on %s" % host.name)
timeout = timeout - 1
cls._cleanup = [
cls.service_offering,
cls.vpc_off
]
return
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
hosts = Host.list(
cls.api_client,
zoneid=cls.zone.id,
listall=True,
type='Routing'
)
if isinstance(hosts, list):
for host in hosts:
Host.cancelMaintenance(
cls.api_client,
id=host.id
)
hosts_states = Host.list(
cls.api_client,
id=host.id,
listall=True
)
if hosts_states[0].resourcestate != 'Enabled':
raise Exception(
"Failed to cancel maintenance mode on %s" % (host.name))
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.account = Account.create(
self.apiclient,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = [self.account]
return
def tearDown(self):
try:
#Clean up, terminate the created network offerings
cleanup_resources(self.apiclient, self.cleanup)
interval = list_configurations(
self.apiclient,
name='network.gc.interval'
)
wait = list_configurations(
self.apiclient,
name='network.gc.wait'
)
# Sleep to ensure that all resources are deleted
time.sleep(int(interval[0].value) + int(wait[0].value))
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def validate_vpc_offering(self, vpc_offering):
"""Validates the VPC offering"""
self.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
self.assertEqual(
isinstance(vpc_offs, list),
True,
"List VPC offerings should return a valid list"
)
self.assertEqual(
vpc_offering.name,
vpc_offs[0].name,
"Name of the VPC offering should match with listVPCOff data"
)
self.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def validate_vpc_network(self, network, state=None):
"""Validates the VPC network"""
self.debug("Check if the VPC network is created successfully?")
vpc_networks = VPC.list(
self.apiclient,
id=network.id
)
self.assertEqual(
isinstance(vpc_networks, list),
True,
"List VPC network should return a valid list"
)
self.assertEqual(
network.name,
vpc_networks[0].name,
"Name of the VPC network should match with listVPC data"
)
if state:
self.assertEqual(
vpc_networks[0].state,
state,
"VPC state should be '%s'" % state
)
self.debug("VPC network validated - %s" % network.name)
return
@attr(tags=["advanced", "intervlan"])
def test_01_create_vpc_host_maintenance(self):
""" Test VPC when host is in maintenance mode
"""
# Validate the following
# 1. Put the host in maintenance mode.
# 2. Attempt to Create a VPC with cidr - 10.1.1.1/16
# 3. VPC will be created but will be in "Disabled" state
self.debug("creating a VPC network in the account: %s" %
self.account.name)
self.services["vpc"]["cidr"] = '10.1.1.1/16'
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=self.vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.validate_vpc_network(vpc, state='Disabled')
return
@attr(tags=["advanced", "intervlan"])
def test_02_create_vpc_wait_gc(self):
""" Test VPC when host is in maintenance mode and wait till nw gc
"""
# Validate the following
# 1. Put the host in maintenance mode.
# 2. Attempt to Create a VPC with cidr - 10.1.1.1/16
# 3. Wait for the VPC GC thread to run.
# 3. VPC will be created but will be in "Disabled" state and should
# get deleted
self.debug("creating a VPC network in the account: %s" %
self.account.name)
self.services["vpc"]["cidr"] = '10.1.1.1/16'
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=self.vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.validate_vpc_network(vpc, state='Disabled')
interval = list_configurations(
self.apiclient,
name='network.gc.interval'
)
wait = list_configurations(
self.apiclient,
name='network.gc.wait'
)
self.debug("Sleep till network gc thread runs..")
# Sleep to ensure that all resources are deleted
time.sleep(int(interval[0].value) + int(wait[0].value))
vpcs = VPC.list(
self.apiclient,
id=vpc.id,
listall=True
)
self.assertEqual(
vpcs,
None,
"List VPC should not return anything after network gc"
)
return

View File

@ -664,6 +664,32 @@ class TestLoadBalancingRule(cloudstackTestCase):
cleanup_resources(cls.api_client, cls._cleanup)
return
def try_ssh(self, src_nat_ip_addr, hostnames):
try:
self.debug(
"SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" %
(self.vm_1.ipaddress, src_nat_ip_addr.ipaddress)
)
ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
# If Round Robin Algorithm is chosen,
# each ssh command should alternate between VMs
# hostnames = [ssh_1.execute("hostname")[0]]
hostnames.append(ssh_1.execute("hostname")[0])
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
time.sleep(self.services["lb_switch_wait"])
return
@attr(tags = ["advanced", "advancedns", "smoke"])
def test_01_create_lb_rule_src_nat(self):
"""Test to create Load balancing rule with source NAT"""
@ -776,62 +802,33 @@ class TestLoadBalancingRule(cloudstackTestCase):
[self.vm_1.id, self.vm_2.id],
"Check List Load Balancer instances Rules returns valid VM ID"
)
try:
self.debug(
"SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" %
(self.vm_1.ipaddress, src_nat_ip_addr.ipaddress)
)
ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
# If Round Robin Algorithm is chosen,
# each ssh command should alternate between VMs
hostnames = [ssh_1.execute("hostname")[0]]
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
hostnames = []
self.try_ssh(src_nat_ip_addr, hostnames)
self.try_ssh(src_nat_ip_addr, hostnames)
self.try_ssh(src_nat_ip_addr, hostnames)
self.try_ssh(src_nat_ip_addr, hostnames)
self.try_ssh(src_nat_ip_addr, hostnames)
time.sleep(self.services["lb_switch_wait"])
try:
self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" %
(
src_nat_ip_addr.ipaddress,
self.vm_1.id,
self.vm_2.id
))
ssh_2 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
hostnames.append(ssh_2.execute("hostname")[0])
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
self.debug("Hostnames: %s" % str(hostnames))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_2.name,
hostnames,
"Check if ssh succeeded for server2"
)
self.debug("Hostnames: %s" % str(hostnames))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_2.name,
hostnames,
"Check if ssh succeeded for server2"
)
#SSH should pass till there is a last VM associated with LB rule
lb_rule.remove(self.apiclient, [self.vm_2])
# making hostnames list empty
hostnames[:] = []
try:
self.debug("SSHing into IP address: %s after removing VM (ID: %s)" %
(
@ -839,25 +836,18 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.vm_2.id
))
ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
self.try_ssh(src_nat_ip_addr, hostnames)
hostnames.append(ssh_1.execute("hostname")[0])
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
self.assertIn(
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
lb_rule.remove(self.apiclient, [self.vm_1])
with self.assertRaises(Exception):
@ -967,50 +957,24 @@ class TestLoadBalancingRule(cloudstackTestCase):
"Check List Load Balancer instances Rules returns valid VM ID"
)
try:
self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" %
(
self.non_src_nat_ip.ipaddress.ipaddress,
self.vm_1.id,
self.vm_2.id
))
ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
hostnames = []
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
# If Round Robin Algorithm is chosen,
# each ssh command should alternate between VMs
hostnames = [ssh_1.execute("hostname")[0]]
time.sleep(self.services["lb_switch_wait"])
self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" %
(
self.non_src_nat_ip.ipaddress.ipaddress,
self.vm_1.id,
self.vm_2.id
))
ssh_2 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
hostnames.append(ssh_2.execute("hostname")[0])
self.debug("Hostnames after adding 2 VMs to LB rule: %s" % str(hostnames))
self.assertIn(
self.debug("Hostnames: %s" % str(hostnames))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
self.assertIn(
)
self.assertIn(
self.vm_2.name,
hostnames,
"Check if ssh succeeded for server2"
)
)
#SSH should pass till there is a last VM associated with LB rule
lb_rule.remove(self.apiclient, [self.vm_2])
@ -1020,25 +984,23 @@ class TestLoadBalancingRule(cloudstackTestCase):
self.non_src_nat_ip.ipaddress.ipaddress,
self.vm_2.id
))
ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
# Making host list empty
hostnames[:] = []
self.try_ssh(self.non_src_nat_ip, hostnames)
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
hostnames.append(ssh_1.execute("hostname")[0])
self.debug("Hostnames after removing VM2: %s" % str(hostnames))
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, self.non_src_nat_ip.ipaddress.ipaddress))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
lb_rule.remove(self.apiclient, [self.vm_1])
with self.assertRaises(Exception):
self.debug("SSHing into IP address: %s after removing VM (ID: %s) from LB rule" %
@ -1209,7 +1171,7 @@ class TestRebootRouter(cloudstackTestCase):
except Exception as e:
self.fail(
"SSH Access failed for %s: %s" % \
(self.nat_rule.ipaddress.ipaddress, e))
(self.vm_1.ipaddress, e))
return
def tearDown(self):
@ -1277,6 +1239,36 @@ class TestAssignRemoveLB(cloudstackTestCase):
]
return
def tearDown(self):
cleanup_resources(self.apiclient, self.cleanup)
return
def try_ssh(self, src_nat_ip_addr, hostnames):
try:
self.debug(
"SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" %
(self.vm_1.ipaddress, src_nat_ip_addr.ipaddress)
)
ssh_1 = remoteSSHClient(
src_nat_ip_addr.ipaddress,
self.services['lbrule']["publicport"],
self.vm_1.username,
self.vm_1.password
)
# If Round Robin Algorithm is chosen,
# each ssh command should alternate between VMs
# hostnames = [ssh_1.execute("hostname")[0]]
hostnames.append(ssh_1.execute("hostname")[0])
except Exception as e:
self.fail("%s: SSH failed for VM with IP Address: %s" %
(e, src_nat_ip_addr.ipaddress))
time.sleep(self.services["lb_switch_wait"])
return
@attr(tags = ["advanced", "advancedns", "smoke"])
def test_assign_and_removal_lb(self):
"""Test for assign & removing load balancing rule"""
@ -1344,137 +1336,74 @@ class TestAssignRemoveLB(cloudstackTestCase):
)
lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2])
try:
self.debug("SSHing into IP address: %s with VMs (ID: %s , %s) added to LB rule" %
(
self.non_src_nat_ip.ipaddress,
self.vm_1.id,
self.vm_2.id
))
#Create SSH client for each VM
ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
self.vm_1.password
)
except Exception as e:
self.fail("SSH failed for VM with IP: %s" %
self.non_src_nat_ip.ipaddress)
hostnames = []
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
try:
self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" %
(
self.non_src_nat_ip.ipaddress,
self.vm_1.id,
self.vm_2.id
))
ssh_2 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_2.username,
self.vm_2.password
)
self.debug("Hostnames: %s" % str(hostnames))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_2.name,
hostnames,
"Check if ssh succeeded for server2"
)
# If Round Robin Algorithm is chosen,
# each ssh command should alternate between VMs
res_1 = ssh_1.execute("hostname")[0]
self.debug(res_1)
time.sleep(self.services["lb_switch_wait"])
res_2 = ssh_2.execute("hostname")[0]
self.debug(res_2)
except Exception as e:
self.fail("SSH failed for VM with IP: %s" %
self.non_src_nat_ip.ipaddress)
self.assertIn(
self.vm_1.name,
res_1,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_2.name,
res_2,
"Check if ssh succeeded for server2"
)
#Removing VM and assigning another VM to LB rule
lb_rule.remove(self.apiclient, [self.vm_2])
# making hostnames list empty
hostnames[:] = []
try:
self.debug("SSHing again into IP address: %s with VM (ID: %s) added to LB rule" %
(
self.non_src_nat_ip.ipaddress,
self.vm_1.id,
))
# Again make a SSH connection, as previous is not used after LB remove
ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
self.vm_1.password
)
res_1 = ssh_1.execute("hostname")[0]
self.debug(res_1)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
except Exception as e:
self.fail("SSH failed for VM with IP: %s" %
self.non_src_nat_ip.ipaddress)
self.assertIn(
self.vm_1.name,
res_1,
"Check if ssh succeeded for server1"
)
lb_rule.assign(self.apiclient, [self.vm_3])
try:
ssh_1 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_1.username,
self.vm_1.password
)
ssh_3 = remoteSSHClient(
self.non_src_nat_ip.ipaddress,
self.services["lbrule"]["publicport"],
self.vm_3.username,
self.vm_3.password
)
# Making hostnames list empty
hostnames[:] = []
res_1 = ssh_1.execute("hostname")[0]
self.debug(res_1)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
self.try_ssh(self.non_src_nat_ip, hostnames)
time.sleep(self.services["lb_switch_wait"])
res_3 = ssh_3.execute("hostname")[0]
self.debug(res_3)
except Exception as e:
self.fail("SSH failed for VM with IP: %s" %
self.non_src_nat_ip.ipaddress)
self.assertIn(
self.vm_1.name,
res_1,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_3.name,
res_3,
"Check if ssh succeeded for server3"
)
self.debug("Hostnames: %s" % str(hostnames))
self.assertIn(
self.vm_1.name,
hostnames,
"Check if ssh succeeded for server1"
)
self.assertIn(
self.vm_3.name,
hostnames,
"Check if ssh succeeded for server3"
)
return
def tearDown(self):
cleanup_resources(self.apiclient, self.cleanup)
return
class TestReleaseIP(cloudstackTestCase):
def setUp(self):

View File

@ -150,10 +150,10 @@ version="1.0">
</div>
<div id="footer_mainmaster">
<p>Copyright © 2012 The Apache Software Foundation, Licensed under the
<p>Copyright © 2013 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</a> <br />
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>
</div>
</div>

View File

@ -179,9 +179,9 @@ version="1.0">
<li> <a href="#"> Contacts</a> </li>
</ul>
<p>Copyright © 2012 The Apache Software Foundation, Licensed under the
<p>Copyright © 2013 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</a> <br />
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>

View File

@ -144,9 +144,9 @@ version="1.0">
</div>
<div id="footer">
<div id="footer_mainmaster">
<p>Copyright © 2012 The Apache Software Foundation, Licensed under the
<p>Copyright © 2013 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</a> <br />
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>

View File

@ -26,9 +26,9 @@ under the License.
<div id="footer">
<div id="footer_mainmaster">
<p>Copyright © 2012 The Apache Software Foundation, Licensed under the
<p>Copyright © 2013 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</a> <br />
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>
</div>

View File

@ -142,9 +142,9 @@ version="1.0">
<div id="footer">
<div id="footer_mainmaster">
<p>Copyright © 2012 The Apache Software Foundation, Licensed under the
<p>Copyright © 2013 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</a> <br />
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
Apache, CloudStack, Apache CloudStack, the Apache CloudStack logo, the CloudMonkey logo and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -239,7 +239,7 @@ a:hover.insdownload_button {
a.cloud_logo {
width:300px;
width:373px;
height:51px;
float:left;
background:url(../images/cloudstack.png) no-repeat top left;

View File

@ -18,7 +18,7 @@
# Use following rules for versioning:
# <cloudstack version>-<cli increment, starts from 0>
__version__ = "4.1.0-0"
__version__ = "4.2.0-0"
__description__ = "Command Line Interface for Apache CloudStack"
__maintainer__ = "Rohit Yadav"
__maintaineremail__ = "bhaisaab@apache.org"

View File

@ -125,61 +125,36 @@ def monkeyrequest(command, args, isasync, asyncblock, logger, host, port,
command = "queryAsyncJobResult"
request = {'jobid': jobid}
timeout = int(timeout)
pollperiod = 3
pollperiod = 2
progress = 1
while timeout > 0:
print '\r' + '.' * progress,
sys.stdout.flush()
progress += 1
time.sleep(pollperiod)
timeout = timeout - pollperiod
progress += 1
logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout))
sys.stdout.flush()
if re.match("queryAsyncJobResult", command):
time.sleep(pollperiod)
else:
response, error = monkeyrequest(command, request, isasync,
asyncblock, logger,
host, port, apikey, secretkey,
timeout, protocol, path)
response, error = make_request(command, request, logger,
host, port, apikey, secretkey,
protocol, path)
if error is not None:
return response, error
response = process_json(response)
responsekeys = filter(lambda x: 'response' in x, response.keys())
if len(responsekeys) < 1:
time.sleep(pollperiod)
continue
result = response[responsekeys[0]]
jobstatus = result['jobstatus']
jobresultcode = result['jobresultcode']
try:
jobresult = result["jobresult"]
logger_debug(logger, "jobresult %s" % (jobresult))
sys.stdout.flush()
return response, None
except KeyError:
logger_debug(logger, "No jobresult yet %s" % (result))
sys.stdout.flush()
if jobresultcode != 0:
error = "Error: resultcode %d for jobid %s" % (jobresultcode,
jobid)
logger_debug(logger, "%s" % (error))
return response, error
else:
# if we get a valid respons resultcode give back results
response, error = monkeyrequest(command, request, isasync,
asyncblock, logger,
host, port, apikey, secretkey,
timeout, protocol, path)
logger_debug(logger, "Ok: %s" % (jobid))
return response, error
if jobstatus == 2:
jobresult = result["jobresult"]
error = "\rAsync job %s failed\nError %s, %s" % (jobid,
jobresult["errorcode"], jobresult["errortext"])
return response, error
elif jobstatus == 1:
print '\r',
print "\r" + " " * progress,
return response, error
else:
logger_debug(logger, "We should not arrive here!")

View File

@ -1698,7 +1698,6 @@ under the License.
<script type="text/javascript" src="scripts/docs.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/vm_snapshots.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/projectSelect.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/zoneFilter.js?t=<%=now%>"></script>
<!-- Plugin/module API -->
<script type="text/javascript" src="scripts/ui-custom/pluginListing.js?t=<%=now%>"></script>

View File

@ -1411,8 +1411,11 @@
}
});
}
$providers.each(function() {
$(this).val($(this).find('option:first'));
$providers.each(function() {
//if selected option is disabled, select the first enabled option instead
if($(this).find('option:selected:disabled').length > 0) {
$(this).val($(this).find('option:first'));
}
});

View File

@ -1340,7 +1340,7 @@
docID: 'helpGuestNetworkZoneVLANID'
},
isolatedpvlanId: {
label: 'Private VLAN ID'
label: 'Secondary Isolated VLAN ID'
},
scope: {
@ -7899,7 +7899,13 @@
lbdevicededicated: {
label: 'label.dedicated',
converter: cloudStack.converters.toBooleanText
}
},
gslbprovider: {
label: 'GSLB service',
converter: cloudStack.converters.toBooleanText
},
gslbproviderpublicip: { label: 'GSLB service Public IP' },
gslbproviderprivateip: { label: 'GSLB service Private IP' }
}
],
dataProvider: function(args) {

View File

@ -1327,6 +1327,12 @@
});
$table.dataTable(null, { noSelect: uiCustom });
if(args.data &&
args.data.length < pageSize &&
options.setEndTable) {
options.setEndTable();
}
setTimeout(function() {
$table.dataTable('refresh');
});
@ -1467,6 +1473,12 @@
var page = 1;
var actions = listViewData.actions;
var reorder = listViewData.reorder;
var tableHeight = $table.height();
var endTable = false;
var setEndTable = function() {
endTable = true;
}
var $switcher;
if (args.sections) {
@ -1572,7 +1584,8 @@
{
context: args.context,
reorder: reorder,
detailView: listViewData.detailView
detailView: listViewData.detailView,
setEndTable: setEndTable
}
);
@ -1625,7 +1638,8 @@
{
context: $listView.data('view-args').context,
reorder: listViewData.reorder,
detailView: listViewData.detailView
detailView: listViewData.detailView,
setEndTable: setEndTable
}
);
};
@ -1675,7 +1689,8 @@
{
context: $listView.data('view-args').context,
reorder: listViewData.reorder,
detailView: listViewData.detailView
detailView: listViewData.detailView,
setEndTable: setEndTable
}
);
};
@ -1728,8 +1743,6 @@
return false;
});
var tableHeight = $table.height();
var endTable = false;
// Infinite scrolling event
$listView.bind('scroll', function(event) {
@ -1767,7 +1780,8 @@
filterBy: filterBy
}, actions, {
reorder: listViewData.reorder,
detailView: listViewData.detailView
detailView: listViewData.detailView,
setEndTable: setEndTable
});
$table.height() == tableHeight ? endTable = true : tableHeight = $table.height();
}

View File

@ -97,6 +97,13 @@
name != 'icmpcode' &&
name != 'cidrlist';
});
var $portFields = $inputs.filter(function() {
var name = $(this).attr('name');
return $.inArray(name, [
'startport',
'endport'
]) > -1;
});
var $protocolinput = args.$form.find('td input');
var $protocolFields = $protocolinput.filter(function(){
@ -124,6 +131,10 @@
$icmpFields.hide();
$icmpFields.parent().find('label.error').hide();
$protocolFields.hide().removeClass('required');
if ($(this).val() == 'all'){
$portFields.attr('disabled', 'disabled');
$portFields.hide();
}
}
});
@ -216,11 +227,11 @@
if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.startport=="" || args.data.startport == undefined)){
if((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.startport=="" || args.data.startport == undefined)){
cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')});
$(window).trigger('cloudStack.fullRefresh');
}
else if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.endport=="" || args.data.endport == undefined)){
else if((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.endport=="" || args.data.endport == undefined)){
cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')});
$(window).trigger('cloudStack.fullRefresh');
}
@ -761,7 +772,7 @@
}
});
},
notificaton: {
notification: {
poll: pollAsyncJobResult
}
}

View File

@ -1394,4 +1394,13 @@ public class NetUtils {
return null;
}
public static String generateMacOnIncrease(String baseMac, long l) {
long mac = mac2Long(baseMac);
if (l > 0xFFFFl) {
return null;
}
mac = mac + (l << 24);
mac = mac & 0x06FFFFFFFFFFl;
return long2Mac(mac);
}
}

View File

@ -155,4 +155,17 @@ public class NetUtilsTest extends TestCase {
//Check for Incorrect format of CIDR
assertFalse(NetUtils.isSameIpRange(cidrFirst, "10.3.6.5/50"));
}
public void testMacGenerateion() {
String mac = "06:01:23:00:45:67";
String newMac = NetUtils.generateMacOnIncrease(mac, 2);
assertTrue(newMac.equals("06:01:25:00:45:67"));
newMac = NetUtils.generateMacOnIncrease(mac, 16);
assertTrue(newMac.equals("06:01:33:00:45:67"));
mac = "06:ff:ff:00:45:67";
newMac = NetUtils.generateMacOnIncrease(mac, 1);
assertTrue(newMac.equals("06:00:00:00:45:67"));
newMac = NetUtils.generateMacOnIncrease(mac, 16);
assertTrue(newMac.equals("06:00:0f:00:45:67"));
}
}