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

This commit is contained in:
Wei Zhou 2013-06-10 15:01:53 +02:00
commit 080bb76187
56 changed files with 1434 additions and 1562 deletions

View File

@ -272,4 +272,6 @@ public interface NetworkModel {
Map<Detail, String> getNtwkOffDetails(long offId);
Networks.IsolationType[] listNetworkIsolationMethods();
Nic getNicInNetworkIncludingRemoved(long vmId, long networkId);
}

View File

@ -19,7 +19,7 @@ package org.apache.cloudstack.api.command.user.affinitygroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@ -28,7 +28,7 @@ import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
@APICommand(name = "listAffinityGroups", description = "Lists affinity groups", responseObject = AffinityGroupResponse.class)
public class ListAffinityGroupsCmd extends BaseListCmd {
public class ListAffinityGroupsCmd extends BaseListAccountResourcesCmd {
public static final Logger s_logger = Logger.getLogger(ListAffinityGroupsCmd.class.getName());
private static final String s_name = "listaffinitygroupsresponse";
@ -77,7 +77,8 @@ public class ListAffinityGroupsCmd extends BaseListCmd {
public void execute(){
ListResponse<AffinityGroupResponse> response = _queryService.listAffinityGroups(id, affinityGroupName,
affinityGroupType, virtualMachineId, this.getStartIndex(), this.getPageSizeVal());
affinityGroupType, virtualMachineId, this.getAccountName(), this.getDomainId(), this.isRecursive(),
this.listAll(), this.getStartIndex(), this.getPageSizeVal());
response.setResponseName(getCommandName());
this.setResponseObject(response);

View File

@ -86,7 +86,8 @@ public interface QueryService {
public ListResponse<ZoneResponse> listDataCenters(ListZonesByCmd cmd);
public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName,
String affinityGroupType, Long vmId, Long startIndex, Long pageSize);
String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive,
boolean listAll, Long startIndex, Long pageSize);
public List<ResourceDetailResponse> listResource(ListResourceDetailsCmd cmd);

View File

@ -48,6 +48,7 @@
</bookinfo>
<xi:include href="gsoc-tuna.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<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" />
</book>

View File

@ -48,6 +48,7 @@ under the License.
<section id="generating-rpms">
<title>Generating RPMS</title>
<para>Now that we have the prerequisites and source, you will cd to the <filename>packaging/centos63/</filename> directory.</para>
<programlisting><prompt>$</prompt> cd packaging/centos63</programlisting>
<para>Generating RPMs is done using the <filename>package.sh</filename> script:
<programlisting><prompt>$</prompt>./package.sh</programlisting>
</para>

View File

@ -0,0 +1,149 @@
<?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-dharmesh">
<title>Dharmesh's 2013 GSoC Proposal</title>
<para>This chapter describes Dharmrsh's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal.</para>
<section id="abstract-dharmesh">
<title>Abstract</title>
<para>
The project aims to bring <ulink url="http://aws.amazon.com/cloudformation/"><citetitle>cloudformation</citetitle></ulink> like service to cloudstack. One of the prime use-case is cluster computing frameworks on cloudstack. A cloudformation service will give users and administrators of cloudstack ability to manage and control a set of resources easily. The cloudformation will allow booting and configuring a set of VMs and form a cluster. Simple example would be LAMP stack. More complex clusters such as mesos or hadoop cluster requires a little more advanced configuration. There is already some work done by Chiradeep Vittal at this front [5]. In this project, I will implement server side cloudformation service for cloudstack and demonstrate how to run mesos cluster using it.
</para>
</section>
<section id="mesos">
<title>Mesos</title>
<para>
<ulink url="http://incubator.apache.org/mesos/"><citetitle>Mesos</citetitle></ulink> is a resource management platform for clusters. It aims to increase resource utilization of clusters by sharing cluster resources among multiple processing frameworks(like MapReduce, MPI, Graph Processing) or multiple instances of same framework. It provides efficient resource isolation through use of containers. Uses zookeeper for state maintenance and fault tolerance.
</para>
</section>
<section id="mesos-use">
<title>What can run on mesos ?</title>
<para><emphasis role="bold">Spark:</emphasis> A cluster computing framework based on the Resilient Distributed Datasets (RDDs) abstraction. RDD is more generalized than MapReduce and can support iterative and interactive computation while retaining fault tolerance, scalability, data locality etc.</para>
<para><emphasis role="bold">Hadoop:</emphasis>: Hadoop is fault tolerant and scalable distributed computing framework based on MapReduce abstraction.</para>
<para><emphasis role="bold">Begel:</emphasis>: A graph processing framework based on pregel.</para>
<para>and other frameworks like MPI, Hypertable.</para>
</section>
<section id="mesos-deploy">
<title>How to deploy mesos ?</title>
<para>Mesos provides cluster installation <ulink url="https://github.com/apache/mesos/blob/trunk/docs/Deploy-Scripts.textile"><citetitle>scripts</citetitle></ulink> for cluster deployment. There are also scripts available to deploy a cluster on <ulink url="https://github.com/apache/mesos/blob/trunk/docs/EC2-Scripts.textile"><citetitle>Amazon EC2</citetitle></ulink>. It would be interesting to see if this scripts can be leveraged in anyway.</para>
</section>
<section id="deliverables-dharmesh">
<title>Deliverables</title>
<orderedlist>
<listitem>
<para>Deploy CloudStack and understand instance configuration/contextualization</para>
</listitem>
<listitem>
<para>Test and deploy Mesos on a set of CloudStack based VM, manually. Design/propose an automation framework</para>
</listitem>
<listitem>
<para>Test stackmate and engage chiradeep (report bugs, make suggestion, make pull request)</para>
</listitem>
<listitem>
<para>Create cloudformation template to provision a Mesos Cluster</para>
</listitem>
<listitem>
<para>Compare with Apache Whirr or other cluster provisioning tools for server side implementation of cloudformation service.</para>
</listitem>
</orderedlist>
</section>
<section id="arch-and-tools">
<title>Architecture and Tools</title>
<para>The high level architecture is as follows:</para>
<para>
<mediaobject>
<imageobject>
<imagedata fileref="images/mesos-integration-arch.jpg"/>
</imageobject>
</mediaobject>
</para>
<para>It includes following components:</para>
<orderedlist>
<listitem>
<para>CloudFormation Query API server:</para>
<para>This acts as a point of contact to and exposes CloudFormation functionality as Query API. This can be accessed directly or through existing tools from Amazon AWS for their cloudformation service. It will be easy to start as a module which resides outside cloudstack at first and I plan to use dropwizard [3] to start with. Later may be the API server can be merged with cloudstack core. I plan to use mysql for storing details of clusters.</para>
</listitem>
<listitem>
<para>Provisioning:</para>
<para>Provisioning module is responsible for handling the booting process of the VMs through cloudstack. This uses the cloudstack APIs for launching VMs. I plan to use preconfigured templates/images with required dependencies installed, which will make cluster creation process much faster even for large clusters. Error handling is very important part of this module. For example, what you do if few VMs fail to boot in cluster ?</para>
</listitem>
<listitem>
<para>Configuration:</para>
<para>This module deals with configuring the VMs to form a cluster. This can be done via manual scripts/code or via configuration management tools like chef/ironfan/knife. Potentially workflow automation tools like rundeck [4] also can be used. Also Apache whirr and Provisionr are options. I plan to explore this tools and select suitable ones.</para>
</listitem>
</orderedlist>
</section>
<section id="api">
<title>API</title>
<para>Query <ulink url="http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Operations.html"><citetitle>API</citetitle></ulink> will be based on Amazon AWS cloudformation service. This will allow leveraging existing <ulink url="http://aws.amazon.com/developertools/AWS-CloudFormation"><citetitle>tools</citetitle></ulink> for AWS.</para>
</section>
<section id="timeline">
<title>Timeline</title>
<para>1-1.5 week : project design. Architecture, tools selection, API design</para>
<para>1-1.5 week : getting familiar with cloudstack and stackmate codebase and architecture details</para>
<para>1-1.5 week : getting familiar with mesos internals</para>
<para>1-1.5 week : setting up the dev environment and create mesos templates</para>
<para>2-3 week : build provisioning and configuration module</para>
<para>Midterm evaluation: provisioning module, configuration module</para>
<para>2-3 week : develope cloudformation server side implementation</para>
<para>2-3 week : test and integrate</para>
</section>
<section id="future-work">
<title>Future Work</title>
<orderedlist>
<listitem>
<para><emphasis role="bold">Auto Scaling:</emphasis></para>
<para>Automatically adding or removing VMs from mesos cluster based on various conditions like utilization going above/below a static threshold. There can be more sophisticated strategies based on prediction or fine grained metric collection with tight integration with mesos framework.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Cluster Simulator:</emphasis></para>
<para>Integrating with existing simulator to simulate mesos clusters. This can be useful in various scenarios, for example while developing a new scheduling algorithm, testing autoscaling etc.</para>
</listitem>
</orderedlist>
</section>
</chapter>

235
docs/en-US/gsoc-meng.xml Normal file
View File

@ -0,0 +1,235 @@
<?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-meng">
<title>Meng's 2013 GSoC Proposal</title>
<para>This chapter describes Meng's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal.</para>
<section id="Project-Description">
<title>Project Description</title>
<para>
Getting a hadoop cluster going can be challenging and painful due to the tedious configuration phase and the diverse idiosyncrasies of each cloud provider. Apache Whirr<ulink url="http://whirr.apache.org/ "><citetitle>[1]</citetitle></ulink> and Provisionr is a set of libraries for running cloud services in an automatic or semi-automatic fashion. They take advantage of a cloud-neutral library called jclouds<ulink url=" http://www.jclouds.org/documentation/gettingstarted/what-is-jclouds/"><citetitle>[2]</citetitle></ulink> to create one-click, auto-configuring hadoop clusters on multiple clouds. Since jclouds supports CloudStack API, most of the services provided by Whirr and Provisionr should work out of the box on CloudStack. My first task is to test that assumption, make sure everything is well documented, and correct all issues with the latest version of CloudStack (4.0 and 4.1).
</para>
<para>
The biggest challenge for hadoop provisioning is automatically configuring each instance at launch time based on what it is supposed to do, a process known as contextualization<ulink url="http://dl.acm.org/citation.cfm?id=1488934"><citetitle>[3]</citetitle></ulink><ulink url="http://www.nimbusproject.org/docs/current/clouds/clusters2.html "><citetitle>[4]</citetitle></ulink>. It causes last minute changes inside an instance to adapt to a cluster environment. Many automated cloud services are enabled by contextualization. For example in one-click hadoop clusters, contextualization basically amounts to generating and distributing ssh key pairs among instances, telling an instance where the master node is and what other slave nodes it should be aware of, etc. On EC2 contextualization is done via passing information through the EC2_USER_DATA entry<ulink url="http://aws.amazon.com/amazon-linux-ami/ "><citetitle>[5]</citetitle></ulink><ulink url="https://svn.apache.org/repos/asf/whirr/branches/contrib-python/src/py/hadoop/cloud/data/hadoop-ec2-init-remote.sh"><citetitle>[6]</citetitle></ulink>. Whirr and Provisionr embrace this feature to provision hadoop instances on EC2. My second task is to test and extend Whirr and Provisionrs one-click solution on EC2 to CloudStack and also improve CloudStacks support for Whirr and Provisionr to enable hadoop provisioning on CloudStack based clouds.
</para>
<para>
My third task is to add a Query API that is compatible with Amazon Elastic MapReduce (EMR) to CloudStack. Through this API, all hadoop provisioning functionality will be exposed and users can reuse cloud clients that are written for EMR to create and manage hadoop clusters on CloudStack based clouds.
</para>
</section>
<section id="Project-Details">
<title>Project Details</title>
<para>
Whirr defines four roles for the hadoop provisioning service: Namenode, JobTracker, Datanode and TaskTraker. With the help of CloudInit<ulink url="https://help.ubuntu.com/community/CloudInit "><citetitle>[7]</citetitle></ulink> (a popular package for cloud instance initialization), each VM instance is configured based on its role and a compressed file that is passed in the EC2_USER_DATA entry. Since CloudStack also supports EC2_USER_DATA, I think the most feasible way to have hadoop provisioning on CloudStack is to extend Whirrs solution on EC2 to CloudStack platform and to make necessary adjustment based on CloudStacks
</para>
<para>
Whirr and Provisionr deal with two critical issues in their role configuration scripts (configure-hadoop-role_list): SSH key authentication and hostname configuration.
</para>
<orderedlist>
<listitem><para>
SSH Key Authentication. The need for SSH Key based authentication is required so that the master node can login to slave nodes to start/stop hadoop daemons. Also each node needs to login to itself to start its own hadoop daemons. Traditionally this is done by generating a key pair on the master node and distributing the public key to all slave nodes. This can be only done with human intervention. Whirr works around this problem on EC2 by having a common key pair for all nodes in a hadoop cluster. Thus every node is able to login to one another. The key pair is provided by users and obtained by CloudInit inside an instance from metadata service. As far as I know, Cloudstack does not support user-provided ssh key authentication. Although CloudStack has the createSSHKeyPair API<ulink url="http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.0.2/html/Installation_Guide/using-sshkeys.html "><citetitle>[8]</citetitle></ulink> to generate SSH keys and users can create an instance template that supports SSH keys, there is no easy way to have a unified SSH key on all cluster instances. Besides Whirr prefers minimal image management, so having a customized template doesnt seem quite fit here.
</para></listitem>
<listitem><para>
Hostname configuration. The hostname of each instance has to be properly set and injected into the set of hadoop config files (core-site.xml, hdfs-site.xml, mapred-site.xml ). For an EC2 instance, its host name is converted from a combination of its public IP and an EC2-specific pre/suffix (e.g. an instance with IP 54.224.206.71 will have its hostname set to ec2-54-224-206-71.compute-1.amazonaws.com). This hostname amounts to the Fully Qualified Domain Name that uniquely identifies this node on the network. As for the case of CloudStack, if users do not specify a name the hostname that identifies a VM on a network will be a unique UUID generated by CloudStack<ulink url="https://cwiki.apache.org/CLOUDSTACK/allow-user-provided-hostname-internal-vm-name-on-hypervisor-instead-of-cloud-platform-auto-generated-name-for-guest-vms.html"><citetitle>[9]</citetitle></ulink>.
</para></listitem>
</orderedlist>
<para>
These two are the main issues that need support improvement on the CloudStack side. Other things like preparing disks, installing hadoop tarballs and starting hadoop daemons can be easily done as they are relatively role/instance-independent and static. Runurl can be used to simplify user-data scripts.
</para>
<para>
After we achieve hadoop provisioning on CloudStack using Whirr we can go further to add a Query API to CloudStack to expose this functionality. I will write an API that is compatible with Amazon Elastic MapReduce Service (EMR)<ulink url="http://docs.aws.amazon.com/ElasticMapReduce/latest/API/Welcome.html "><citetitle>[10]</citetitle></ulink> so that users can reuse clients that are written for EMR to submit jobs to existing hadoop clusters, poll job status, terminate a hadoop instance and do other things on CloudStack based clouds. There are eight actions<ulink url="http://docs.aws.amazon.com/ElasticMapReduce/latest/API/API_Operations.html "><citetitle>[11]</citetitle></ulink> now supported in EMR API. I will try to implement as many as I can during the period of GSoC. The following statements give some examples of the API that I will write.
</para>
<programlisting><![CDATA[
https://elasticmapreduce.cloudstack.com?Action=RunJobFlow &Name=MyJobFlowName &Instances.MasterInstanceType=m1.small &Instances.SlaveInstanceType=m1.small &Instances.InstanceCount=4
]]></programlisting>
<para>
This will launch a new hadoop cluster with four instances using specified instance types and add a job flow to it.
</para>
<programlisting><![CDATA[
https://elasticmapreduce.cloudstack.com?Action=AddJobFlowSteps &JobFlowId=j-3UN6WX5RRO2AG &Steps.member.1.Name=MyStep2 &Steps.member.1.HadoopJarStep.Jar=MyJar
]]></programlisting>
<para>
This will add a step to the existing job flow with ID j-3UN6WX5RRO2AG. This step will run the specified jar file.
</para>
<programlisting><![CDATA[
https://elasticmapreduce.cloudstack.com?Action=DescribeJobFlows &JobFlowIds.member.1=j-3UN6WX5RRO2AG
]]></programlisting>
<para>
This will return the status of the given job flow.
</para>
</section>
<section id="Roadmap">
<title>Roadmap</title>
<para><emphasis role="bold">Jun. 17 Jun. 30</emphasis> </para>
<orderedlist>
<listitem><para>
Learn CloudStack and Apache Whirr/Provisionr APIs; Deploy a CloudStack cluster.
</para></listitem>
<listitem><para>
Identify how EC2_USER_DATA is passed and executed on each CloudStack instance.
</para></listitem>
<listitem><para>
Figure out how the files passed in EC2_USER_DATA are acted upon by CloudInit.
</para></listitem>
<listitem><para>
Identify files in /etc/init/ that are used or modified by Whirr and Provisionr for hadoop related configuration.
</para></listitem>
<listitem><para>
Deploy a hadoop cluster on CloudStack via Whirr/Provisionr. This is to test what are missing in CloudStack or Whirr/Provisionr in terms of their support for each other.
</para></listitem>
</orderedlist>
<para><emphasis role="bold">Jul. 1 Aug. 1</emphasis> </para>
<orderedlist>
<listitem><para>
Write scripts to configure VM hostname on CloudStack with the help of CloudInit;
</para></listitem>
<listitem><para>
Write scripts to distribute SSH keys among CloudStack instances. Add the capability of using user-provided ssh key for authentication to CloudStack.
</para></listitem>
<listitem><para>
Take care of the other things left for hadoop provisioning, such as mounting disks, installing hadoop tarballs, etc.
</para></listitem>
<listitem><para>
Compose files that need to be passed in EC2_USER_DATA to each CloudStack instance . Test these files and write patches to make sure that Whirr/Provisionr can succefully deploy one-click hadoop clusters on CloudStack.
</para></listitem>
</orderedlist>
<para><emphasis role="bold">Aug. 3 Sep. 8</emphasis> </para>
<orderedlist>
<listitem><para>
Design and build an Elastic Mapreduce API for CloudStack that takes control of hadoop cluster creation and management.
</para></listitem>
<listitem><para>
Implement the eight actions defined in EMR API. This task might take a while.
</para></listitem>
</orderedlist>
<para><emphasis role="bold">Sep. 10 Sep. 23</emphasis> </para>
<orderedlist>
<listitem><para>
Code cleaning and documentation wrap up.
</para></listitem>
</orderedlist>
</section>
<section id="Deliverables-meng">
<title>Deliverables</title>
<orderedlist>
<listitem><para>
Whirr has limited support for CloudStack. Check whats missing and make sure all steps are properly documented on the Whirr and CloudStack websites.
</para></listitem>
<listitem><para>
Contribute code to CloudStack and and send patches to Whirr/Provisionr if necessary to enable hadoop provisioning on CloudStack via Whirr/Provisionr.
</para></listitem>
<listitem><para>
Build an EMR-compatible API for CloudStack.
</para></listitem>
</orderedlist>
</section>
<section id="Nice-to-have">
<title>Nice to have</title>
<para>In addition to the required deliverables, its nice to have the following:</para>
<orderedlist>
<listitem><para>
The capability to add and remove hadoop nodes dynamically to enable elastic hadoop clusters on CloudStack.
</para></listitem>
<listitem><para>
A review of the existing tools that offer one-click provisioning and make sure that they support CloudStack based clouds.
</para></listitem>
</orderedlist>
</section>
<section id="References">
<title>References</title>
<orderedlist>
<listitem><para>
http://whirr.apache.org/
</para></listitem>
<listitem><para>
http://www.jclouds.org/documentation/gettingstarted/what-is-jclouds/
</para></listitem>
<listitem><para>
Katarzyna Keahey, Tim Freeman, Contextualization: Providing One-Click Virtual Clusters
</para></listitem>
<listitem><para>
http://www.nimbusproject.org/docs/current/clouds/clusters2.html
</para></listitem>
<listitem><para>
http://aws.amazon.com/amazon-linux-ami/
</para></listitem>
<listitem><para>
https://svn.apache.org/repos/asf/whirr/branches/contrib-python/src/py/hadoop/cloud/data/hadoop-ec2-init-remote.sh
</para></listitem>
<listitem><para>
https://help.ubuntu.com/community/CloudInit
</para></listitem>
<listitem><para>
http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.0.2/html/Installation_Guide/using-sshkeys.html
</para></listitem>
<listitem><para>
https://cwiki.apache.org/CLOUDSTACK/allow-user-provided-hostname-internal-vm-name-on-hypervisor-instead-of-cloud-platform-auto-generated-name-for-guest-vms.html
</para></listitem>
<listitem><para>
http://docs.aws.amazon.com/ElasticMapReduce/latest/API/Welcome.html
</para></listitem>
<listitem><para>
http://docs.aws.amazon.com/ElasticMapReduce/latest/API/API_Operations.html
</para></listitem>
<listitem><para>
http://buildacloud.org/blog/235-puppet-and-cloudstack.html
</para></listitem>
<listitem><para>
http://chriskleban-internet.blogspot.com/2012/03/build-cloud-cloudstack-instance.html
</para></listitem>
<listitem><para>
http://gehrcke.de/2009/06/aws-about-api/
</para></listitem>
<listitem><para>
Apache_CloudStack-4.0.0-incubating-API_Developers_Guide-en-US.pdf
</para></listitem>
</orderedlist>
</section>
</chapter>

View File

@ -21,18 +21,69 @@
-->
<section id="pvlan">
<title>Isolation in Advanced Zone Using Private VLAN</title>
<para/>
<para>Isolation of guest traffic in shared networks can be achieved by using Private VLANs
(PVLAN). PVLANs provide Layer 2 isolation between ports within the same VLAN. In a PVLAN-enabled
shared network, a user VM cannot reach other user VM though they can reach the DHCP server and
gateway, this would in turn allow users to control traffic within a network and help them deploy
multiple applications without communication between application as well as prevent communication
with other users VMs.</para>
<itemizedlist>
<listitem>
<para>Isolate VMs in a shared networks by using Private VLANs.</para>
</listitem>
<listitem>
<para>Supported in both VPC and non-VPC deployments.</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>
</listitem>
</itemizedlist>
<section id="about-pvlan">
<title>About Private VLAN</title>
<para>In an Ethernet switch, a VLAN is a broadcast domain in which hosts can establish direct
<para>In an Ethernet switch, a VLAN is a broadcast domain where hosts can establish direct
communication with each another at Layer 2. Private VLAN is designed as an extension of VLAN
standard to add further segmentation of the logical broadcast domain. A regular VLAN is a
single broadcast domain, whereas a private VLAN partitions a larger VLAN broadcast domain into
smaller sub-domains. A sub-domain is represented by a pair of VLANs: a Primary VLAN and a
Secondary VLAN. The original VLAN that is being divided into smaller groups is called
Primary, That implies all VLAN pairs in a private VLAN share the same Primary VLAN. All the
Secondary VLAN. The original VLAN that is being divided into smaller groups is called Primary,
which implies that all VLAN pairs in a private VLAN share the same Primary VLAN. All the
secondary VLANs exist only inside the Primary. Each Secondary VLAN has a specific VLAN ID
associated to it, which differentiates one sub-domain from another.</para>
associated to it, which differentiates one sub-domain from another. </para>
<para>Three types of ports exist in a private VLAN domain, which essentially determine the
behaviour of the participating hosts. Each ports will have its own unique set of rules, which
regulate a connected host's ability to communicate with other connected host within the same
private VLAN domain. Configure each host that is part of a PVLAN pair can be by using one of
these three port designation:</para>
<itemizedlist>
<listitem>
<para><emphasis role="bold">Promiscuous</emphasis>: A promiscuous port can communicate with
all the interfaces, including the community and isolated host ports that belong to the
secondary VLANs. In Promiscuous mode, hosts are connected to promiscuous ports and are
able to communicate directly with resources on both primary and secondary VLAN. Routers,
DHCP servers, and other trusted devices are typically attached to promiscuous
ports.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Isolated VLANs</emphasis>: The ports within an isolated VLAN
cannot communicate with each other at the layer-2 level. The hosts that are connected to
Isolated ports can directly communicate only with the Promiscuous resources. If your
customer device needs to have access only to a gateway router, attach it to an isolated
port.</para>
</listitem>
<listitem>
<para><emphasis role="bold">Community VLANs</emphasis>: The ports within a community VLAN
can communicate with each other and with the promiscuous ports, but they cannot
communicate with the ports in other communities at the layer-2 level. In a Community mode,
direct communication is permitted only with the hosts in the same community and those that
are connected to the Primary PVLAN in promiscuous mode. If your customer has two devices
that need to be isolated from other customers' devices, but to be able to communicate
among themselves, deploy them in community ports.</para>
</listitem>
</itemizedlist>
<para>For further reading:</para>
<itemizedlist>
<listitem>
@ -52,6 +103,61 @@
</section>
<section id="prereq-pvlan">
<title>Prerequisites</title>
<para>Ensure that you configure private VLAN on your physical switches out-of-band.</para>
<itemizedlist>
<listitem>
<para>Use a PVLAN supported switch.</para>
<para>See <ulink
url="http://www.cisco.com/en/US/products/hw/switches/ps708/products_tech_note09186a0080094830.shtml"
>Private VLAN Catalyst Switch Support Matrix</ulink>for more information.</para>
</listitem>
<listitem>
<para>Connect a switch to the gateway; connect additional switches to the gateway via a
trunk port: Only Cisco Catalyst 4500 has the PVLAN promiscuous trunk mode to connect both
normal VLAN and PVLAN to a PVLAN-unaware switch. For other Catalyst PVLAN support 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>All the layer 2 switches, which are PVLAN-aware, are connected to each other, and one
of them is connected to a router. All the ports connected to the host would be configured
in trunk mode. Allow Management VLAN, Primary VLAN (public) and secondary Isolated VLAN
ports. Configure the switch port connected to the router in PVLAN promiscuous trunk mode,
which would translate an isolated VLAN to primary VLAN for router, which is PVLAN-unaware.
</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 one 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 upper switch to access mode, and allow only the traffic of
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>
</itemizedlist>
</section>
<section id="ability-pvlan">
<title/>
<para/>
</section>
</section>

View File

@ -155,6 +155,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
address.setAssociatedWithNetworkId(null);
address.setVpcId(null);
address.setSystem(false);
address.setVmIp(null);
update(ipAddressId, address);
}

View File

@ -43,5 +43,5 @@ public interface PortForwardingRulesDao extends GenericDao<PortForwardingRuleVO,
List<PortForwardingRuleVO> listByAccount(long accountId);
List<PortForwardingRuleVO> listByDestIpAddr(String ip4Address);
PortForwardingRuleVO findByIdAndIp(long id, String secondaryIp);
}

View File

@ -158,5 +158,12 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
sc.setParameters("dstIp", ip4Address);
return listBy(sc);
}
@Override
public PortForwardingRuleVO findByIdAndIp(long id, String secondaryIp) {
SearchCriteria<PortForwardingRuleVO> sc = AllFieldsSearch.create();
sc.setParameters("id", id);
sc.setParameters("dstIp", secondaryIp);
return findOneBy(sc);
}
}

View File

@ -38,6 +38,7 @@ public interface UsageDao extends GenericDao<UsageVO, Long> {
Long getLastUserStatsId();
List<Long> listPublicTemplatesByAccount(long accountId);
Long getLastVmDiskStatsId();
void updateVmDiskStats(List<VmDiskStatisticsVO> vmNetStats);
void saveVmDiskStats(List<VmDiskStatisticsVO> vmNetStats);
void updateVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats);
void saveVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats);
void saveUsageRecords(List<UsageVO> usageRecords);
}

View File

@ -18,6 +18,7 @@ package com.cloud.usage.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
@ -63,6 +64,8 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
" VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)";
private static final String UPDATE_VM_DISK_STATS = "UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, " +
"net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=? WHERE id=?";
private static final String INSERT_USGAE_RECORDS = "INSERT INTO cloud_usage.cloud_usage (zone_id, account_id, domain_id, description, usage_display, usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, " +
"usage_id, type, size, network_id, start_date, end_date) VALUES (?,?,?,?,?,?,?,?,?, ?, ?, ?,?,?,?,?,?)";
protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
@ -375,4 +378,65 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
}
}
@Override
public void saveUsageRecords(List<UsageVO> usageRecords) {
Transaction txn = Transaction.currentTxn();
try {
txn.start();
String sql = INSERT_USGAE_RECORDS;
PreparedStatement pstmt = null;
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
for (UsageVO usageRecord : usageRecords) {
pstmt.setLong(1, usageRecord.getZoneId());
pstmt.setLong(2, usageRecord.getAccountId());
pstmt.setLong(3, usageRecord.getDomainId());
pstmt.setString(4, usageRecord.getDescription());
pstmt.setString(5, usageRecord.getUsageDisplay());
pstmt.setInt(6, usageRecord.getUsageType());
pstmt.setDouble(7, usageRecord.getRawUsage());
if(usageRecord.getVmInstanceId() != null){
pstmt.setLong(8, usageRecord.getVmInstanceId());
} else {
pstmt.setNull(8, Types.BIGINT);
}
pstmt.setString(9, usageRecord.getVmName());
if(usageRecord.getOfferingId() != null){
pstmt.setLong(10, usageRecord.getOfferingId());
} else {
pstmt.setNull(10, Types.BIGINT);
}
if(usageRecord.getTemplateId() != null){
pstmt.setLong(11, usageRecord.getTemplateId());
} else {
pstmt.setNull(11, Types.BIGINT);
}
if(usageRecord.getUsageId() != null){
pstmt.setLong(12, usageRecord.getUsageId());
} else {
pstmt.setNull(12, Types.BIGINT);
}
pstmt.setString(13, usageRecord.getType());
if(usageRecord.getSize() != null){
pstmt.setLong(14, usageRecord.getSize());
} else {
pstmt.setNull(14, Types.BIGINT);
}
if(usageRecord.getNetworkId() != null){
pstmt.setLong(15, usageRecord.getNetworkId());
} else {
pstmt.setNull(15, Types.BIGINT);
}
pstmt.setTimestamp(16, new Timestamp(usageRecord.getStartDate().getTime()));
pstmt.setTimestamp(17, new Timestamp(usageRecord.getEndDate().getTime()));
pstmt.addBatch();
}
pstmt.executeBatch();
txn.commit();
} catch (Exception ex) {
txn.rollback();
s_logger.error("error saving usage records to cloud_usage db", ex);
throw new CloudRuntimeException(ex.getMessage());
}
}
}

View File

@ -428,51 +428,52 @@ public class VolumeServiceImpl implements VolumeService {
public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(
VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
try {
DataObject volumeOnStore = store.create(volume);
volume.processEvent(Event.CreateOnlyRequested);
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null,
(VolumeObject)volume, store, volumeOnStore, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null))
.setContext(context);
this.motionSrv.copyAsync(snapshot, volumeOnStore, caller);
DataObject volumeOnStore = store.create(volume);
volume = this.volFactory.getVolume(volume.getId(), store);
volume.processEvent(Event.CreateOnlyRequested);
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null,
(VolumeObject)volume, store, volumeOnStore, future);
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null))
.setContext(context);
this.motionSrv.copyAsync(snapshot, volumeOnStore, caller);
} catch (Exception e) {
s_logger.debug("create volume from snapshot failed", e);
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
future.complete(result);
s_logger.debug("create volume from snapshot failed", e);
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
future.complete(result);
}
return future;
}
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
CopyCommandResult result = callback.getResult();
VolumeInfo volume = context.vo;
VolumeApiResult apiResult = new VolumeApiResult(volume);
Event event = null;
if (result.isFailed()) {
apiResult.setResult(result.getResult());
event = Event.OperationFailed;
} else {
event = Event.OperationSuccessed;
}
try {
volume.processEvent(event);
} catch (Exception e) {
s_logger.debug("create volume from snapshot failed", e);
apiResult.setResult(e.toString());
}
AsyncCallFuture<VolumeApiResult> future = context.future;
future.complete(apiResult);
return null;
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
CopyCommandResult result = callback.getResult();
VolumeInfo volume = context.vo;
VolumeApiResult apiResult = new VolumeApiResult(volume);
Event event = null;
if (result.isFailed()) {
apiResult.setResult(result.getResult());
event = Event.OperationFailed;
} else {
event = Event.OperationSuccessed;
}
try {
volume.processEvent(event);
} catch (Exception e) {
s_logger.debug("create volume from snapshot failed", e);
apiResult.setResult(e.toString());
}
AsyncCallFuture<VolumeApiResult> future = context.future;
future.complete(apiResult);
return null;
}
protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) {
Long lastPoolId = volume.getPoolId();
VolumeVO newVol = new VolumeVO(volume);

View File

@ -811,7 +811,53 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return new SetFirewallRulesAnswer(cmd, true, results);
}
protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource SetVPCStaticNatRulesCommand: " + _gson.toJson(cmd));
}
String[] results = new String[cmd.getRules().length];
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
String controlIp = getRouterSshControlIp(cmd);
int i = 0;
boolean endResult = true;
for (StaticNatRuleTO rule : cmd.getRules()) {
// Prepare command to be send to VPC VR
String args = "";
args += rule.revoked() ? " -D" : " -A";
args += " -l " + rule.getSrcIp();
args += " -r " + rule.getDstIp();
// Invoke command on VPC VR.
try {
Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticnat.sh " + args);
if (s_logger.isDebugEnabled())
s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticnat.sh " + args);
if (!result.first()) {
s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args);
results[i++] = "Failed";
endResult = false;
} else {
results[i++] = null;
}
} catch (Throwable e) {
s_logger.error("SetVPCStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e);
results[i++] = "Failed";
endResult = false;
}
}
return new SetStaticNatRulesAnswer(cmd, results, endResult);
}
protected Answer execute(SetStaticNatRulesCommand cmd) {
if (cmd.getVpcId() != null) {
return SetVPCStaticNatRules(cmd);
}
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd));
}
@ -1262,7 +1308,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
args += rule.revoked() ? " -D" : " -A";
args += " -P " + rule.getProtocol().toLowerCase();
args += " -l " + rule.getSrcIp();
args += " -p " + rule.getStringSrcPortRange().replace(":", "-");
args += " -p " + rule.getStringSrcPortRange();
args += " -r " + rule.getDstIp();
args += " -d " + rule.getStringDstPortRange().replace(":", "-");

View File

@ -3404,8 +3404,8 @@ public class ApiResponseHelper implements ResponseGenerator {
//Device Type
usageRecResponse.setType(usageRecord.getType());
//VM Instance Id
VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
usageRecResponse.setUsageId(vm.getUuid());
VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
usageRecResponse.setVirtualMachineId(vm.getUuid());
//Volume ID
VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
usageRecResponse.setUsageId(volume.getUuid());

View File

@ -2401,9 +2401,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
@Override
public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName,
String affinityGroupType, Long vmId, Long startIndex, Long pageSize) {
String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive,
boolean listAll, Long startIndex, Long pageSize) {
Pair<List<AffinityGroupJoinVO>, Integer> result = listAffinityGroupsInternal(affinityGroupId,
affinityGroupName, affinityGroupType, vmId, startIndex, pageSize);
affinityGroupName, affinityGroupType, vmId, accountName, domainId, isRecursive, listAll, startIndex, pageSize);
ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();
List<AffinityGroupResponse> agResponses = ViewResponseHelper.createAffinityGroupResponses(result.first());
response.setResponses(agResponses, result.second());
@ -2412,12 +2413,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
public Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsInternal(Long affinityGroupId,
String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize) {
String affinityGroupName, String affinityGroupType, Long vmId, String accountName, Long domainId,
boolean isRecursive, boolean listAll, Long startIndex, Long pageSize) {
Account caller = UserContext.current().getCaller();
Long accountId = caller.getAccountId();
Long domainId = caller.getDomainId();
if (vmId != null) {
UserVmVO userVM = _userVmDao.findById(vmId);
@ -2429,20 +2430,25 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
}
List<Long> permittedAccounts = new ArrayList<Long>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, null, permittedAccounts,
domainIdRecursiveListProject, listAll, true);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize);
SearchBuilder<AffinityGroupJoinVO> groupSearch = _affinityGroupJoinDao.createSearchBuilder();
_accountMgr.buildACLViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select
// distinct
SearchCriteria<AffinityGroupJoinVO> sc = groupSearch.create();
if (accountId != null) {
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
}
if (domainId != null) {
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
}
_accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
if (affinityGroupId != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
@ -2457,8 +2463,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc,
searchFilter);
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
// search group details by ids
Integer count = uniqueGroupsPair.second();
if (count.intValue() == 0) {

View File

@ -945,6 +945,13 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId);
HostVO secondaryStorageHost = this.templateMgr.getSecondaryStorageHost(dataCenterId);
boolean templateReady = false;
if (secondaryStorageHost == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
}
return false;
}
if (template != null && secondaryStorageHost != null) {
VMTemplateHostVO templateHostRef = _vmTemplateHostDao.findByHostTemplate(secondaryStorageHost.getId(), template.getId());

View File

@ -770,7 +770,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
@Override
public Nic getNicInNetwork(long vmId, long networkId) {
return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
return _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
}
@Override
@ -1761,7 +1761,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
return true;
}
Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
@Override
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
}

View File

@ -789,10 +789,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
//check PF or static NAT is configured on this ip address
String secondaryIp = secIpVO.getIp4Address();
List<PortForwardingRuleVO> pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp);
if (pfRuleList.size() != 0) {
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
List<FirewallRuleVO> fwRulesList = _firewallDao.listByNetworkAndPurpose(network.getId(), Purpose.PortForwarding);
if (fwRulesList.size() != 0) {
for (FirewallRuleVO rule: fwRulesList) {
if (_portForwardingDao.findByIdAndIp(rule.getId(), secondaryIp) != null) {
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
}
}
}
//check if the secondary ip associated with any static nat rule
IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp);
@ -2116,6 +2121,21 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
// In some scenarios even though guesVmCidr and network CIDR do not appear similar but
// the IP ranges exactly matches, in these special cases make sure no Reservation gets applied
if (network.getNetworkCidr() == null) {
if (NetUtils.isSameIpRange(guestVmCidr, network.getCidr()) && !guestVmCidr.equals(network.getCidr())) {
throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: "+ guestVmCidr + " and CIDR: " + network.getCidr() + " are same, " +
"even though both the cidrs appear to be different. As a precaution no IP Reservation will be applied.");
}
} else {
if(NetUtils.isSameIpRange(guestVmCidr, network.getNetworkCidr()) && !guestVmCidr.equals(network.getNetworkCidr())) {
throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: "+ guestVmCidr + " and Network CIDR: " + network.getNetworkCidr() + " are same, " +
"even though both the cidrs appear to be different. As a precaution IP Reservation will not be affected. If you want to reset IP Reservation, " +
"specify guestVmCidr to be: " + network.getNetworkCidr());
}
}
// When reservation is applied for the first time, network_cidr will be null
// Populate it with the actual network cidr
if (network.getNetworkCidr() == null) {
@ -2665,9 +2685,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
vnetString = vnetString+vnetRange.first().toString()+"-"+value.toString()+";";
}
}
vnetString = vnetString+"*";
vnetString = vnetString.replace(";*","");
network.setVnet(vnetString);
if (vnetString.length() > 0 && vnetString.charAt(vnetString.length()-1)==';') {
vnetString = vnetString.substring(0, vnetString.length()-1);
}
network.setVnet(vnetString);
}
for (Pair<Integer, Integer> vnetToAdd : vnetsToAdd) {
@ -2773,12 +2794,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
_datacneter_vnet.deleteRange(txn, network.getDataCenterId(), network.getId(), start, end);
String vnetString="";
for (Pair<Integer,Integer> vnetRange : existingRanges ){
vnetString=vnetString+vnetRange.first().toString()+"-"+vnetRange.second().toString()+";";
if (existingRanges.isEmpty()) {
network.setVnet(null);
} else {
for (Pair<Integer,Integer> vnetRange : existingRanges ) {
vnetString=vnetString+vnetRange.first().toString()+"-"+vnetRange.second().toString()+";";
}
vnetString = vnetString.substring(0, vnetString.length()-1);
network.setVnet(vnetString);
}
vnetString = vnetString+"*";
vnetString = vnetString.replace(";*","");
network.setVnet(vnetString);
_physicalNetworkDao.update(network.getId(), network);
txn.commit();
_physicalNetworkDao.releaseFromLockTable(network.getId());

View File

@ -1371,7 +1371,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
// create new static nat rule
// Get nic IP4 address
Nic guestNic = _networkModel.getNicInNetwork(vm.getId(), networkId);
Nic guestNic = _networkModel.getNicInNetworkIncludingRemoved(vm.getId(), networkId);
if (guestNic == null) {
throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
}

View File

@ -2208,6 +2208,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
domainIdRecursiveListProject.second(true);
}
}
} else if (domainId != null) {
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
permittedAccounts.add(caller.getId());
}
}
}

View File

@ -874,4 +874,9 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
// TODO Auto-generated method stub
return null;
}
@Override
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
return null;
}
}

View File

@ -887,4 +887,9 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
return null;
}
@Override
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
return null;
}
}

View File

@ -385,7 +385,6 @@ class TestRemoveUserFromAccount(cloudstackTestCase):
)
return
@unittest.skip("Open Questions")
@attr(tags=["advanced", "basic", "eip", "advancedns", "sg"])
def test_02_remove_all_users(self):
"""Test Remove both users from the account
@ -712,7 +711,6 @@ class TestServiceOfferingSiblings(cloudstackTestCase):
return
@unittest.skip("Open Questions")
class TestServiceOfferingHierarchy(cloudstackTestCase):
@classmethod
@ -841,7 +839,6 @@ class TestServiceOfferingHierarchy(cloudstackTestCase):
return
@unittest.skip("Open Questions")
class TesttemplateHierarchy(cloudstackTestCase):
@classmethod
@ -1441,7 +1438,6 @@ class TestUserDetails(cloudstackTestCase):
)
return
@unittest.skip("Login API response returns nothing")
class TestUserLogin(cloudstackTestCase):
@classmethod

View File

@ -730,6 +730,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
networkids=self.shared_network_sg.id,
serviceofferingid=self.service_offering.id
)
self.cleanup_vms.append(self.shared_network_admin_account_virtual_machine)
vms = VirtualMachine.list(
self.api_client,
id=self.shared_network_admin_account_virtual_machine.id,

View File

@ -1966,7 +1966,6 @@ class TestStartStopVMWithEgressRule(cloudstackTestCase):
return
@unittest.skip("Valid bug- ID: CS-12647")
class TestInvalidParametersForEgress(cloudstackTestCase):
def setUp(self):

View File

@ -182,7 +182,6 @@ class TestEIP(cloudstackTestCase):
@attr(tags = ["eip"])
@unittest.skip("skipped - Framework DB Exception")
def test_01_eip_by_deploying_instance(self):
"""Test EIP by deploying an instance
"""
@ -350,7 +349,6 @@ class TestEIP(cloudstackTestCase):
return
@attr(tags = ["eip"])
@unittest.skip("skipped - Framework DB Exception")
def test_02_acquire_ip_enable_static_nat(self):
"""Test associate new IP and enable static NAT for new IP and the VM
"""
@ -495,7 +493,6 @@ class TestEIP(cloudstackTestCase):
return
@attr(tags = ["eip"])
@unittest.skip("skipped - Framework DB Exception")
def test_03_disable_static_nat(self):
"""Test disable static NAT and release EIP acquired
"""
@ -695,7 +692,6 @@ class TestEIP(cloudstackTestCase):
return
@attr(tags = ["eip"])
@unittest.skip("skipped - Framework DB Exception")
def test_04_disable_static_nat_system(self):
"""Test disable static NAT with system = True
"""
@ -765,7 +761,6 @@ class TestEIP(cloudstackTestCase):
return
@attr(tags = ["eip"])
@unittest.skip("skipped - Framework DB Exception")
def test_05_destroy_instance(self):
"""Test EIO after destroying instance
"""
@ -1406,7 +1401,6 @@ class TestELB(cloudstackTestCase):
return
@attr(tags = ["eip"])
@unittest.skip("valid bug : http://bugs.cloudstack.org/browse/CS-15077 : ListPublicIPAddress failing")
def test_04_delete_lb_on_eip(self):
"""Test delete LB rule generated on EIP
"""

View File

@ -2132,7 +2132,6 @@ class TestLoadBalancingRule(cloudstackTestCase):
return
@unittest.skip("Questions - How to verify after changing public/private ports?")
class TestDeleteCreateLBRule(cloudstackTestCase):
@classmethod

View File

@ -1816,7 +1816,6 @@ class TestNetworkUpgrade(cloudstackTestCase):
return
@unittest.skip("Skipped since shared network requires StartIp/endIp/gateway/netmask")
class TestSharedNetworkWithoutIp(cloudstackTestCase):
@classmethod

View File

@ -343,7 +343,6 @@ class TestProjectCreationNegative(cloudstackTestCase):
@attr(configuration = "allow.user.create.projects")
@attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"])
@unittest.skip("Known bug-able to create project as a domain user")
def test_user_project_creation(self):
"""Test create project as a domain admin and domain user
"""
@ -1299,7 +1298,6 @@ class TestProjectInviteTimeout(cloudstackTestCase):
)
return
@unittest.skip("Requires SMPT configs")
def test_09_invite_to_project_by_email(self):
"""Test invite user to project by email"""

View File

@ -328,7 +328,6 @@ class TestProjectLimits(cloudstackTestCase):
return
@attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"])
@unittest.skip("No provision for updating resource limits from account through API")
def test_02_project_limits_normal_user(self):
""" Test project limits
"""

View File

@ -559,7 +559,6 @@ class TestDeleteAccountWithProject(cloudstackTestCase):
return
@unittest.skip("Deleting domain doesn't cleanup account")
class TestDeleteDomainWithProject(cloudstackTestCase):
@classmethod

View File

@ -690,7 +690,6 @@ class TestResourceTags(cloudstackTestCase):
return
@attr(tags=["advanced"])
@unittest.skip("Not supported in 3.0.5")
def test_04_vpn_tag(self):
""" Test Create tag on vpn and remove the vpn
"""
@ -1421,7 +1420,6 @@ class TestResourceTags(cloudstackTestCase):
return
@attr(tags=["basic", "sg"])
@unittest.skip("skip")
def test_11_migrate_tagged_vm_del(self):
""" Test migration of a tagged vm and delete the tag
"""

View File

@ -99,7 +99,6 @@ class Services:
}
@unittest.skip("Open questions")
class TestCreateTemplate(cloudstackTestCase):
def setUp(self):

View File

@ -69,7 +69,6 @@ class Services:
# CentOS 5.3 (64-bit)
}
@unittest.skip("Additional test")
class TestVMPasswordEnabled(cloudstackTestCase):
@classmethod

View File

@ -2474,7 +2474,6 @@ class TestVPC(cloudstackTestCase):
"Updation of VPC display text failed.")
@unittest.skip("Skip")
class TestVPCHostMaintenance(cloudstackTestCase):
@classmethod

View File

@ -35,139 +35,144 @@ class 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,
},
"network_offering": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
"servicecapabilitylist": {
},
},
"network_off_netscaler": {
"name": 'Network offering-netscaler',
"displaytext": 'Network offering-netscaler',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Vpn": 'VpcVirtualRouter',
"Lb": 'Netscaler',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
},
},
"network_off_shared": {
"name": 'Shared Network offering',
"displaytext": 'Shared Network offering',
"guestiptype": 'Shared',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"specifyIpRanges": True,
"specifyVlan": True
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"network": {
"name": "Test Network",
"displaytext": "Test Network",
"netmask": '255.255.255.0'
},
"lbrule": {
"name": "SSH",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"openfirewall": False,
"startport": 22,
"endport": 2222,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"fw_rule": {
"startport": 1,
"endport": 6000,
"cidr": '0.0.0.0/0',
# Any network (For creating FW rule)
"protocol": "TCP"
},
"http_rule": {
"startport": 80,
"endport": 80,
"cidrlist": '0.0.0.0/0',
"protocol": "ICMP"
},
"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,
"mode": 'advanced'
}
"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,
},
"network_offering": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "peraccount"},
"Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"}
},
},
"network_off_netscaler": {
"name": 'Network offering-netscaler',
"displaytext": 'Network offering-netscaler',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Vpn": 'VpcVirtualRouter',
"Lb": 'Netscaler',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "peraccount"},
"Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"}
},
},
"network_off_shared": {
"name": 'Shared Network offering',
"displaytext": 'Shared Network offering',
"guestiptype": 'Shared',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"specifyIpRanges": True,
"specifyVlan": True
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"network": {
"name": "Test Network",
"displaytext": "Test Network",
"netmask": '255.255.255.0'
},
"lbrule": {
"name": "SSH",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"openfirewall": False,
"startport": 22,
"endport": 2222,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"fw_rule": {
"startport": 1,
"endport": 6000,
"cidr": '0.0.0.0/0',
# Any network (For creating FW rule)
"protocol": "TCP"
},
"http_rule": {
"startport": 80,
"endport": 80,
"cidrlist": '0.0.0.0/0',
"protocol": "ICMP"
},
"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 TestVPCNetwork(cloudstackTestCase):
@ -459,7 +464,6 @@ class TestVPCNetwork(cloudstackTestCase):
)
return
@unittest.skip("Skip - Requires netscaler setup")
@attr(tags=["netscaler", "intervlan"])
def test_03_create_network_netscaler(self):
""" Test create network using netscaler for LB
@ -707,7 +711,6 @@ class TestVPCNetwork(cloudstackTestCase):
return
@attr(tags=["advanced", "intervlan"])
@unittest.skip("Skipping - able to create network with RvR")
def test_06_create_network_with_rvr(self):
""" Test create network with eredundant router capability
"""
@ -1038,7 +1041,6 @@ class TestVPCNetwork(cloudstackTestCase):
"Network creation failed as VPC support nw with conserve mode OFF")
return
@unittest.skip("tested")
class TestVPCNetworkRanges(cloudstackTestCase):
@classmethod
@ -1670,7 +1672,6 @@ class TestVPCNetworkUpgrade(cloudstackTestCase):
return
@attr(tags=["advanced", "intervlan"])
@unittest.skip("Error while NW upgrade - Failed to implement network (with specified id) elements and resources as a part of network update")
def test_01_network_services_upgrade(self):
""" Test update Network that is part of a VPC to a network offering
that has more services.

View File

@ -44,138 +44,139 @@ from marvin.integration.lib.common import (get_domain,
class Services:
"""Test VPC network services - Port Forwarding Rules Test Data Class.
"""
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",
},
"host1":None,
"host2":None,
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 1000,
"memory": 512,
},
"network_offering": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
"servicecapabilitylist": {
},
},
"network_offering_no_lb": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"network": {
"name": "Test Network",
"displaytext": "Test Network",
"netmask": '255.255.255.0'
},
"lbrule": {
"name": "SSH",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"openfirewall": False,
"startport": 22,
"endport": 2222,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"lbrule_http": {
"name": "HTTP",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 80,
"publicport": 8888,
"openfirewall": False,
"startport": 80,
"endport": 8888,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"http_rule": {
"privateport": 80,
"publicport": 80,
"startport": 80,
"endport": 80,
"cidrlist": '0.0.0.0/0',
"protocol": "TCP"
},
"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)',
"sleep": 60,
"timeout": 10,
"mode": 'advanced'
}
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "test",
# Random characters are appended for unique
# username
"password": "password",
},
"host1": None,
"host2": None,
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 1000,
"memory": 512,
},
"network_offering": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
"servicecapabilitylist": {
},
},
"network_offering_no_lb": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter'
},
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"network": {
"name": "Test Network",
"displaytext": "Test Network",
"netmask": '255.255.255.0'
},
"lbrule": {
"name": "SSH",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"openfirewall": False,
"startport": 22,
"endport": 2222,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"lbrule_http": {
"name": "HTTP",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 80,
"publicport": 8888,
"openfirewall": False,
"startport": 80,
"endport": 8888,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"http_rule": {
"privateport": 80,
"publicport": 80,
"startport": 80,
"endport": 80,
"cidrlist": '0.0.0.0/0',
"protocol": "TCP"
},
"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)',
"sleep": 60,
"timeout": 10,
"mode": 'advanced'
}
class TestVPCNetworkPFRules(cloudstackTestCase):
@ -251,15 +252,12 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
try:
#Clean up, terminate the created network offerings
cleanup_resources(self.apiclient, self._cleanup)
wait_for_cleanup(self.apiclient, [
"network.gc.interval",
"network.gc.wait"])
except Exception as e:
self.debug("Warning: Exception during cleanup : %s" % e)
#raise Exception("Warning: Exception during cleanup : %s" % e)
return
def get_Router_For_VPC(self):
def get_vpcrouter(self):
routers = list_routers(self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
@ -276,8 +274,8 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
return router
def stop_VPC_VRouter(self):
router = self.get_Router_For_VPC()
def stop_vpcrouter(self):
router = self.get_vpcrouter()
self.debug("Stopping router ID: %s" % router.id)
cmd = stopRouter.stopRouterCmd()
cmd.id = router.id
@ -298,7 +296,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
)
return router
def start_VPC_VRouter(self, router):
def start_vpcrouter(self, router):
# Start the VPC Router
cmd = startRouter.startRouterCmd()
cmd.id = router.id
@ -348,7 +346,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
else:
self.debug("Failed to wget from VM=%s http server on public_ip=%s" % (vm.name, public_ip.ipaddress.ipaddress))
def create_StaticNatRule_For_VM(self, vm, public_ip, network):
def create_staticnat(self, vm, public_ip, network):
self.debug("Enabling static NAT for IP: %s" %
public_ip.ipaddress.ipaddress)
try:
@ -364,7 +362,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
self.fail("Failed to enable static NAT on IP: %s - %s" % (
public_ip.ipaddress.ipaddress, e))
def create_NatRule_For_VM(self, vm, public_ip, network, services=None):
def create_natrule(self, vm, public_ip, network, services=None):
self.debug("Creatinng NAT rule in network for vm with public IP")
if not services:
services = self.services["natrule"]
@ -386,7 +384,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
self.debug('nwacl_nat=%s' % nwacl_nat.__dict__)
return nat_rule
def acquire_Public_IP(self, network):
def acquire_publicip(self, network):
self.debug("Associating public IP for network: %s" % network.name)
public_ip = PublicIPAddress.create(self.apiclient,
accountid=self.account.name,
@ -400,7 +398,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
))
return public_ip
def create_VPC(self, cidr='10.1.2.1/16'):
def create_vpc(self, cidr='10.1.2.1/16'):
self.debug("Creating a VPC offering..")
self.services["vpc_offering"]["name"] = self.services["vpc_offering"]["name"] + str(cidr)
vpc_off = VpcOffering.create(
@ -424,7 +422,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
)
return vpc
def create_Network(self, net_offerring, gateway='10.1.1.1',vpc=None):
def create_network(self, net_offerring, gateway='10.1.1.1',vpc=None):
try:
self.debug('Create NetworkOffering')
net_offerring["name"] = "NET_OFF-" + str(gateway)
@ -453,7 +451,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
except:
self.fail('Unable to create a Network with offering=%s' % net_offerring)
def create_VM_in_Network(self, network, host_id=None):
def deployvm_in_network(self, network, host_id=None):
try:
self.debug('Creating VM in network=%s' % network.name)
vm = VirtualMachine.create(
@ -471,7 +469,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
except:
self.fail('Unable to create VM in a Network=%s' % network.name)
def create_LB_Rule(self, public_ip, network, vmarray, services=None):
def create_lbrule(self, public_ip, network, vmarray, services=None):
self.debug("Creating LB rule for IP address: %s" %
public_ip.ipaddress.ipaddress)
objservices = None
@ -493,7 +491,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
lb_rule.assign(self.apiclient, vmarray)
return lb_rule
def create_egress_Internet_Rule(self, network):
def open_egress_to_world(self, network):
self.debug("Adding Egress rules to network %s and %s to allow access to internet" % (network.name,self.services["http_rule"]))
nwacl_internet_1 = NetworkACL.create(
self.apiclient,
@ -507,8 +505,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
@attr(tags=["advanced", "intervlan"])
def test_01_network_services_VPC_StopCreatePF(self):
""" Test case no 204 : Create PF rules for a single virtual network of a VPC,
using a new Public IP Address available with the VPC when Virtual Router is in Stopped State
""" Test : Create VPC PF rules on acquired public ip when VpcVirtualRouter is stopped
"""
# Validate the following
@ -521,20 +518,19 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 7. Start VPC Virtual Router.
# 8. Successfully ssh into the Guest VM using the PF rule
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
router = self.stop_VPC_VRouter()
self.create_NatRule_For_VM( vm_1, public_ip_1, network_1)
self.start_VPC_VRouter(router)
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
router = self.stop_vpcrouter()
self.create_natrule( vm_1, public_ip_1, network_1)
self.start_vpcrouter(router)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
return
@attr(tags=["advanced", "intervlan"])
def test_02_network_services_VPC_CreatePF(self):
""" Test case no 190 : Create PF rules for a single virtual network of a VPC using a
new Public IP Address available with the VPC when Virtual Router is in Running State
""" Test Create VPC PF rules on acquired public ip when VpcVirtualRouter is Running
"""
# Validate the following
@ -545,17 +541,16 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 5. Use the Create PF rule for vm in network1.
# 6. Successfully ssh into the Guest VM using the PF rule
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
self.create_NatRule_For_VM( vm_1, public_ip_1, network_1)
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
self.create_natrule( vm_1, public_ip_1, network_1)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
return
@attr(tags=["advanced", "intervlan"])
def test_03_network_services_VPC_StopCreateMultiplePF(self):
""" Test case no 205 : Create PF rules for a two/multiple virtual networks of a VPC using
a new Public IP Address available with the VPC when Virtual Router is in Stopped State
""" Test Create multiple VPC PF rules on acquired public ip in diff't networks when VpcVirtualRouter is stopped
"""
# Validate the following
@ -571,24 +566,23 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 10. Start VPC Virtual Router.
# 11. Successfully ssh into the Guest VM1 and VM2 using the PF rule
network_1 = self.create_Network(self.services["network_offering_no_lb"])
network_2 = self.create_Network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.create_VM_in_Network(network_1)
vm_2 = self.create_VM_in_Network(network_2)
public_ip_1 = self.acquire_Public_IP(network_1)
public_ip_2 = self.acquire_Public_IP(network_2)
router = self.stop_VPC_VRouter()
self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
self.create_NatRule_For_VM(vm_2, public_ip_2, network_2)
self.start_VPC_VRouter(router)
network_1 = self.create_network(self.services["network_offering_no_lb"])
network_2 = self.create_network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.deployvm_in_network(network_1)
vm_2 = self.deployvm_in_network(network_2)
public_ip_1 = self.acquire_publicip(network_1)
public_ip_2 = self.acquire_publicip(network_2)
router = self.stop_vpcrouter()
self.create_natrule(vm_1, public_ip_1, network_1)
self.create_natrule(vm_2, public_ip_2, network_2)
self.start_vpcrouter(router)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False)
return
@attr(tags=["advanced", "intervlan"])
def test_04_network_services_VPC_CreateMultiplePF(self):
""" Test case no 191 : Create PF rules for a two/multiple virtual networks of a VPC using a
new Public IP Address available with the VPC when Virtual Router is in Running State
""" Test Create multiple VPC PF rules on acquired public ip in diff't networks when VpcVirtualRouter is running
"""
# Validate the following
@ -603,24 +597,23 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 9. Start VPC Virtual Router.
# 10. Successfully ssh into the Guest VM1 and VM2 using the PF rule
network_1 = self.create_Network(self.services["network_offering"])
network_2 = self.create_Network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.create_VM_in_Network(network_1)
vm_2 = self.create_VM_in_Network(network_2)
public_ip_1 = self.acquire_Public_IP(network_1)
public_ip_2 = self.acquire_Public_IP(network_2)
router = self.stop_VPC_VRouter()
self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
self.create_NatRule_For_VM(vm_2, public_ip_2, network_2)
self.start_VPC_VRouter(router)
network_1 = self.create_network(self.services["network_offering"])
network_2 = self.create_network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.deployvm_in_network(network_1)
vm_2 = self.deployvm_in_network(network_2)
public_ip_1 = self.acquire_publicip(network_1)
public_ip_2 = self.acquire_publicip(network_2)
router = self.stop_vpcrouter()
self.create_natrule(vm_1, public_ip_1, network_1)
self.create_natrule(vm_2, public_ip_2, network_2)
self.start_vpcrouter(router)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False)
return
@attr(tags=["advanced", "intervlan"])
def test_05_network_services_VPC_StopDeletePF(self):
""" Test case no 207 : Delete few(not all) PF rules for a single virtual network of
a VPC belonging to a single Public IP Address when Virtual Router is in Stopped State
""" Test delete a PF rule in VPC when VpcVirtualRouter is Stopped
"""
# Validate the following
@ -636,24 +629,23 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 10. Start VPC Virtual Router.
# 11. wget a file present on http server of VM1 should fail
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
http_rule = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1, self.services["http_rule"])
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
self.create_natrule(vm_1, public_ip_1, network_1)
http_rule = self.create_natrule(vm_1, public_ip_1, network_1, self.services["http_rule"])
#http_rule = self.create_egress_Internet_Rule(network_1)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False)
router = self.stop_VPC_VRouter()
router = self.stop_vpcrouter()
http_rule.delete()
self.start_VPC_VRouter(router)
self.start_vpcrouter(router)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True)
return
@attr(tags=["advanced", "intervlan"])
def test_06_network_services_VPC_DeletePF(self):
""" Test case no 193 : Delete few(not all) PF rules for a single virtual network of
a VPC belonging to a single Public IP Address when Virtual Router is in Running State
""" Test delete a PF rule in VPC when VpcVirtualRouter is Running
"""
# Validate the following
@ -667,11 +659,11 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 9. Delete internet PF rule
# 10. wget a file present on http server of VM1 should fail
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
http_rule=self.create_NatRule_For_VM(vm_1, public_ip_1, network_1, self.services["http_rule"])
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
self.create_natrule(vm_1, public_ip_1, network_1)
http_rule=self.create_natrule(vm_1, public_ip_1, network_1, self.services["http_rule"])
#http_rule = self.create_egress_Internet_Rule(network_1)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False)
@ -681,8 +673,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
@attr(tags=["advanced", "intervlan"])
def test_07_network_services_VPC_StopDeleteAllPF(self):
""" Test case no 208 : Delete all PF rules for a single virtual network of a
VPC belonging to a single Public IP Address when Virtual Router is in Stopped State
""" Test delete all PF rules in VPC when VpcVirtualRouter is Stopped
"""
# Validate the following
@ -699,26 +690,25 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 11. wget a file present on http server of VM1 should fail
# 12. ssh into Guest VM using the PF rule should fail
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
nat_rule = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
http_rule = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1, self.services["http_rule"])
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
nat_rule = self.create_natrule(vm_1, public_ip_1, network_1)
http_rule = self.create_natrule(vm_1, public_ip_1, network_1, self.services["http_rule"])
#http_rule = self.create_egress_Internet_Rule(network_1)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False)
router = self.stop_VPC_VRouter()
router = self.stop_vpcrouter()
http_rule.delete()
nat_rule.delete()
self.start_VPC_VRouter(router)
self.start_vpcrouter(router)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=True)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=True)
return
@attr(tags=["advanced", "intervlan"])
def test_08_network_services_VPC_DeleteAllPF(self):
""" Test case no 194 : Delete all PF rules for a single virtual network of a
VPC belonging to a single Public IP Address when Virtual Router is in Running State
""" Test delete all PF rules in VPC when VpcVirtualRouter is Running
"""
# Validate the following
@ -733,11 +723,11 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 9. wget a file present on http server of VM1 should fail
# 10. ssh into Guest VM using the PF rule should fail
network_1 = self.create_Network(self.services["network_offering"])
vm_1 = self.create_VM_in_Network(network_1)
public_ip_1 = self.acquire_Public_IP(network_1)
nat_rule = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
http_rule = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1, self.services["http_rule"])
network_1 = self.create_network(self.services["network_offering"])
vm_1 = self.deployvm_in_network(network_1)
public_ip_1 = self.acquire_publicip(network_1)
nat_rule = self.create_natrule(vm_1, public_ip_1, network_1)
http_rule = self.create_natrule(vm_1, public_ip_1, network_1, self.services["http_rule"])
#http_rule = self.create_egress_Internet_Rule(network_1)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_wget_from_vm(vm_1, public_ip_1, testnegative=False)
@ -749,8 +739,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
@attr(tags=["advanced", "intervlan"])
def test_09_network_services_VPC_StopDeleteAllMultiplePF(self):
""" Test case no 209 : Delete all PF rules for two/multiple virtual networks of a VPC.
Observe the status of the Public IP Addresses of the rules when Virtual Router is in Stopped State
""" Test delete all PF rules in VPC across multiple networks when VpcVirtualRouter is Stopped
"""
# Validate the following
@ -769,20 +758,20 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 12. Start VPC Virtual Router.
# 13. Fail to ssh and http to vm1, vm2, vm3 and vm4.
network_1 = self.create_Network(self.services["network_offering"])
network_2 = self.create_Network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.create_VM_in_Network(network_1)
vm_2 = self.create_VM_in_Network(network_1)
vm_3 = self.create_VM_in_Network(network_2)
vm_4 = self.create_VM_in_Network(network_2)
public_ip_1 = self.acquire_Public_IP(network_1)
public_ip_2 = self.acquire_Public_IP(network_1)
nat_rule1 = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
nat_rule2 = self.create_NatRule_For_VM(vm_2, public_ip_2, network_1)
http_rule1 = self.create_egress_Internet_Rule(network_1)
nat_rule3 = self.create_NatRule_For_VM(vm_3, public_ip_1, network_2)
nat_rule4 = self.create_NatRule_For_VM(vm_4, public_ip_2, network_2)
http_rule2 = self.create_egress_Internet_Rule(network_2)
network_1 = self.create_network(self.services["network_offering"])
network_2 = self.create_network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.deployvm_in_network(network_1)
vm_2 = self.deployvm_in_network(network_1)
vm_3 = self.deployvm_in_network(network_2)
vm_4 = self.deployvm_in_network(network_2)
public_ip_1 = self.acquire_publicip(network_1)
public_ip_2 = self.acquire_publicip(network_1)
nat_rule1 = self.create_natrule(vm_1, public_ip_1, network_1)
nat_rule2 = self.create_natrule(vm_2, public_ip_2, network_1)
http_rule1 = self.open_egress_to_world(network_1)
nat_rule3 = self.create_natrule(vm_3, public_ip_1, network_2)
nat_rule4 = self.create_natrule(vm_4, public_ip_2, network_2)
http_rule2 = self.open_egress_to_world(network_2)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False)
self.check_ssh_into_vm(vm_3, public_ip_1, testnegative=False)
@ -791,14 +780,14 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
self.check_wget_from_vm(vm_2, public_ip_2, testnegative=False)
self.check_wget_from_vm(vm_3, public_ip_1, testnegative=False)
self.check_wget_from_vm(vm_4, public_ip_2, testnegative=False)
router = self.stop_VPC_VRouter()
router = self.stop_vpcrouter()
nat_rule1.delete()
nat_rule2.delete()
nat_rule3.delete()
nat_rule4.delete()
http_rule1.delete()
http_rule2.delete()
self.start_VPC_VRouter(router)
self.start_vpcrouter(router)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=True)
self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=True)
self.check_ssh_into_vm(vm_3, public_ip_1, testnegative=True)
@ -811,10 +800,8 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
@attr(tags=["advanced", "intervlan"])
def test_10_network_services_VPC_DeleteAllMultiplePF(self):
""" Test case no 195: Delete all PF rules for two/multiple virtual networks of a VPC.
Observe the status of the Public IP Addresses of the rules when Virtual Router is in Running State
""" Test delete all PF rules in VPC across multiple networks when VpcVirtualRouter is Running
"""
# Validate the following
# 1. Create a VPC with cidr - 10.1.1.1/16.
# 2. Create a Network offering - NO1 with all supported services.
@ -829,20 +816,20 @@ class TestVPCNetworkPFRules(cloudstackTestCase):
# 12. Delete all PF rultes for vm1, vm2, vm3 and vm4.
# 13. Fail to ssh and http to vm1, vm2, vm3 and vm4.
network_1 = self.create_Network(self.services["network_offering"])
network_2 = self.create_Network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.create_VM_in_Network(network_1)
vm_2 = self.create_VM_in_Network(network_1)
vm_3 = self.create_VM_in_Network(network_2)
vm_4 = self.create_VM_in_Network(network_2)
public_ip_1 = self.acquire_Public_IP(network_1)
public_ip_2 = self.acquire_Public_IP(network_1)
nat_rule1 = self.create_NatRule_For_VM(vm_1, public_ip_1, network_1)
nat_rule2 = self.create_NatRule_For_VM(vm_2, public_ip_2, network_1)
http_rule1 = self.create_egress_Internet_Rule(network_1)
nat_rule3 = self.create_NatRule_For_VM(vm_3, public_ip_1, network_2)
nat_rule4 = self.create_NatRule_For_VM(vm_4, public_ip_2, network_2)
http_rule2 = self.create_egress_Internet_Rule(network_2)
network_1 = self.create_network(self.services["network_offering"])
network_2 = self.create_network(self.services["network_offering_no_lb"], '10.1.2.1')
vm_1 = self.deployvm_in_network(network_1)
vm_2 = self.deployvm_in_network(network_1)
vm_3 = self.deployvm_in_network(network_2)
vm_4 = self.deployvm_in_network(network_2)
public_ip_1 = self.acquire_publicip(network_1)
public_ip_2 = self.acquire_publicip(network_1)
nat_rule1 = self.create_natrule(vm_1, public_ip_1, network_1)
nat_rule2 = self.create_natrule(vm_2, public_ip_2, network_1)
http_rule1 = self.open_egress_to_world(network_1)
nat_rule3 = self.create_natrule(vm_3, public_ip_1, network_2)
nat_rule4 = self.create_natrule(vm_4, public_ip_2, network_2)
http_rule2 = self.open_egress_to_world(network_2)
self.check_ssh_into_vm(vm_1, public_ip_1, testnegative=False)
self.check_ssh_into_vm(vm_2, public_ip_2, testnegative=False)
self.check_ssh_into_vm(vm_3, public_ip_1, testnegative=False)

View File

@ -278,7 +278,6 @@ class TestVPCOffering(cloudstackTestCase):
return
@attr(tags=["advanced", "intervlan"])
@unittest.skip("Skipping - Issue: Deleting account doesn't clean VPC")
def test_02_deploy_vms_in_vpc_nw(self):
"""Test deploy virtual machines in VPC networks"""
@ -897,7 +896,6 @@ class TestVPCOffering(cloudstackTestCase):
return
@attr(tags=["advanced", "intervlan"])
@unittest.skip("Skipping - API should not allow to create VPC offering without SourceNAT, Firewall")
def test_06_vpc_off_invalid_services(self):
"""Test VPC offering with invalid services"""

View File

@ -509,7 +509,6 @@ class TestVPCRoutersBasic(cloudstackTestCase):
)
return
@unittest.skip("Needs hosts")
@attr(tags=["advanced", "intervlan"])
def test_04_migrate_router_after_creating_vpc(self):
""" Test migration of router to another host after creating VPC """
@ -531,7 +530,6 @@ class TestVPCRoutersBasic(cloudstackTestCase):
self.migrate_router(routers[0])
return
@unittest.skip("Fails")
@attr(tags=["advanced", "intervlan"])
def test_05_change_service_offerring_vpc(self):
""" Tests to change service offering of the Router after
@ -1236,7 +1234,6 @@ class TestVPCRouterOneNetwork(cloudstackTestCase):
)
return
@unittest.skip("Untested - hosts not available")
@attr(tags=["advanced", "intervlan"])
def test_04_migrate_router_after_addition_of_one_guest_network(self):
""" Test migrate of router after addition of one guest network
@ -1280,7 +1277,6 @@ class TestVPCRouterOneNetwork(cloudstackTestCase):
self.migrate_router(routers[0])
return
@unittest.skip("Fails")
@attr(tags=["advanced", "intervlan"])
def test_05_chg_srv_off_router_after_addition_of_one_guest_network(self):
""" Test to change service offering of router after addition of one guest network

File diff suppressed because it is too large Load Diff

View File

@ -1721,7 +1721,6 @@ class TestVMDeployVPC(cloudstackTestCase):
return
@attr(tags=["advanced", "intervlan"])
@unittest.skip("Not tested")
def test_07_delete_network_with_rules(self):
""" Test delete network that has PF/staticNat/LB rules/Network Acl
"""

View File

@ -1209,7 +1209,7 @@ class TestRebootRouter(cloudstackTestCase):
except Exception as e:
self.fail(
"SSH Access failed for %s: %s" % \
(self.vm_1.ipaddress, e))
(self.nat_rule.ipaddress.ipaddress, e))
return
def tearDown(self):

View File

@ -107,7 +107,6 @@ class TestRouterServices(cloudstackTestCase):
serviceofferingid=cls.service_offering.id
)
cls.cleanup = [
cls.vm_1,
cls.account,
cls.service_offering
]

View File

@ -92,7 +92,7 @@ class Services:
"displaytext": "Small Instance",
"cpunumber": 1,
"cpuspeed": 100,
"memory": 256,
"memory": 128,
},
"medium":
{
@ -433,7 +433,7 @@ class TestServiceOfferings(cloudstackTestCase):
)
self.assertAlmostEqual(
int(total_mem) / 1024, # In MBs
self.small_offering.memory,
int(self.small_offering.memory),
"Check Memory(kb) for small offering"
)
return

View File

@ -687,10 +687,12 @@ class TestVMLifeCycle(cloudstackTestCase):
else:
break
self.debug("listVirtualMachines response: %s" % list_vm_response)
self.assertEqual(
list_vm_response,
None,
"Check Expunged virtual machine is listVirtualMachines"
"Check Expunged virtual machine is in listVirtualMachines response"
)
return
@ -730,6 +732,15 @@ class TestVMLifeCycle(cloudstackTestCase):
cmd.virtualmachineid = self.virtual_machine.id
self.apiclient.attachIso(cmd)
#determine device type from hypervisor
hosts = Host.list(self.apiclient, id=self.virtual_machine.hostid)
self.assertTrue(isinstance(hosts, list))
self.assertTrue(len(hosts) > 0)
self.debug("Found %s host" % hosts[0].hypervisor)
if hosts[0].hypervisor.lower() == "kvm":
self.services["diskdevice"] = "/dev/vda"
try:
ssh_client = self.virtual_machine.get_ssh_client()
except Exception as e:

View File

@ -21,6 +21,12 @@ ROOTPW=password
HOSTNAME=systemvm
CLOUDSTACK_RELEASE=4.2.0
add_backports () {
sed -i '/backports/d' /etc/apt/sources.list
echo 'deb http://http.us.debian.org/debian wheezy-backports main' >> /etc/apt/sources.list
apt-get update
}
install_packages() {
DEBIAN_FRONTEND=noninteractive
DEBIAN_PRIORITY=critical
@ -81,10 +87,7 @@ install_packages() {
# rm -fr /opt/vmware-tools-distrib
# apt-get -q -y --force-yes purge build-essential
# haproxy. Wheezy doesn't have haproxy, install from backports
#apt-get --no-install-recommends -q -y --force-yes install haproxy
wget http://ftp.us.debian.org/debian/pool/main/h/haproxy/haproxy_1.4.8-1_i386.deb
dpkg -i haproxy_1.4.8-1_i386.deb
apt-get --no-install-recommends -q -y --force-yes install haproxy
}
setup_accounts() {
@ -223,6 +226,8 @@ do_signature() {
begin=$(date +%s)
echo "*************ADDING BACKPORTS********************"
add_backports
echo "*************INSTALLING PACKAGES********************"
install_packages
echo "*************DONE INSTALLING PACKAGES********************"

View File

@ -21,6 +21,13 @@ ROOTPW=password
HOSTNAME=systemvm
CLOUDSTACK_RELEASE=4.2.0
add_backports () {
sed -i '/backports/d' /etc/apt/sources.list
echo 'deb http://http.us.debian.org/debian wheezy-backports main' >> /etc/apt/sources.list
apt-get update
}
install_packages() {
DEBIAN_FRONTEND=noninteractive
DEBIAN_PRIORITY=critical
@ -80,10 +87,8 @@ install_packages() {
# rm -fr /opt/vmware-tools-distrib
# apt-get -q -y --force-yes purge build-essential
# haproxy. Wheezy doesn't have haproxy temporarily, install from backports
#apt-get --no-install-recommends -q -y --force-yes install haproxy
wget http://ftp.us.debian.org/debian/pool/main/h/haproxy/haproxy_1.4.8-1_amd64.deb
dpkg -i haproxy_1.4.8-1_amd64.deb
apt-get --no-install-recommends -q -y --force-yes install haproxy
}
setup_accounts() {
@ -222,6 +227,8 @@ do_signature() {
begin=$(date +%s)
echo "*************ADDING BACKPORTS********************"
add_backports
echo "*************INSTALLING PACKAGES********************"
install_packages
echo "*************DONE INSTALLING PACKAGES********************"

View File

@ -4531,11 +4531,34 @@
networkdomain: {
docID: 'helpVPCDomain',
label: 'label.DNS.domain.for.guest.networks'
}
},
loadbalancer:{ //Support for Netscaler as an external device for load balancing
label:'Load Balancer',
select:function(args){
$.ajax({
url:createURL('listVPCOfferings&listall=true'),
dataType:'json',
success:function(json){
var items=[];
var vpcObj = json.listvpcofferingsresponse.vpcoffering;
$(vpcObj).each(function(){
items.push({id:this.id , description:this.name});
});
args.response.success({data:items});
}
});
}
}
}
},
action: function(args) {
var defaultvpcofferingid;
/* var defaultvpcofferingid;
$.ajax({
url: createURL("listVPCOfferings"),
dataType: "json",
@ -4546,14 +4569,14 @@
success: function(json) {
defaultvpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id;
}
});
});*/
var dataObj = {
name: args.data.name,
displaytext: args.data.displaytext,
zoneid: args.data.zoneid,
cidr: args.data.cidr,
vpcofferingid: defaultvpcofferingid
vpcofferingid: args.data.loadbalancer // Support for external load balancer
};
if(args.data.networkdomain != null && args.data.networkdomain.length > 0)

View File

@ -11425,8 +11425,8 @@
label: 'label.scope',
select: function(args) {
var scope = [
{ id: 'zone', description: _l('label.zone.wide') },
{ id: 'cluster', description: _l('label.cluster') }
{ id: 'cluster', description: _l('label.cluster') },
{ id: 'zone', description: _l('label.zone.wide') }
// { id: 'host', description: _l('label.host') }
];

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.usage.parser;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -89,6 +90,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.
networkUsageByZone.put(key, new NetworkInfo(zoneId, usageNetwork.getHostId(), usageNetwork.getHostType(), usageNetwork.getNetworkId(), bytesSent, bytesReceived));
}
List<UsageVO> usageRecords = new ArrayList<UsageVO>();
for (String key : networkUsageByZone.keySet()) {
NetworkInfo networkInfo = networkUsageByZone.get(key);
long totalBytesSent = networkInfo.getBytesSent();
@ -110,7 +112,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.
}
UsageVO usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesSent + " bytes sent",
UsageTypes.NETWORK_BYTES_SENT, new Double(totalBytesSent), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate);
m_usageDao.persist(usageRecord);
usageRecords.add(usageRecord);
// Create the usage record for bytes received
usageDesc = "network bytes received";
@ -119,7 +121,7 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.
}
usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesReceived + " bytes received",
UsageTypes.NETWORK_BYTES_RECEIVED, new Double(totalBytesReceived), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate);
m_usageDao.persist(usageRecord);
usageRecords.add(usageRecord);
} else {
// Don't charge anything if there were zero bytes processed
if (s_logger.isDebugEnabled()) {
@ -127,6 +129,11 @@ public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.
}
}
}
try {
m_usageDao.saveUsageRecords(usageRecords);
} catch (Exception ex) {
s_logger.error("Exception in usage manager", ex);
}
return true;
}

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.usage.parser;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -93,6 +94,7 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g
vmDiskUsageByZone.put(key, new VmDiskInfo(zoneId, usageVmDisk.getVmId(), usageVmDisk.getVolumeId(), ioRead, ioWrite, bytesRead, bytesWrite));
}
List<UsageVO> usageRecords = new ArrayList<UsageVO>();
for (String key : vmDiskUsageByZone.keySet()) {
VmDiskInfo vmDiskInfo = vmDiskUsageByZone.get(key);
long ioRead = vmDiskInfo.getIORead();
@ -107,44 +109,45 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g
}
Long vmId = null;
Long volumeId = null;
// Create the usage record for bytes read
String usageDesc = "disk bytes read";
if(vmDiskInfo.getVmId() != 0){
if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){
vmId = vmDiskInfo.getVmId();
usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId();
volumeId = vmDiskInfo.getVolumeId();
usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId;
}
UsageVO usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, ioRead + " io read",
UsageTypes.VM_DISK_IO_READ, new Double(ioRead), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate);
m_usageDao.persist(usageRecord);
UsageTypes.VM_DISK_IO_READ, new Double(ioRead), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine");
usageRecords.add(usageRecord);
// Create the usage record for bytes write
usageDesc = "disk bytes write";
if(vmDiskInfo.getVmId() != 0){
usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId();
if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){
usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId;
}
usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, ioWrite + " io write",
UsageTypes.VM_DISK_BYTES_WRITE, new Double(ioWrite), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate);
m_usageDao.persist(usageRecord);
UsageTypes.VM_DISK_BYTES_WRITE, new Double(ioWrite), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine");
usageRecords.add(usageRecord);
// Create the usage record for bytes read
usageDesc = "disk bytes read";
if(vmDiskInfo.getVmId() != 0){
vmId = vmDiskInfo.getVmId();
usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId();
if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){
usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId;
}
usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, bytesRead + " bytes read",
UsageTypes.VM_DISK_BYTES_READ, new Double(bytesRead), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate);
m_usageDao.persist(usageRecord);
UsageTypes.VM_DISK_BYTES_READ, new Double(bytesRead), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine");
usageRecords.add(usageRecord);
// Create the usage record for bytes write
usageDesc = "disk bytes write";
if(vmDiskInfo.getVmId() != 0){
usageDesc += " for Vm: "+vmDiskInfo.getVmId()+" and Volume: "+ vmDiskInfo.getVolumeId();
if ((vmDiskInfo.getVmId() != 0) && (vmDiskInfo.getVolumeId() != 0)){
usageDesc += " for Vm: " + vmId + " and Volume: " + volumeId;
}
usageRecord = new UsageVO(vmDiskInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, bytesWrite + " bytes write",
UsageTypes.VM_DISK_BYTES_WRITE, new Double(bytesWrite), vmId, "VirtualMachine", vmDiskInfo.getVolumeId(), startDate, endDate);
m_usageDao.persist(usageRecord);
UsageTypes.VM_DISK_BYTES_WRITE, new Double(bytesWrite), vmId, null, null, null, vmDiskInfo.getVolumeId(), startDate, endDate, "VirtualMachine");
usageRecords.add(usageRecord);
} else {
// Don't charge anything if there were zero bytes processed
@ -154,6 +157,12 @@ public static final Logger s_logger = Logger.getLogger(VmDiskUsageParser.class.g
}
}
try {
m_usageDao.saveUsageRecords(usageRecords);
} catch (Exception ex) {
s_logger.error("Exception in usage manager", ex);
}
return true;
}

View File

@ -1023,6 +1023,34 @@ public class NetUtils {
return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size);
}
// Check if 2 CIDRs have exactly same IP Range
public static boolean isSameIpRange (String cidrA, String cidrB) {
if(!NetUtils.isValidCIDR(cidrA)) {
s_logger.info("Invalid value of cidr " + cidrA);
return false;
}
if (!NetUtils.isValidCIDR(cidrB)) {
s_logger.info("Invalid value of cidr " + cidrB);
return false;
}
String[] cidrPairFirst = cidrA.split("\\/");
String[] cidrPairSecond = cidrB.split("\\/");
Long networkSizeFirst = Long.valueOf(cidrPairFirst[1]);
Long networkSizeSecond = Long.valueOf(cidrPairSecond[1]);
String ipRangeFirst [] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeFirst);
String ipRangeSecond [] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeSecond);
long startIpFirst = NetUtils.ip2Long(ipRangeFirst[0]);
long endIpFirst = NetUtils.ip2Long(ipRangeFirst[1]);
long startIpSecond = NetUtils.ip2Long(ipRangeSecond[0]);
long endIpSecond = NetUtils.ip2Long(ipRangeSecond[1]);
if(startIpFirst == startIpSecond && endIpFirst == endIpSecond) {
return true;
}
return false;
}
public static boolean validateGuestCidr(String cidr) {
// RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the
// following three blocks of the IP address space for private internets:

View File

@ -136,4 +136,23 @@ public class NetUtilsTest extends TestCase {
assertTrue(NetUtils.getPrimaryPvlanFromUri(uri).equals("123"));
assertTrue(NetUtils.getIsolatedPvlanFromUri(uri).equals("456"));
}
public void testIsSameIpRange() {
//Test to check IP Range of 2 CIDRs
String cidrFirst = "10.0.144.0/20";
String cidrSecond = "10.0.151.0/20";
String cidrThird = "10.0.144.0/21";
assertTrue(NetUtils.isValidCIDR(cidrFirst));
assertTrue(NetUtils.isValidCIDR(cidrSecond));
assertTrue(NetUtils.isValidCIDR(cidrThird));
//Check for exactly same CIDRs
assertTrue(NetUtils.isSameIpRange(cidrFirst, cidrFirst));
//Check for 2 different CIDRs, but same IP Range
assertTrue(NetUtils.isSameIpRange(cidrFirst, cidrSecond));
//Check for 2 different CIDRs and different IP Range
assertFalse(NetUtils.isSameIpRange(cidrFirst, cidrThird));
//Check for Incorrect format of CIDR
assertFalse(NetUtils.isSameIpRange(cidrFirst, "10.3.6.5/50"));
}
}