Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cloudstack into disk_io_throttling
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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///////////////////
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@
|
|||
<property name="Adapters">
|
||||
<list>
|
||||
<ref bean="HostAntiAffinityProcessor" />
|
||||
<ref bean="ExplicitDedicationProcessor"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 + "'");
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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)){
|
||||
|
|
|
|||
|
|
@ -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}]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
"""
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -84,6 +84,7 @@ class Services:
|
|||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": True,
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
},
|
||||
"natrule": {
|
||||
"publicport": 22,
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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!")
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||