mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cloudstack into disk_io_throttling
This commit is contained in:
commit
080bb76187
|
|
@ -272,4 +272,6 @@ public interface NetworkModel {
|
|||
Map<Detail, String> getNtwkOffDetails(long offId);
|
||||
|
||||
Networks.IsolationType[] listNetworkIsolationMethods();
|
||||
|
||||
Nic getNicInNetworkIncludingRemoved(long vmId, long networkId);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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 Provisionr’s one-click solution on EC2 to CloudStack and also improve CloudStack’s 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 Whirr’s solution on EC2 to CloudStack platform and to make necessary adjustment based on CloudStack’s
|
||||
</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 doesn’t 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 what’s 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, it’s 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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(":", "-");
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -887,4 +887,9 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1966,7 +1966,6 @@ class TestStartStopVMWithEgressRule(cloudstackTestCase):
|
|||
return
|
||||
|
||||
|
||||
@unittest.skip("Valid bug- ID: CS-12647")
|
||||
class TestInvalidParametersForEgress(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2132,7 +2132,6 @@ class TestLoadBalancingRule(cloudstackTestCase):
|
|||
return
|
||||
|
||||
|
||||
@unittest.skip("Questions - How to verify after changing public/private ports?")
|
||||
class TestDeleteCreateLBRule(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -1816,7 +1816,6 @@ class TestNetworkUpgrade(cloudstackTestCase):
|
|||
return
|
||||
|
||||
|
||||
@unittest.skip("Skipped since shared network requires StartIp/endIp/gateway/netmask")
|
||||
class TestSharedNetworkWithoutIp(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -559,7 +559,6 @@ class TestDeleteAccountWithProject(cloudstackTestCase):
|
|||
return
|
||||
|
||||
|
||||
@unittest.skip("Deleting domain doesn't cleanup account")
|
||||
class TestDeleteDomainWithProject(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -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
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ class Services:
|
|||
}
|
||||
|
||||
|
||||
@unittest.skip("Open questions")
|
||||
class TestCreateTemplate(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ class Services:
|
|||
# CentOS 5.3 (64-bit)
|
||||
}
|
||||
|
||||
@unittest.skip("Additional test")
|
||||
class TestVMPasswordEnabled(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -2474,7 +2474,6 @@ class TestVPC(cloudstackTestCase):
|
|||
"Updation of VPC display text failed.")
|
||||
|
||||
|
||||
@unittest.skip("Skip")
|
||||
class TestVPCHostMaintenance(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ class TestRouterServices(cloudstackTestCase):
|
|||
serviceofferingid=cls.service_offering.id
|
||||
)
|
||||
cls.cleanup = [
|
||||
cls.vm_1,
|
||||
cls.account,
|
||||
cls.service_offering
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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********************"
|
||||
|
|
|
|||
|
|
@ -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********************"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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') }
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue