From 6d140538c5efc394fda8a4ddc7cb72832470d0b3 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Sat, 15 Jun 2013 11:21:46 +0530 Subject: [PATCH 01/95] CLOUDSTACK-3004: remove duplicate ssvm-check.sh ssvm_check.sh remove the duplicate file from consoleproxy and include the script from secondary storage folder while packing iso Signed-off-by: Prasanna Santhanam --- .../server/scripts/ssvm-check.sh | 136 ------------------ .../server/systemvm-descriptor.xml | 9 ++ 2 files changed, 9 insertions(+), 136 deletions(-) delete mode 100644 services/console-proxy/server/scripts/ssvm-check.sh diff --git a/services/console-proxy/server/scripts/ssvm-check.sh b/services/console-proxy/server/scripts/ssvm-check.sh deleted file mode 100644 index a4011647f07..00000000000 --- a/services/console-proxy/server/scripts/ssvm-check.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# Health check script for the Secondary Storage VM - -# DNS server is specified. - - -CMDLINE=/var/cache/cloud/cmdline -for i in `cat $CMDLINE` -do - key=`echo $i | cut -d= -f1` - value=`echo $i | cut -d= -f2` - case $key in - host) - MGMTSERVER=$value - ;; - esac -done - - -# ping dns server -echo ================================================ -DNSSERVER=`egrep '^nameserver' /etc/resolv.conf | awk '{print $2}'| head -1` -echo "First DNS server is " $DNSSERVER -ping -c 2 $DNSSERVER -if [ $? -eq 0 ] -then - echo "Good: Can ping DNS server" -else - echo "WARNING: cannot ping DNS server" - echo "route follows" - route -n -fi - - -# check dns resolve -echo ================================================ -nslookup download.cloud.com 1> /tmp/dns 2>&1 -grep 'no servers could' /tmp/dns 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "ERROR: DNS not resolving download.cloud.com" - echo resolv.conf follows - cat /etc/resolv.conf - exit 2 -else - echo "Good: DNS resolves download.cloud.com" -fi - - -# check to see if we have the NFS volume mounted -echo ================================================ -mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "NFS is currently mounted" - # check for write access - for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'` - do - if [ $MOUNTPT != "/proc/xen" ] # mounted by xen - then - echo Mount point is $MOUNTPT - touch $MOUNTPT/foo - if [ $? -eq 0 ] - then - echo "Good: Can write to mount point" - rm $MOUNTPT/foo - else - echo "ERROR: Cannot write to mount point" - echo "You need to export with norootsquash" - fi - fi - done -else - echo "ERROR: NFS is not currently mounted" - echo "Try manually mounting from inside the VM" - NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'` - echo "NFS server is " $NFSSERVER - ping -c 2 $NFSSERVER - if [ $? -eq 0 ] - then - echo "Good: Can ping NFS server" - else - echo "WARNING: cannot ping NFS server" - echo routing table follows - route -n - fi -fi - - -# check for connectivity to the management server -echo ================================================ -echo Management server is $MGMTSERVER. Checking connectivity. -socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1) -if [ $? -eq 0 ] -then - echo "Good: Can connect to management server port 8250" -else - echo "ERROR: Cannot connect to $MGMTSERVER port 8250" - echo $socatout - exit 4 -fi - - -# check for the java process running -echo ================================================ -ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "Good: Java process is running" -else - echo "ERROR: Java process not running. Try restarting the SSVM." - exit 3 -fi - -echo ================================================ -echo Tests Complete. Look for ERROR or WARNING above. - -exit 0 diff --git a/services/console-proxy/server/systemvm-descriptor.xml b/services/console-proxy/server/systemvm-descriptor.xml index e34026bc3a6..6c98d2d3eb0 100644 --- a/services/console-proxy/server/systemvm-descriptor.xml +++ b/services/console-proxy/server/systemvm-descriptor.xml @@ -36,6 +36,15 @@ 555 555 + + ../../secondary-storage/scripts/ + + 555 + 555 + + ssvm-check.sh + + ../../../scripts/storage/secondary/ scripts/storage/secondary From 2f345c5b4dcac464770f1f7719e07cf73c5f6ea8 Mon Sep 17 00:00:00 2001 From: rayeesn Date: Sat, 15 Jun 2013 15:17:32 -0700 Subject: [PATCH 02/95] test_accounts.TesttemplateHierarchy;ostype added Signed-off-by: Prasanna Santhanam --- test/integration/component/test_accounts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 3f106c3b048..ec135b1de4f 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -84,6 +84,7 @@ class Services: "isfeatured": True, "ispublic": True, "isextractable": True, + "ostype": 'CentOS 5.3 (64-bit)', }, "natrule": { "publicport": 22, From 1a058d77939819ef8a00130064bfb9ca4f108ebe Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Sun, 16 Jun 2013 18:33:34 +0530 Subject: [PATCH 03/95] cloudmonkey: Bump up version of cloudmonkey to 4.2.xx Signed-off-by: Rohit Yadav --- tools/cli/cloudmonkey/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/cloudmonkey/config.py b/tools/cli/cloudmonkey/config.py index aaf97ebd25d..36f7e77ed82 100644 --- a/tools/cli/cloudmonkey/config.py +++ b/tools/cli/cloudmonkey/config.py @@ -18,7 +18,7 @@ # Use following rules for versioning: # - -__version__ = "4.1.0-0" +__version__ = "4.2.0-0" __description__ = "Command Line Interface for Apache CloudStack" __maintainer__ = "Rohit Yadav" __maintaineremail__ = "bhaisaab@apache.org" From 10f9516015121fc0521616d3b6d675ac7561c7d9 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Sun, 16 Jun 2013 18:34:32 +0530 Subject: [PATCH 04/95] cloumonkey: Remove junk from requester.py This fix removes junk from 6e22843acb6bbd61260849fac171bba61ac6650f which was supposed to just improve error messages and not messup the whole async block logic and go into an infinite recursion or fail with some key error. Signed-off-by: Rohit Yadav --- tools/cli/cloudmonkey/requester.py | 47 +++++++----------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/tools/cli/cloudmonkey/requester.py b/tools/cli/cloudmonkey/requester.py index d2dae6dfc3f..b06e1fc99e3 100644 --- a/tools/cli/cloudmonkey/requester.py +++ b/tools/cli/cloudmonkey/requester.py @@ -125,61 +125,36 @@ def monkeyrequest(command, args, isasync, asyncblock, logger, host, port, command = "queryAsyncJobResult" request = {'jobid': jobid} timeout = int(timeout) - pollperiod = 3 + pollperiod = 2 progress = 1 while timeout > 0: print '\r' + '.' * progress, sys.stdout.flush() - progress += 1 + time.sleep(pollperiod) timeout = timeout - pollperiod + progress += 1 logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout)) - sys.stdout.flush() - if re.match("queryAsyncJobResult", command): - time.sleep(pollperiod) - else: - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) + response, error = make_request(command, request, logger, + host, port, apikey, secretkey, + protocol, path) + if error is not None: + return response, error + response = process_json(response) responsekeys = filter(lambda x: 'response' in x, response.keys()) if len(responsekeys) < 1: - time.sleep(pollperiod) continue result = response[responsekeys[0]] jobstatus = result['jobstatus'] - jobresultcode = result['jobresultcode'] - try: - jobresult = result["jobresult"] - logger_debug(logger, "jobresult %s" % (jobresult)) - sys.stdout.flush() - return response, None - except KeyError: - logger_debug(logger, "No jobresult yet %s" % (result)) - sys.stdout.flush() - - if jobresultcode != 0: - error = "Error: resultcode %d for jobid %s" % (jobresultcode, - jobid) - logger_debug(logger, "%s" % (error)) - return response, error - else: - # if we get a valid respons resultcode give back results - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) - logger_debug(logger, "Ok: %s" % (jobid)) - return response, error - if jobstatus == 2: + jobresult = result["jobresult"] error = "\rAsync job %s failed\nError %s, %s" % (jobid, jobresult["errorcode"], jobresult["errortext"]) return response, error elif jobstatus == 1: - print '\r', + print "\r" + " " * progress, return response, error else: logger_debug(logger, "We should not arrive here!") From 2fb18db7b1484fbc7cedf616b2970fe596586db8 Mon Sep 17 00:00:00 2001 From: Isaac Chiang Date: Sun, 16 Jun 2013 23:04:33 +0800 Subject: [PATCH 05/95] CLOUDSTACK-2976: At zone level setting same parameter page is getting displayed repeatedly when you scroll down --- ui/scripts/ui/widgets/listView.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index ba4d2881580..8dbc2f6ffbc 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1327,6 +1327,12 @@ }); $table.dataTable(null, { noSelect: uiCustom }); + if(args.data && + args.data.length < pageSize && + options.setEndTable) { + options.setEndTable(); + } + setTimeout(function() { $table.dataTable('refresh'); }); @@ -1467,6 +1473,12 @@ var page = 1; var actions = listViewData.actions; var reorder = listViewData.reorder; + var tableHeight = $table.height(); + var endTable = false; + var setEndTable = function() { + endTable = true; + } + var $switcher; if (args.sections) { @@ -1572,7 +1584,8 @@ { context: args.context, reorder: reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); @@ -1625,7 +1638,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1675,7 +1689,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1728,8 +1743,6 @@ return false; }); - var tableHeight = $table.height(); - var endTable = false; // Infinite scrolling event $listView.bind('scroll', function(event) { @@ -1767,7 +1780,8 @@ filterBy: filterBy }, actions, { reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable }); $table.height() == tableHeight ? endTable = true : tableHeight = $table.height(); } From bf0265d21d77dbc28bc61f46c535ca75b727d115 Mon Sep 17 00:00:00 2001 From: rayeesn Date: Sat, 15 Jun 2013 10:26:13 -0700 Subject: [PATCH 06/95] CLOUDSTACK-3020: Fix assert error If you do not give a name during vm creation, UUID will be set for Name and Display name will be blank. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_custom_hostname.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_custom_hostname.py b/test/integration/component/test_custom_hostname.py index c9db2154a94..e569215980c 100644 --- a/test/integration/component/test_custom_hostname.py +++ b/test/integration/component/test_custom_hostname.py @@ -300,7 +300,7 @@ class TestInstanceNameFlagTrue(cloudstackTestCase): "Running", "Vm state should be running after deployment" ) - self.assertEqual( + self.assertNotEqual( vm.displayname, vm.id, "Vm display name should not match the given name" From e405703d5c38fd42b4c91533cf50e07190fbe760 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 10:04:26 +0530 Subject: [PATCH 07/95] CLOUDSTACK-3024: Invalid reference to testclient close Testclient does not expose a close() method anymore for closing the connection to cloudstack Signed-off-by: Prasanna Santhanam --- test/integration/component/test_host_high_availability.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/component/test_host_high_availability.py b/test/integration/component/test_host_high_availability.py index 57eb5edede9..2fe07b1771f 100644 --- a/test/integration/component/test_host_high_availability.py +++ b/test/integration/component/test_host_high_availability.py @@ -142,7 +142,6 @@ class TestHostHighAvailability(cloudstackTestCase): try: #Clean up, terminate the created accounts, domains etc cleanup_resources(self.apiclient, self.cleanup) - self.testClient.close() except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return From 776301ce6f124767d42fcd58f9c411a002dc310d Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Wed, 12 Jun 2013 17:31:23 +0100 Subject: [PATCH 08/95] Change listAll to return a boolean and fix a typo Signed-off-by: Abhinandan Prateek --- .../api/command/admin/ldap/LDAPConfigCmd.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java index 2976de4bf28..2726f84163d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java @@ -43,10 +43,9 @@ public class LDAPConfigCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") - private String listall; - + @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.BOOLEAN, description="If true return current LDAP configuration") + private Boolean listAll; + @Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") private String hostname; @@ -78,10 +77,10 @@ public class LDAPConfigCmd extends BaseCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getListAll() { - return listall == null ? "false" : listall; + public Boolean getListAll() { + return listAll == null ? Boolean.FALSE : listAll; } - + public String getBindPassword() { return bindPassword; } @@ -156,16 +155,15 @@ public class LDAPConfigCmd extends BaseCmd { InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { try { - if ("true".equalsIgnoreCase(getListAll())){ + if (getListAll()){ // return the existing conf LDAPConfigCmd cmd = _configService.listLDAPConfig(this); - LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), - cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); + LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); lr.setResponseName(getCommandName()); this.setResponseObject(lr); } else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) { - throw new InvalidParameterValueException("You need to provide hostname, serachbase and queryfilter to configure your LDAP server"); + throw new InvalidParameterValueException("You need to provide hostname, searchbase and queryfilter to configure your LDAP server"); } else { boolean result = _configService.updateLDAP(this); From 2f1ed47213014f2462d7add0bec6a2437e336899 Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Mon, 17 Jun 2013 11:08:59 +0530 Subject: [PATCH 09/95] CLOUDSTACK-769 review comments fixed --- docs/en-US/add-loadbalancer-rule-vpc.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en-US/add-loadbalancer-rule-vpc.xml b/docs/en-US/add-loadbalancer-rule-vpc.xml index b7b9e3e7613..82e870243d1 100644 --- a/docs/en-US/add-loadbalancer-rule-vpc.xml +++ b/docs/en-US/add-loadbalancer-rule-vpc.xml @@ -25,16 +25,16 @@ External LB is nothing but a LB rule created to redirect the traffic received at a public IP of the VPC virtual router. The traffic is load balanced within a tier based on your configuration. Citrix NetScaler and VPC virtual router are supported for external LB. When you use internal LB - service, traffic received at a tier is load balanced across different tiers within the VPC. For - example, traffic reached at Web tier is redirected to Application tier. External load balancing - devices are not supported for internal LB. The service is provided by a internal LB VM + service, traffic received at a tier is load balanced across different VMs within that tier. For + example, traffic reached at Web tier is redirected to another VM in that tier. External load + balancing devices are not supported for internal LB. The service is provided by a internal LB VM configured on the target tier.
Load Balancing Within a Tier (External LB) A &PRODUCT; user or administrator may create load balancing rules that balance traffic received at a public IP to one or more VMs that belong to a network tier that provides load balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the - rule to a set of VMs within a VPC. + rule to a set of VMs within a tier. Log in to the &PRODUCT; UI as an administrator or end user. From fcafe28d7b9231282161e326e9dfa8528054f5fd Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Mon, 17 Jun 2013 11:41:07 +0530 Subject: [PATCH 10/95] CLOUDSTACK-758 --- docs/en-US/create-vpn-connection-vpc.xml | 31 ++++++++++++++++++----- docs/en-US/create-vpn-gateway-for-vpc.xml | 30 +++++++++++++++++----- docs/en-US/delete-reset-vpn.xml | 28 ++++++++++++++++---- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/docs/en-US/create-vpn-connection-vpc.xml b/docs/en-US/create-vpn-connection-vpc.xml index 1fba09e18fb..88a058c9f89 100644 --- a/docs/en-US/create-vpn-connection-vpc.xml +++ b/docs/en-US/create-vpn-connection-vpc.xml @@ -20,6 +20,7 @@ -->
Creating a VPN Connection + &PRODUCT; supports creating up to 8 VPN connections. Log in to the &PRODUCT; UI as an administrator or end user. @@ -38,19 +39,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -100,4 +119,4 @@ -
\ No newline at end of file +
diff --git a/docs/en-US/create-vpn-gateway-for-vpc.xml b/docs/en-US/create-vpn-gateway-for-vpc.xml index 396a7d9d174..0f8a0dcc03b 100644 --- a/docs/en-US/create-vpn-gateway-for-vpc.xml +++ b/docs/en-US/create-vpn-gateway-for-vpc.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ACLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -77,4 +95,4 @@ - \ No newline at end of file + diff --git a/docs/en-US/delete-reset-vpn.xml b/docs/en-US/delete-reset-vpn.xml index 318e5fe321e..2fe85d279b6 100644 --- a/docs/en-US/delete-reset-vpn.xml +++ b/docs/en-US/delete-reset-vpn.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists From ac48e5dc67e6ae93545ab188500070b3ef3da290 Mon Sep 17 00:00:00 2001 From: Shiva Teja Date: Thu, 13 Jun 2013 23:02:12 +0530 Subject: [PATCH 11/95] Add proposal to CloudStack_GSoC_Guide.xml --- docs/en-US/CloudStack_GSoC_Guide.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en-US/CloudStack_GSoC_Guide.xml b/docs/en-US/CloudStack_GSoC_Guide.xml index 1f435931363..cd8205d34ba 100644 --- a/docs/en-US/CloudStack_GSoC_Guide.xml +++ b/docs/en-US/CloudStack_GSoC_Guide.xml @@ -50,5 +50,6 @@ + From a3d585ea4effc3a326858e777a7f785ddf44dfe2 Mon Sep 17 00:00:00 2001 From: Shiva Teja Date: Fri, 14 Jun 2013 00:54:03 +0530 Subject: [PATCH 12/95] Add Shiva Teja's proposal to GSoC docbook --- docs/en-US/gsoc-shiva.xml | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/en-US/gsoc-shiva.xml diff --git a/docs/en-US/gsoc-shiva.xml b/docs/en-US/gsoc-shiva.xml new file mode 100644 index 00000000000..400af3c82f6 --- /dev/null +++ b/docs/en-US/gsoc-shiva.xml @@ -0,0 +1,70 @@ + + +%BOOK_ENTITIES; +]> + + + + + Shiva Teja's 2013 GSoC Proposal + This chapter describes Shiva Teja's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal. +
+ Abstract + + The aim of this project is to create a new modular UI for Apache CloudStack using Bootstrap by Twitter and Backbone.js. To achieve this easily, I'll be creating a RESTful wrapper API on top of the current CloudStack API. I hope this project will make custom UIs for CloudStack very easy. + + Why does CloudStack need a new UI? + + The current UI cannot be reused easliy to make a custom UI. The UI I will be making using backbone.js can be reused very easily to make custom UIs. The models, views, routers etc can remain the same in all the UIs. The user interface can be changed just by changing the templates. Check the implementation details below for further details. + + Why does it need a RESTful wrapper API ? + + Backbone.js heavily depends on RESTful architecture. Making a new UI with backbone.js using a query based API might not be easy. +
+
+ List of deliverables + + A new UI for CloudStack(with almost all features in the current UI and new ones, if any). + A RESTful wrapper API on top of the CloudStack API + Some documentation about using this UI to make a custom UI. + +
+
+ Approach + Wrapper API: Backbone.js, by default, uses four HTTP methods(GET, PUT, POST, DELETE) for communicating with the server. It uses GET to fetch a resource from the server, POST to create a resource, PUT to update the resource and DELETE to delete the resource. A query based API can probably be used to make the UI by overriding backbone's default sync function. But it makes more sense to have an API which supports the above mentioned method and is resource based. This RESTful API works on top of the CloudStack API. The main task is to map the combinations of these HTTP methods and the resources to appropriate CloudStack API command. The other task is to decide on how the URLs should look like. Say for starting a virtual machine, for it to be RESTful, we have to use POST as we are creating a resource, or a PUT as we are changing the state of a virtual machine. So the possible options on the URL could be to do a POST /runningvirtualmachines and respond with 201 Created code or a PUT on /virtualmachines/id and respond with 200 OK. If these are decided, the wrapper can be generated or be written manually, which can use defined patters to map to appropriate CloudStack API commands(Similar to what cloudmonkey does. See this prototype. I can use cloudmonkey's code to generate the required API entity verb relationships. Each verb will have a set of rules saying what method should be used in the RESTful API and how should it look like in the URL. Another possible way could be to group entities first manually and write the wrapper manually(something like zone/pods/cluster). Some possibilities have been discussed in this thread. + + UI: It will be a single page app. It'll use client side templating for rendering. This makes it very easy to make a custom UI because it can be achieved just by changing the templates. Backbone views will make use of these templates to render the appropriate models/collections. A completely new interface can be written just by changing the templates. Javascript code can completely remain the same. The views will take care of appropriate DOM events. Such event will correspond to appropriate model/collection chages, thus causing appropriate API calls. +
+
+ Approximate Schedle + Till June 17 - Decide on how the RESTful API should look like and design algorithms to generate the wrapper. + July 5(soft deadline), July 10(hard deadline) : Wrapper API will be ready. + July 12(soft) - July 15(hard): Make basic wireframes and designs for the website and get them approved. + July 29(mid term evaluation) : All the basic models, views, routes of the UI should be ready along with a few templates. + August 15(hard deadline, shouldn't take much time actually) - A basic usable UI where users can just list all the entities which are present in the current UI's main navigation( Like Instances, Templates, Accounts etc) + September 1(hard) - From this UI, users should be able to launch instances, edit settings of most of the entities. + September 16(Pencil down!) - Fix some design tweaks and finish a completely usable interface with functions similar to current UI. + September 23 - Finish the documentation on how to use this UI to make custom UIs. +
+
+ About Me + I am a 2nd year computer science undergrad studying at IIT Mandi, India. I've been using Python for an year and a half now. I've used Django, Flask and Tornado for my small projects. Along with Python, I use C++ for competitive programming. Recently, I fell in love with Haskell. I've always been fascinated about web technologies. +
+
From 0587d3a496b4c5d29a6b14774f5e7fdc42a5bb33 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 12:32:50 +0530 Subject: [PATCH 13/95] Moving maintenance mode into component/maint All tests that could possible disrupt the runs of other tests because of putting resources into maintenace will be put under maint/. This should allow us to run the tests sequentially when other tests are not running on a deployment. Signed-off-by: Prasanna Santhanam --- test/integration/component/maint/__init__.py | 21 ++ .../{ => maint}/test_high_availability.py | 0 .../test_host_high_availability.py | 10 +- .../{ => maint}/test_vpc_host_maintenance.py | 330 +----------------- .../maint/test_vpc_on_host_maintenance.py | 323 +++++++++++++++++ test/integration/component/test_vpc.py | 252 +------------ 6 files changed, 351 insertions(+), 585 deletions(-) create mode 100644 test/integration/component/maint/__init__.py rename test/integration/component/{ => maint}/test_high_availability.py (100%) rename test/integration/component/{ => maint}/test_host_high_availability.py (99%) rename test/integration/component/{ => maint}/test_vpc_host_maintenance.py (63%) create mode 100644 test/integration/component/maint/test_vpc_on_host_maintenance.py diff --git a/test/integration/component/maint/__init__.py b/test/integration/component/maint/__init__.py new file mode 100644 index 00000000000..f044f8bcd9a --- /dev/null +++ b/test/integration/component/maint/__init__.py @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Tests that put hosts, zones, resources in to maintenance mode are here. +These will have to be run sequentiall when resources are available so as not disrupt other tests +""" \ No newline at end of file diff --git a/test/integration/component/test_high_availability.py b/test/integration/component/maint/test_high_availability.py similarity index 100% rename from test/integration/component/test_high_availability.py rename to test/integration/component/maint/test_high_availability.py diff --git a/test/integration/component/test_host_high_availability.py b/test/integration/component/maint/test_host_high_availability.py similarity index 99% rename from test/integration/component/test_host_high_availability.py rename to test/integration/component/maint/test_host_high_availability.py index 2fe07b1771f..5fb047ba6cb 100644 --- a/test/integration/component/test_host_high_availability.py +++ b/test/integration/component/maint/test_host_high_availability.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -""" P1 tests for dedicated Host high availability +""" P1 tests for dedicated Host high availability """ #Import Local Modules from nose.plugins.attrib import attr @@ -157,7 +157,7 @@ class TestHostHighAvailability(cloudstackTestCase): # Validations, #1. Ensure that the offering is created and that in the UI the 'Offer HA' field is enabled (Yes) #The listServiceOffering API should list 'offerha' as true. - #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. + #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. # Also, check that the HA Enabled field is enabled 'Yes'. #list and validate above created service offering with Ha enabled @@ -257,7 +257,7 @@ class TestHostHighAvailability(cloudstackTestCase): self.debug("Deployed VM on host: %s" % vm.hostid) - #validate the virtual machine created is host Ha enabled + #validate the virtual machine created is host Ha enabled list_hosts_response = list_hosts( self.apiclient, id=vm.hostid @@ -593,7 +593,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_enabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_enabled.hostid @@ -725,7 +725,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_disabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_disabled.hostid diff --git a/test/integration/component/test_vpc_host_maintenance.py b/test/integration/component/maint/test_vpc_host_maintenance.py similarity index 63% rename from test/integration/component/test_vpc_host_maintenance.py rename to test/integration/component/maint/test_vpc_host_maintenance.py index d28b7985b9b..8fc427abd36 100644 --- a/test/integration/component/test_vpc_host_maintenance.py +++ b/test/integration/component/maint/test_vpc_host_maintenance.py @@ -558,332 +558,4 @@ class TestVMLifeCycleHostmaintenance(cloudstackTestCase): "Router state should be running" ) # TODO: Check for the network connectivity - return - - -class TestVPCNetworkRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkRules, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering_1 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_1"] - ) - cls.service_offering_2 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_2"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.services["vpc"]["cidr"] = '10.1.1.1/16' - cls.vpc = VPC.create( - cls.api_client, - cls.services["vpc"], - vpcofferingid=cls.vpc_off.id, - zoneid=cls.zone.id, - account=cls.account.name, - domainid=cls.account.domainid - ) - - cls.nw_off = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=False - ) - # Enable Network offering - cls.nw_off.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_1 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off.id, - zoneid=cls.zone.id, - gateway='10.1.1.1', - vpcid=cls.vpc.id - ) - cls.nw_off_no_lb = NetworkOffering.create( - cls.api_client, - cls.services["network_offering_no_lb"], - conservemode=False - ) - # Enable Network offering - cls.nw_off_no_lb.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_2 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off_no_lb.id, - zoneid=cls.zone.id, - gateway='10.1.2.1', - vpcid=cls.vpc.id - ) - # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_1.id)] - ) - # Spawn an instance in that network - cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_1.id)] - ) - cls.vm_3 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_2.id)] - ) - cls.vm_4 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_2.id)] - ) - - cls._cleanup = [ - cls.service_offering_1, - cls.service_offering_2, - cls.nw_off, - cls.nw_off_no_lb, - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.account.delete(cls.api_client) - wait_for_cleanup(cls.api_client, ["account.cleanup.interval"]) - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - # Waiting for network cleanup to delete vpc offering - wait_for_cleanup(cls.api_client, ["network.gc.wait", - "network.gc.interval"]) - cls.vpc_off.delete(cls.api_client) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def validate_vm_deployment(self): - """Validates VM deployment on different hosts""" - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_1.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_1 = vms[0].hostid - self.debug("Host for network 1: %s" % vms[0].hostid) - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_2 = vms[0].hostid - self.debug("Host for network 2: %s" % vms[0].hostid) - - self.assertNotEqual( - host_1, - host_2, - "Both the virtual machines should be deployed on diff hosts " - ) - return - - @attr(tags=["advanced", "intervlan"]) - def test_list_pf_rules_for_vpc(self): - """ Test List Port Forwarding Rules & vms belonging to a VPC - """ - - # Validate the following - # 1. Create a VPC with cidr - 10.1.1.1/16 - # 2. Add network1(10.1.1.1/24) and network2(10.1.2.1/24) to this VPC. - # 3. Deploy vm1 and vm2 in network1 and vm3 and vm4 in network2. - # Make sure vm1 and vm3 are deployed on one host in the cluster - # while vm2 and vm4 are deployed on the other host in the cluster. - # This can be done using host's tags and service offerings with - # host tags. - # 4. Create a PF rule for vms in network1. - # 5. Create a PF rule for vms in network2. - # Steps: - # 1. List all the Port Forwarding Rules belonging to a VPC - # 2. Successfully List the Port Forwarding Rules belonging to the VPC - # 3. List the VMs on network1 for selection for the PF Rule - # 4. Successfully list the VMs for Port Forwarding Rule creation - - self.debug("Associating public IP for network: %s" % - self.network_1.name) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_1.ipaddress.ipaddress, - self.network_1.id - )) - - nat_rule_1 = NATRule.create( - self.apiclient, - self.vm_1, - self.services["natrule"], - ipaddressid=public_ip_1.ipaddress.id, - openfirewall=False, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - - self.debug("Associating public IP for network: %s" % - self.network_2.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - self.network_2.id - )) - - nat_rule_2 = NATRule.create( - self.apiclient, - self.vm_3, - self.services["natrule"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=False, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - - self.debug("Listing all the PF rules belonging to VPC") - nat_rules = NATRule.list( - self.apiclient, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return the valid list" - ) - self.assertEqual( - len(nat_rules), - 2, - "List NAT for VPC shall return all NAT rules belonging to VPC" - ) - for nat_rule in nat_rules: - self.assertEqual( - nat_rule.vpcid, - self.vpc.id, - "NAT rules should belong to VPC" - ) - - self.debug( - "Listing all the VMs belonging to VPC for network: %s" % - self.network_1.name) - vms = VirtualMachine.list( - self.apiclient, - networkid=self.network_1.id, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List virtual machines should return the valid list" - ) - for vm in vms: - self.assertEqual( - vm.networkid, - self.network_1.id, - "List VMs should return vms belonging to network_1" - ) - return - + return \ No newline at end of file diff --git a/test/integration/component/maint/test_vpc_on_host_maintenance.py b/test/integration/component/maint/test_vpc_on_host_maintenance.py new file mode 100644 index 00000000000..6630ee61e0a --- /dev/null +++ b/test/integration/component/maint/test_vpc_on_host_maintenance.py @@ -0,0 +1,323 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * + + +class Services: + """Test VPC services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "vpc_offering": { + "name": 'VPC off', + "displaytext": 'VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL', + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.0.0.1/24' + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + # Hypervisor type should be same as + # hypervisor type of cluster + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + # Cent OS 5.3 (64 bit) + "sleep": 60, + "timeout": 10 + } + +class TestVPCHostMaintenance(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestVPCHostMaintenance, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["mode"] = cls.zone.networktype + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.vpc_off = VpcOffering.create( + cls.api_client, + cls.services["vpc_offering"] + ) + cls.vpc_off.update(cls.api_client, state='Enabled') + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + + if isinstance(hosts, list): + for host in hosts: + Host.enableMaintenance( + cls.api_client, + id=host.id + ) + + timeout = cls.services["timeout"] + while True: + time.sleep(cls.services["sleep"]) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate == 'PrepareForMaintenance': + # Wait for sometimetill host goes in maintenance state + time.sleep(cls.services["sleep"]) + elif hosts_states[0].resourcestate == 'Maintenance': + time.sleep(cls.services["sleep"]) + break + elif timeout == 0: + raise unittest.SkipTest( + "Failed to enable maintenance mode on %s" % host.name) + timeout = timeout - 1 + + cls._cleanup = [ + cls.service_offering, + cls.vpc_off + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + if isinstance(hosts, list): + for host in hosts: + Host.cancelMaintenance( + cls.api_client, + id=host.id + ) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate != 'Enabled': + raise Exception( + "Failed to cancel maintenance mode on %s" % (host.name)) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def validate_vpc_offering(self, vpc_offering): + """Validates the VPC offering""" + + self.debug("Check if the VPC offering is created successfully?") + vpc_offs = VpcOffering.list( + self.apiclient, + id=vpc_offering.id + ) + self.assertEqual( + isinstance(vpc_offs, list), + True, + "List VPC offerings should return a valid list" + ) + self.assertEqual( + vpc_offering.name, + vpc_offs[0].name, + "Name of the VPC offering should match with listVPCOff data" + ) + self.debug( + "VPC offering is created successfully - %s" % + vpc_offering.name) + return + + def validate_vpc_network(self, network, state=None): + """Validates the VPC network""" + + self.debug("Check if the VPC network is created successfully?") + vpc_networks = VPC.list( + self.apiclient, + id=network.id + ) + self.assertEqual( + isinstance(vpc_networks, list), + True, + "List VPC network should return a valid list" + ) + self.assertEqual( + network.name, + vpc_networks[0].name, + "Name of the VPC network should match with listVPC data" + ) + if state: + self.assertEqual( + vpc_networks[0].state, + state, + "VPC state should be '%s'" % state + ) + self.debug("VPC network validated - %s" % network.name) + return + + @attr(tags=["advanced", "intervlan"]) + def test_01_create_vpc_host_maintenance(self): + """ Test VPC when host is in maintenance mode + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. VPC will be created but will be in "Disabled" state + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + self.services["vpc"]["cidr"] = '10.1.1.1/16' + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + return + + @attr(tags=["advanced", "intervlan"]) + def test_02_create_vpc_wait_gc(self): + """ Test VPC when host is in maintenance mode and wait till nw gc + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. Wait for the VPC GC thread to run. + # 3. VPC will be created but will be in "Disabled" state and should + # get deleted + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + self.services["vpc"]["cidr"] = '10.1.1.1/16' + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + self.debug("Sleep till network gc thread runs..") + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + vpcs = VPC.list( + self.apiclient, + id=vpc.id, + listall=True + ) + self.assertEqual( + vpcs, + None, + "List VPC should not return anything after network gc" + ) + return diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 3fc0cc5a7e2..acf7a8eb2e3 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -18,16 +18,12 @@ """ Component tests for VPC functionality """ #Import Local Modules -import marvin -import unittest from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * -from marvin.remoteSSHClient import remoteSSHClient -import datetime class Services: @@ -331,7 +327,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_restart_vpc_with_networks(self): - """ Test restart VPC having with networks + """ Test restart VPC having networks """ # Validate the following @@ -2474,250 +2470,4 @@ class TestVPC(cloudstackTestCase): "Updation of VPC display text failed.") -class TestVPCHostMaintenance(cloudstackTestCase): - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCHostMaintenance, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - - if isinstance(hosts, list): - for host in hosts: - Host.enableMaintenance( - cls.api_client, - id=host.id - ) - - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate == 'PrepareForMaintenance': - # Wait for sometimetill host goes in maintenance state - time.sleep(cls.services["sleep"]) - elif hosts_states[0].resourcestate == 'Maintenance': - time.sleep(cls.services["sleep"]) - break - elif timeout == 0: - raise unittest.SkipTest( - "Failed to enable maintenance mode on %s" % host.name) - timeout = timeout - 1 - - cls._cleanup = [ - cls.service_offering, - cls.vpc_off - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - if isinstance(hosts, list): - for host in hosts: - Host.cancelMaintenance( - cls.api_client, - id=host.id - ) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate != 'Enabled': - raise Exception( - "Failed to cancel maintenance mode on %s" % (host.name)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def validate_vpc_offering(self, vpc_offering): - """Validates the VPC offering""" - - self.debug("Check if the VPC offering is created successfully?") - vpc_offs = VpcOffering.list( - self.apiclient, - id=vpc_offering.id - ) - self.assertEqual( - isinstance(vpc_offs, list), - True, - "List VPC offerings should return a valid list" - ) - self.assertEqual( - vpc_offering.name, - vpc_offs[0].name, - "Name of the VPC offering should match with listVPCOff data" - ) - self.debug( - "VPC offering is created successfully - %s" % - vpc_offering.name) - return - - def validate_vpc_network(self, network, state=None): - """Validates the VPC network""" - - self.debug("Check if the VPC network is created successfully?") - vpc_networks = VPC.list( - self.apiclient, - id=network.id - ) - self.assertEqual( - isinstance(vpc_networks, list), - True, - "List VPC network should return a valid list" - ) - self.assertEqual( - network.name, - vpc_networks[0].name, - "Name of the VPC network should match with listVPC data" - ) - if state: - self.assertEqual( - vpc_networks[0].state, - state, - "VPC state should be '%s'" % state - ) - self.debug("VPC network validated - %s" % network.name) - return - - @attr(tags=["advanced", "intervlan"]) - def test_01_create_vpc_host_maintenance(self): - """ Test VPC when host is in maintenance mode - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. VPC will be created but will be in "Disabled" state - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - self.services["vpc"]["cidr"] = '10.1.1.1/16' - vpc = VPC.create( - self.apiclient, - self.services["vpc"], - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - return - - @attr(tags=["advanced", "intervlan"]) - def test_02_create_vpc_wait_gc(self): - """ Test VPC when host is in maintenance mode and wait till nw gc - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. Wait for the VPC GC thread to run. - # 3. VPC will be created but will be in "Disabled" state and should - # get deleted - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - self.services["vpc"]["cidr"] = '10.1.1.1/16' - vpc = VPC.create( - self.apiclient, - self.services["vpc"], - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - self.debug("Sleep till network gc thread runs..") - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - vpcs = VPC.list( - self.apiclient, - id=vpc.id, - listall=True - ) - self.assertEqual( - vpcs, - None, - "List VPC should not return anything after network gc" - ) - return From f4dcca6e47d77e41e634c5d78fd403e1b4ba4b6d Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 17 Jun 2013 10:40:40 +0200 Subject: [PATCH 14/95] CLOUDSTACK-3019: add missing tags for test integration.component.test_advancedsg_networks.py --- test/integration/component/test_advancedsg_networks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/integration/component/test_advancedsg_networks.py b/test/integration/component/test_advancedsg_networks.py index e1694f12668..f8774be9e48 100644 --- a/test/integration/component/test_advancedsg_networks.py +++ b/test/integration/component/test_advancedsg_networks.py @@ -246,6 +246,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): raise Exception("Warning: Exception during network cleanup : %s" % e) return + @attr(tags = ["advancedsg"]) def test_createIsolatedNetwork(self): """ Test Isolated Network """ @@ -423,8 +424,9 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): except Exception as e: self.debug("Network creation failed because create isolated network is invalid in advanced zone with security groups.") + @attr(tags = ["advancedsg"]) def test_createSharedNetwork_withoutSG(self): - """ Test Shared Network with used vlan 01 """ + """ Test Shared Network with without SecurityProvider """ # Steps, # 1. create an Admin account @@ -574,6 +576,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): except Exception as e: self.debug("Network creation failed because there is no SecurityProvider in the network offering.") + @attr(tags = ["advancedsg"]) def test_deployVM_SharedwithSG(self): """ Test VM deployment in shared networks with SecurityProvider """ From a5189b1550139c2bcf2a0982ddbedf8effcd13d4 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 13:36:29 +0530 Subject: [PATCH 15/95] Fix the listVPC based on user roles listVPC based on user roles uses the old account.account reference causing the test to fail. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_vpc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index acf7a8eb2e3..0afeb772a1d 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -795,16 +795,16 @@ class TestVPC(cloudstackTestCase): self.services["vpc"], vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.validate_vpc_network(vpc_2) self.debug("Validating list VPCs call by passing account and domain") vpcs = VPC.list( self.apiclient, - account=self.user.account.name, - domainid=self.user.account.domainid, + account=self.user.name, + domainid=self.user.domainid, listall=True ) self.assertEqual( From 28b598b4acde49be61caade95824a60e213108b9 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 17:31:10 +0530 Subject: [PATCH 16/95] Fix VPC tests related to user roles Many vpc tests fail because of incorrect apiClient passed in to create the VPC, network etc. The exact method used is getUserApiClient to fetch the apiclient for a specific user. Signed-off-by: Prasanna Santhanam --- setup/dev/advanced.cfg | 3 +- test/integration/component/test_vpc.py | 158 +++++++------------- tools/marvin/marvin/cloudstackTestClient.py | 1 + 3 files changed, 59 insertions(+), 103 deletions(-) diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg index 302016569ab..3d0854d8aa7 100644 --- a/setup/dev/advanced.cfg +++ b/setup/dev/advanced.cfg @@ -218,7 +218,8 @@ "mgtSvrIp": "localhost", "passwd": "password", "user": "root", - "port": 8096 + "port": 8096, + "hypervisor" : "simulator" } ] } diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 0afeb772a1d..510e297c172 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -20,6 +20,7 @@ #Import Local Modules from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * +from marvin.cloudstackException import cloudstackAPIException from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * @@ -820,7 +821,7 @@ class TestVPC(cloudstackTestCase): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "multiple"]) def test_07_restart_network_vm_running(self): """ Test Restart VPC when there are multiple networks associated """ @@ -1923,8 +1924,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_14_deploy_vm_1(self): - """ Test deployment of vm in a network from user account. But the VPC is created - without account/domain ID + """ Test vm deploy in network by a user where VPC was created without account/domain ID """ # 1. Create VPC without providing account/domain ID. @@ -1935,18 +1935,19 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) + self.debug("Created account: %s" % user.name) self.cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, + userapiclient = self.testClient.createUserApiClient( + UserName=user.name, + DomainName=user.domain, acctType=0) + vpc = VPC.create( userapiclient, self.services["vpc"], @@ -1999,8 +2000,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_15_deploy_vm_2(self): - """ Test deployment of vm in a network from domain admin account. But the VPC is created - without account/domain ID + """ Test deployment of vm in a network in a domain admin account where VPC is created without account/domain ID """ # 1. Create VPC without providing account/domain ID. @@ -2016,18 +2016,18 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) + self.debug("Created account: %s" % user.name) self.cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=self.services["domain"]["name"], - acctType=2) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=self.services["domain"]["name"], + type=2) vpc = VPC.create( userapiclient, @@ -2092,23 +2092,23 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) + self.debug("Created account: %s" % user.name) self.cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) vpc = VPC.create( self.apiclient, self.services["vpc"], - account=user.account.name, - domainid=user.account.domainid, + account=user.name, + domainid=user.domainid, vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, ) @@ -2176,82 +2176,39 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["domain_admin"] ) - self.debug("Created account: %s" % domain_admin.account.name) + self.debug("Created account: %s" % domain_admin.name) self.cleanup.append(domain_admin) - da_apiclient = self.testClient.createNewApiClient( - UserName=domain_admin.account.name, - #DomainName=self.services["domain"]["name"], - DomainName=domain_admin.account.domain, - acctType=2) + da_apiclient = self.testClient.getUserApiClient( + account=domain_admin.name, + domain=domain_admin.domain, + type=2) user = Account.create( self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) + self.debug("Created account: %s" % user.name) self.cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) - vpc = VPC.create( - da_apiclient, - self.services["vpc"], - account=user.account.name, - domainid=user.account.domainid, - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - ) - self.validate_vpc_network(vpc) - - self.network_offering = NetworkOffering.create( - self.apiclient, - self.services["network_offering"], - conservemode=False - ) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - self._cleanup.append(self.network_offering) - - gateway = vpc.cidr.split('/')[0] - # Split the cidr to retrieve gateway - # for eg. cidr = 10.0.0.1/24 - # Gateway = 10.0.0.1 - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - userapiclient, - self.services["network"], - networkofferingid=self.network_offering.id, - zoneid=self.zone.id, - gateway=gateway, - vpcid=vpc.id - ) - self.debug("Created network with ID: %s" % network.id) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - userapiclient, - self.services["virtual_machine"], - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - self.assertNotEqual(virtual_machine, - None, - "VM creation in the network failed") - - return + with self.assertRaises(cloudstackAPIException): + vpc = VPC.create( + da_apiclient, + self.services["vpc"], + account=user.name, + domainid=user.domainid, + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + ) @attr(tags=["advanced", "intervlan"]) def test_18_create_net_for_user_diff_domain_by_doadmin(self): @@ -2271,29 +2228,29 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["domain_admin"] ) - self.debug("Created account: %s" % domain_admin.account.name) + self.debug("Created account: %s" % domain_admin.name) self.cleanup.append(domain_admin) - da_apiclient = self.testClient.createNewApiClient( - UserName=domain_admin.account.name, - DomainName=self.services["domain"]["name"], - acctType=2) + da_apiclient = self.testClient.getUserApiClient( + account=domain_admin.name, + domain=self.services["domain"]["name"], + type=2) user = Account.create( self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) + self.debug("Created account: %s" % user.name) self.cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) vpc = VPC.create( da_apiclient, @@ -2467,7 +2424,4 @@ class TestVPC(cloudstackTestCase): self.assertEqual(vpc_networks[0].displaytext, new_display_text, - "Updation of VPC display text failed.") - - - + "Updation of VPC display text failed.") \ No newline at end of file diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index d85a61c4872..37380d62f73 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -121,6 +121,7 @@ class cloudstackTestClient(object): apiKey, securityKey, self.connection.asyncTimeout, self.connection.logging) self.userApiClient = cloudstackAPIClient.CloudStackAPIClient(newUserConnection) self.userApiClient.connection = newUserConnection + self.userApiClient.hypervisor = self.apiClient.hypervisor return self.userApiClient def close(self): From 770cf02ccff2e4eac04a332216d1c575f18639be Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 14 Jun 2013 14:51:08 +0530 Subject: [PATCH 17/95] Global config to disable an account from acquiring public ips and guest vlans from the system if the account has dedicated resources and the dedicated resources have all been consumed - use.system.public.ips and use.system.guest.vlans Both configs are configurable at the account level too. --- .../src/com/cloud/dc/dao/DataCenterDao.java | 2 +- .../src/com/cloud/dc/dao/DataCenterDaoImpl.java | 15 ++++++++++----- .../guru/BigSwitchVnsGuestNetworkGuru.java | 2 +- .../cloud/network/guru/OvsGuestNetworkGuru.java | 3 ++- server/src/com/cloud/configuration/Config.java | 9 ++++++++- .../src/com/cloud/network/NetworkManagerImpl.java | 5 ++++- .../network/guru/ExternalGuestNetworkGuru.java | 3 ++- .../com/cloud/network/guru/GuestNetworkGuru.java | 11 ++++++++++- setup/db/db/schema-410to420.sql | 3 +++ 9 files changed, 41 insertions(+), 12 deletions(-) diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java index e54b9bbbe29..ed6e6965312 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java @@ -36,7 +36,7 @@ public interface DataCenterDao extends GenericDao { Pair allocatePrivateIpAddress(long id, long podId, long instanceId, String reservationId); DataCenterIpAddressVO allocatePrivateIpAddress(long id, String reservationId); String allocateLinkLocalIpAddress(long id, long podId, long instanceId, String reservationId); - String allocateVnet(long dcId, long physicalNetworkId, long accountId, String reservationId); + String allocateVnet(long dcId, long physicalNetworkId, long accountId, String reservationId, boolean canUseSystemGuestVlans); void releaseVnet(String vnet, long dcId, long physicalNetworkId, long accountId, String reservationId); void releasePrivateIpAddress(String ipAddress, long dcId, Long instanceId); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 4d9d01065ca..503306f6722 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -192,22 +192,27 @@ public class DataCenterDaoImpl extends GenericDaoBase implem } @Override - public String allocateVnet(long dataCenterId, long physicalNetworkId, long accountId, String reservationId) { + public String allocateVnet(long dataCenterId, long physicalNetworkId, long accountId, String reservationId, + boolean canUseSystemGuestVlans) { ArrayList dedicatedVlanDbIds = new ArrayList(); + boolean useDedicatedGuestVlans = false; List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId); for (AccountGuestVlanMapVO map : maps) { dedicatedVlanDbIds.add(map.getId()); } if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { + useDedicatedGuestVlans = true; DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, dedicatedVlanDbIds); if (vo != null) return vo.getVnet(); } - DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, null); - if (vo == null) { - return null; + if (!useDedicatedGuestVlans || (useDedicatedGuestVlans && canUseSystemGuestVlans)) { + DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, null); + if (vo != null) { + return vo.getVnet(); + } } - return vo.getVnet(); + return null; } @Override diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java index e753b131ef7..f660b7c7838 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java @@ -162,7 +162,7 @@ public class BigSwitchVnsGuestNetworkGuru extends GuestNetworkGuru { } String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, - network.getAccountId(), context.getReservationId()); + network.getAccountId(), context.getReservationId(), canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, dcId); diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java index 781b4b9b2f2..bbdf1108f90 100644 --- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java +++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java @@ -94,7 +94,8 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru { protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { if (network.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); + String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, + canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 5ee0fad8643..5432ab6dd4e 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -216,7 +216,14 @@ public enum Config { AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null), - + UseSystemPublicIps("Advanced", ManagementServer.class, Boolean.class, "use.system.public.ips", "true", + "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been" + + " consumed ips will be acquired from the system pool", + null, ConfigurationParameterScope.account.toString()), + UseSystemGuestVlans("Advanced", ManagementServer.class, Boolean.class, "use.system.guest.vlans", "true", + "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been" + + " consumed vlans will be allocated from the system pool", + null, ConfigurationParameterScope.account.toString()), // LB HealthCheck Interval. LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600", diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index d6a64508ffe..f5633357e56 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -445,7 +445,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L // If all the dedicated IPs of the owner are in use fetch an IP from the system pool if (addrs.size() == 0 && fetchFromDedicatedRange) { - if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { + // Verify if account is allowed to acquire IPs from the system + boolean useSystemIps = Boolean.parseBoolean(_configServer.getConfigValue(Config.UseSystemPublicIps.key(), + Config.ConfigurationParameterScope.account.toString(), owner.getId())); + if(useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java index eb1b3dc4b24..87098f5049b 100644 --- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -130,7 +130,8 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { // Get a vlan tag int vlanTag; if (config.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), context.getReservationId()); + String vnet = _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), + context.getReservationId(), canUseSystemGuestVlan(config.getAccountId())); try { vlanTag = Integer.parseInt(vnet); diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 32ce744979b..89b0694e114 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -26,6 +26,7 @@ import javax.ejb.Local; import javax.inject.Inject; import com.cloud.event.ActionEventUtils; +import com.cloud.server.ConfigurationServer; import com.cloud.utils.Pair; import org.apache.log4j.Logger; @@ -98,6 +99,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur IPAddressDao _ipAddressDao; @Inject protected PhysicalNetworkDao _physicalNetworkDao; + @Inject + ConfigurationServer _configServer; Random _rand = new Random(System.currentTimeMillis()); private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; @@ -155,6 +158,11 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur return _isolationMethods; } + public boolean canUseSystemGuestVlan(long accountId) { + return Boolean.parseBoolean(_configServer.getConfigValue(Config.UseSystemGuestVlans.key(), + Config.ConfigurationParameterScope.account.toString(), accountId)); + } + protected abstract boolean canHandle(NetworkOffering offering, final NetworkType networkType, PhysicalNetwork physicalNetwork); @Override @@ -260,7 +268,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { if (network.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); + String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, + canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, dcId); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index bcfbcc931fe..272fc4276a6 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1854,3 +1854,6 @@ SET foreign_key_checks = 1; UPDATE `cloud`.`snapshot_policy` set uuid=id WHERE uuid is NULL; #update shared sg enabled network with not null name in Advance Security Group enabled network UPDATE `cloud`.`networks` set name='Shared SG enabled network', display_text='Shared SG enabled network' WHERE name IS null AND traffic_type='Guest' AND data_center_id IN (select id from data_center where networktype='Advanced' and is_security_group_enabled=1) AND acl_type='Domain'; + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.public.ips', 'true', 'If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.guest.vlans', 'true', 'If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool'); From 3a0294212372b9ed1ecc7522d732e640c070d013 Mon Sep 17 00:00:00 2001 From: Dave Brosius Date: Wed, 22 May 2013 02:23:27 -0400 Subject: [PATCH 18/95] set rpcProvider field correctly Signed-off-by: Dave Brosius Signed-off-by: Prasanna Santhanam --- .../cloudstack/storage/HypervisorHostEndPointRpcServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java index bc217769d91..060b490e6a8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java +++ b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java @@ -46,7 +46,7 @@ public class HypervisorHostEndPointRpcServer implements HostEndpointRpcServer { } public HypervisorHostEndPointRpcServer(RpcProvider rpcProvider) { - rpcProvider = rpcProvider; + this.rpcProvider = rpcProvider; rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); } From 6a5c9d777f979fe62b0ff45d88f8a44fd4e5057b Mon Sep 17 00:00:00 2001 From: Gaurav Aradhye Date: Mon, 17 Jun 2013 03:04:23 -0400 Subject: [PATCH 19/95] CLOUDSTACK-2935: Corrected VPC code related to cleanup Signed-off-by: Prasanna Santhanam --- test/integration/component/test_vpc_network_lbrules.py | 2 +- test/integration/component/test_vpc_network_pfrules.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/component/test_vpc_network_lbrules.py b/test/integration/component/test_vpc_network_lbrules.py index 66d6c4d4018..3461bb4e426 100644 --- a/test/integration/component/test_vpc_network_lbrules.py +++ b/test/integration/component/test_vpc_network_lbrules.py @@ -408,7 +408,7 @@ class TestVPCNetworkLBRules(cloudstackTestCase): self.services["vpc_offering"] ) - self._cleanup.append(self.vpc_off) + self._cleanup.append(vpc_off) self.debug("Enabling the VPC offering created") vpc_off.update(self.apiclient, state='Enabled') diff --git a/test/integration/component/test_vpc_network_pfrules.py b/test/integration/component/test_vpc_network_pfrules.py index 92b04ad3f21..8d1d9eccd0b 100644 --- a/test/integration/component/test_vpc_network_pfrules.py +++ b/test/integration/component/test_vpc_network_pfrules.py @@ -406,7 +406,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase): self.services["vpc_offering"] ) - self._cleanup.append(self.vpc_off) + self._cleanup.append(vpc_off) self.debug("Enabling the VPC offering created") vpc_off.update(self.apiclient, state='Enabled') From f8965b6f07e32275f5463d4a89a973030b51b123 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 19:44:33 +0530 Subject: [PATCH 20/95] Concentrated planner granularity is at pod level user.concentrated pod planner will try and put the VMs in the same pod. Correcting the assertion to verify same pod and not same cluster. Test may have passed earlier because of presence of single pod in the deployment. Signed-off-by: Prasanna Santhanam --- ...test_deploy_vms_with_varied_deploymentplanners.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py index af832995245..fc8e71648af 100644 --- a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py +++ b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py @@ -16,7 +16,7 @@ # under the License. from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering, Host +from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering, Host, Cluster from marvin.integration.lib.common import get_zone, get_domain, get_template, cleanup_resources from nose.plugins.attrib import attr @@ -77,6 +77,7 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase): ) cls.services["account"] = cls.account.name cls.hosts = Host.list(cls.apiclient, type='Routing') + cls.clusters = Cluster.list(cls.apiclient) cls.cleanup = [ cls.account ] @@ -241,10 +242,13 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase): ) vm1clusterid = filter(lambda c: c.id == vm1.hostid, self.hosts)[0].clusterid vm2clusterid = filter(lambda c: c.id == vm2.hostid, self.hosts)[0].clusterid + + vm1podid = filter(lambda p: p.id == vm1clusterid, self.clusters)[0].podid + vm2podid = filter(lambda p: p.id == vm2clusterid, self.clusters)[0].podid self.assertEqual( - vm1clusterid, - vm2clusterid, - msg="VMs (%s, %s) meant to be concentrated are deployed on different clusters (%s, %s)" % (vm1.id, vm2.id, vm1clusterid, vm2clusterid) + vm1podid, + vm2podid, + msg="VMs (%s, %s) meant to be pod concentrated are deployed on different pods (%s, %s)" % (vm1.id, vm2.id, vm1clusterid, vm2clusterid) ) @classmethod From 363a7b933c4c7a7cbec096775d991f7430e70968 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Mon, 17 Jun 2013 22:25:01 +0530 Subject: [PATCH 21/95] list the VPCs with vpc id not network id test failed because of incorrectly listing the VPC using the networkid. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_vpc.py | 4 ++-- test/integration/smoke/test_portable_publicip.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 510e297c172..cc7069533db 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -1651,7 +1651,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_11_deploy_vm_wo_network_netdomain(self): - """ Test deployment of vm in a VPC without network netdomain + """ Test deployment of vm in a VPC without network domain """ # 1. Create VPC without providing networkDomain. @@ -2410,7 +2410,7 @@ class TestVPC(cloudstackTestCase): vpc_networks = VPC.list( self.apiclient, - id=network.id + id=vpc.id ) self.assertEqual( diff --git a/test/integration/smoke/test_portable_publicip.py b/test/integration/smoke/test_portable_publicip.py index 5b2fbc7e307..9a3a398c17a 100644 --- a/test/integration/smoke/test_portable_publicip.py +++ b/test/integration/smoke/test_portable_publicip.py @@ -21,7 +21,6 @@ from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * -from marvin import remoteSSHClient from nose.plugins.attrib import attr class Services: From 76d3c27bf4c0ab3690840e56ca162935cea91d48 Mon Sep 17 00:00:00 2001 From: Nils Date: Mon, 17 Jun 2013 15:46:39 +0200 Subject: [PATCH 22/95] CLOUDSTACK-2902: Fixing references to 4.1 repository for this release --- docs/en-US/Release_Notes.xml | 8 ++++---- docs/en-US/configure-package-repository.xml | 4 ++-- docs/pot/configure-package-repository.pot | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml index 2ae87320e40..b9861eeceeb 100644 --- a/docs/en-US/Release_Notes.xml +++ b/docs/en-US/Release_Notes.xml @@ -398,7 +398,7 @@ under the License. SSH keypair assigned to a virtual machine. -
+
Issues Fixed in 4.1.0 Apache CloudStack uses Jira to track its issues. All new features and bugs for 4.1.0 have been tracked @@ -4775,7 +4775,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 @@ -5067,7 +5067,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 @@ -5663,7 +5663,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 diff --git a/docs/en-US/configure-package-repository.xml b/docs/en-US/configure-package-repository.xml index c8ba48f2717..cda46773f53 100644 --- a/docs/en-US/configure-package-repository.xml +++ b/docs/en-US/configure-package-repository.xml @@ -44,7 +44,7 @@ DEB package repository You can add a DEB package repository to your apt sources with the following commands. Please note that only packages for Ubuntu 12.04 LTS (precise) are being built at this time. Use your preferred editor and open (or create) /etc/apt/sources.list.d/cloudstack.list. Add the community provided repository to the file: -deb http://cloudstack.apt-get.eu/ubuntu precise 4.0 +deb http://cloudstack.apt-get.eu/ubuntu precise 4.1 We now have to add the public key to the trusted keys. $ wget -O - http://cloudstack.apt-get.eu/release.asc|apt-key add - Now update your local apt cache. @@ -60,7 +60,7 @@ [cloudstack] name=cloudstack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 diff --git a/docs/pot/configure-package-repository.pot b/docs/pot/configure-package-repository.pot index e91535826a5..c0ee374254a 100644 --- a/docs/pot/configure-package-repository.pot +++ b/docs/pot/configure-package-repository.pot @@ -60,7 +60,7 @@ msgstr "" #. Tag: programlisting #, no-c-format -msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.0" +msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.1" msgstr "" #. Tag: para @@ -118,7 +118,7 @@ msgstr "" msgid "\n" "[cloudstack]\n" "name=cloudstack\n" -"baseurl=http://cloudstack.apt-get.eu/rhel/4.0/\n" +"baseurl=http://cloudstack.apt-get.eu/rhel/4.1/\n" "enabled=1\n" "gpgcheck=0\n" " " From b0ea02e65a01cf62004de0851284da7a8868d406 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Sun, 16 Jun 2013 14:37:48 -0700 Subject: [PATCH 23/95] Allow DSA public keys. DSA can't be used for encryption with the bouncycastle library, so make sure this situation is properly handled. --- .../src/com/cloud/vm/UserVmManagerImpl.java | 63 +++++++---------- .../com/cloud/utils/ssh/SSHKeysHelper.java | 2 +- .../com/cloud/utils/crypto/RSAHelperTest.java | 50 ++++++++++++++ .../cloud/utils/ssh/SSHKeysHelperTest.java | 69 +++++++++++++++++++ 4 files changed, 143 insertions(+), 41 deletions(-) create mode 100644 utils/test/com/cloud/utils/crypto/RSAHelperTest.java create mode 100644 utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1c8ab75f183..44a7d0668b2 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -509,18 +509,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // update the password in vm_details table too // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = userVm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") - && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( - sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - - userVm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(userVm); - } + encryptAndStorePassword(userVm, password); } else { throw new CloudRuntimeException( "Failed to reset password for the virtual machine "); @@ -643,13 +632,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if (template != null && template.getEnablePassword()) { userVm.setPassword(password); //update the encrypted password in vm_details table too - if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - userVm.setDetail("Encrypted.Password", encryptedPasswd); - } + encryptAndStorePassword(userVm, password); } _vmDao.saveDetails(userVm); } else { @@ -3304,18 +3287,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = vm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") - && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( - sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - - vm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(vm); - } + encryptAndStorePassword(vm, password); params = new HashMap(); if (additionalParams != null) { @@ -4621,15 +4593,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // update the password in vm_details table too // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = vm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("VM reset is completed but error occurred when encrypting newly created password"); - } - vm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(vm); - } + encryptAndStorePassword(vm, password); } else { throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine "); } @@ -4717,5 +4681,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if (vm.getState() == State.Running) collectVmDiskStatistics(vm); } + + private void encryptAndStorePassword(UserVmVO vm, String password) { + String sshPublicKey = vm.getDetail("SSH.PublicKey"); + if (sshPublicKey != null && !sshPublicKey.equals("") + && password != null && !password.equals("saved_password")) { + if (!sshPublicKey.startsWith("ssh-rsa")) { + s_logger.warn("Only RSA public keys can be used to encrypt a vm password."); + return; + } + String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( + sshPublicKey, password); + if (encryptedPasswd == null) { + throw new CloudRuntimeException("Error encrypting password"); + } + + vm.setDetail("Encrypted.Password", encryptedPasswd); + _vmDao.saveDetails(vm); + } + } } diff --git a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java index 2755c548048..a14e5a4a9d7 100644 --- a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java +++ b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java @@ -82,7 +82,7 @@ public class SSHKeysHelper { if (!keyMaterial.contains(" ")) keyMaterial = new String(Base64.decodeBase64(keyMaterial.getBytes())); - if (!keyMaterial.startsWith("ssh-rsa") || !keyMaterial.contains(" ")) + if ((!keyMaterial.startsWith("ssh-rsa") && !keyMaterial.startsWith("ssh-dss")) || !keyMaterial.contains(" ")) return null; String[] key = keyMaterial.split(" "); diff --git a/utils/test/com/cloud/utils/crypto/RSAHelperTest.java b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java new file mode 100644 index 00000000000..d1f496e1ab1 --- /dev/null +++ b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// 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. +package com.cloud.utils.crypto; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.cloud.utils.crypt.RSAHelper; + +public class RSAHelperTest { + @Test + public void testEncryptWithRSA() { + String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX"; + String encryptedString = RSAHelper.encryptWithSSHPublicKey(rsaKey, "content"); + assertNotNull(encryptedString); + } + + @Test + public void testEncryptWithDSA() { + String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ=="; + String encryptedString = RSAHelper.encryptWithSSHPublicKey(dssKey, "content"); + assertNull(encryptedString); + } +} diff --git a/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java new file mode 100644 index 00000000000..6402e3ef347 --- /dev/null +++ b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java @@ -0,0 +1,69 @@ +// 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. +package com.cloud.utils.ssh; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SSHKeysHelperTest { + @Test + public void rsaKeyTest() { + String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX test@testkey"; + String storedRsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX"; + String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(rsaKey); + String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey); + + assertTrue(storedRsaKey.equals(parsedKey)); + assertTrue("f6:96:3f:f4:78:f7:80:11:6c:f8:e3:2b:40:20:f1:14".equals(fingerprint)); + + } + + @Test + public void dsaKeyTest() { + String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ== test key"; + String storedDssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ=="; + String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(dssKey); + String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey); + + assertTrue(storedDssKey.equals(parsedKey)); + assertTrue("fc:6e:ef:31:93:f8:92:2b:a9:03:c7:06:90:f5:ec:bb".equals(fingerprint)); + + } +} From fc16e29f992d81156a4e08a77da215f8276f4efe Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 17 Jun 2013 10:09:52 -0700 Subject: [PATCH 24/95] CLOUDSTACK-2914: default lb scheme to Public when the service LB is enabled, and scheme is not specified explicitly --- .../command/admin/network/CreateNetworkOfferingCmd.java | 2 +- .../com/cloud/configuration/ConfigurationManagerImpl.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index 6410715727c..febb0c337eb 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -95,7 +95,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.IS_PERSISTENT, type=CommandType.BOOLEAN, description="true if network offering supports persistent networks; defaulted to false if not specified") private Boolean isPersistent; - @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Template details in key/value pairs." + + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Network offering details in key/value pairs." + " Supported keys are internallbprovider/publiclbprovider with service provider as a value") protected Map details; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 131d34054e3..68745bfacaa 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -3968,9 +3968,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.LbSchemes, publicLbStr); internalLb = publicLbStr.contains("internal"); publicLb = publicLbStr.contains("public"); - } else { - //if not specified, default public lb to true - publicLb = true; } } } @@ -4009,6 +4006,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } } + + if (serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) { + //if not specified, default public lb to true + publicLb = true; + } NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, From 25726277975fb9e39ade7c08d680a93d33dc16b2 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Mon, 17 Jun 2013 13:47:19 -0400 Subject: [PATCH 25/95] Revert "CLOUDSTACK-2902: Fixing references to 4.1 repository for this release" This reverts commit 76d3c27bf4c0ab3690840e56ca162935cea91d48. --- docs/en-US/Release_Notes.xml | 8 ++++---- docs/en-US/configure-package-repository.xml | 4 ++-- docs/pot/configure-package-repository.pot | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml index b9861eeceeb..2ae87320e40 100644 --- a/docs/en-US/Release_Notes.xml +++ b/docs/en-US/Release_Notes.xml @@ -398,7 +398,7 @@ under the License. SSH keypair assigned to a virtual machine.
-
+
Issues Fixed in 4.1.0 Apache CloudStack uses Jira to track its issues. All new features and bugs for 4.1.0 have been tracked @@ -4775,7 +4775,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ enabled=1 gpgcheck=0 @@ -5067,7 +5067,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ enabled=1 gpgcheck=0 @@ -5663,7 +5663,7 @@ service cloudstack-agent restart [apache-cloudstack] name=Apache CloudStack -baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ enabled=1 gpgcheck=0 diff --git a/docs/en-US/configure-package-repository.xml b/docs/en-US/configure-package-repository.xml index cda46773f53..c8ba48f2717 100644 --- a/docs/en-US/configure-package-repository.xml +++ b/docs/en-US/configure-package-repository.xml @@ -44,7 +44,7 @@ DEB package repository You can add a DEB package repository to your apt sources with the following commands. Please note that only packages for Ubuntu 12.04 LTS (precise) are being built at this time. Use your preferred editor and open (or create) /etc/apt/sources.list.d/cloudstack.list. Add the community provided repository to the file: -deb http://cloudstack.apt-get.eu/ubuntu precise 4.1 +deb http://cloudstack.apt-get.eu/ubuntu precise 4.0 We now have to add the public key to the trusted keys. $ wget -O - http://cloudstack.apt-get.eu/release.asc|apt-key add - Now update your local apt cache. @@ -60,7 +60,7 @@ [cloudstack] name=cloudstack -baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ enabled=1 gpgcheck=0 diff --git a/docs/pot/configure-package-repository.pot b/docs/pot/configure-package-repository.pot index c0ee374254a..e91535826a5 100644 --- a/docs/pot/configure-package-repository.pot +++ b/docs/pot/configure-package-repository.pot @@ -60,7 +60,7 @@ msgstr "" #. Tag: programlisting #, no-c-format -msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.1" +msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.0" msgstr "" #. Tag: para @@ -118,7 +118,7 @@ msgstr "" msgid "\n" "[cloudstack]\n" "name=cloudstack\n" -"baseurl=http://cloudstack.apt-get.eu/rhel/4.1/\n" +"baseurl=http://cloudstack.apt-get.eu/rhel/4.0/\n" "enabled=1\n" "gpgcheck=0\n" " " From 9ef366e4b3d7e237503d7dd6a1f4b7af4b74b445 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Mon, 17 Jun 2013 13:46:30 -0400 Subject: [PATCH 26/95] CLOUDSTACK-2902: Updating repository refs Conflicts: docs/zh-TW/configure-package-repository.po --- docs/en-US/configure-package-repository.xml | 4 ++-- docs/pot/configure-package-repository.pot | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en-US/configure-package-repository.xml b/docs/en-US/configure-package-repository.xml index c8ba48f2717..cda46773f53 100644 --- a/docs/en-US/configure-package-repository.xml +++ b/docs/en-US/configure-package-repository.xml @@ -44,7 +44,7 @@ DEB package repository You can add a DEB package repository to your apt sources with the following commands. Please note that only packages for Ubuntu 12.04 LTS (precise) are being built at this time. Use your preferred editor and open (or create) /etc/apt/sources.list.d/cloudstack.list. Add the community provided repository to the file: -deb http://cloudstack.apt-get.eu/ubuntu precise 4.0 +deb http://cloudstack.apt-get.eu/ubuntu precise 4.1 We now have to add the public key to the trusted keys. $ wget -O - http://cloudstack.apt-get.eu/release.asc|apt-key add - Now update your local apt cache. @@ -60,7 +60,7 @@ [cloudstack] name=cloudstack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 diff --git a/docs/pot/configure-package-repository.pot b/docs/pot/configure-package-repository.pot index e91535826a5..c0ee374254a 100644 --- a/docs/pot/configure-package-repository.pot +++ b/docs/pot/configure-package-repository.pot @@ -60,7 +60,7 @@ msgstr "" #. Tag: programlisting #, no-c-format -msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.0" +msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.1" msgstr "" #. Tag: para @@ -118,7 +118,7 @@ msgstr "" msgid "\n" "[cloudstack]\n" "name=cloudstack\n" -"baseurl=http://cloudstack.apt-get.eu/rhel/4.0/\n" +"baseurl=http://cloudstack.apt-get.eu/rhel/4.1/\n" "enabled=1\n" "gpgcheck=0\n" " " From bd699390a6b1c84c0467c94bc0fdba2ed4e28177 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Mon, 17 Jun 2013 13:50:53 -0400 Subject: [PATCH 27/95] Correcting ID in the release notes from issues-fixed-4.0 to issues-fixed-4.1 --- docs/en-US/Release_Notes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml index 2ae87320e40..8843f4c2e20 100644 --- a/docs/en-US/Release_Notes.xml +++ b/docs/en-US/Release_Notes.xml @@ -398,7 +398,7 @@ under the License. SSH keypair assigned to a virtual machine.
-
+
Issues Fixed in 4.1.0 Apache CloudStack uses Jira to track its issues. All new features and bugs for 4.1.0 have been tracked From 952fa2464da9f10b63fbba869922ee735c231c42 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 17 Jun 2013 10:50:22 -0700 Subject: [PATCH 28/95] LOUDSTACK-2914: handle situation when serviceProvider map is empty --- .../src/com/cloud/configuration/ConfigurationManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 68745bfacaa..12164a26694 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -4007,7 +4007,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - if (serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) { + if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) { //if not specified, default public lb to true publicLb = true; } From a2c7d3a8a75b2cec266cef566b8828be7a1ebc72 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 10:55:50 -0700 Subject: [PATCH 29/95] CLOUDSTACK-869: Add VPC dialog - add Public LB Provider dropdown, remove VPC Offering dropdown. When Public LB Provider is selected as Netscaler, pass "Default VPC offering with Netscaler" to createVPC API. When Public LB Provider is selected as VpcVirtualRouter, pass "Default VPC Offering" to createVPC API. --- ui/scripts/network.js | 125 +++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 68 deletions(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index fb63e4b4f19..ddde9c967e5 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -4532,78 +4532,67 @@ docID: 'helpVPCDomain', label: 'label.DNS.domain.for.guest.networks' }, - - loadbalancer:{ //Support for Netscaler as an external device for load balancing - label:'Load Balancer', + publicLoadBalancerProvider:{ + label:'Public Load Balancer Provider', 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}); - - } - - }); - - } - - } - + var items = []; + items.push({id: 'VpcVirtualRouter', description: 'VpcVirtualRouter'}); + items.push({id: 'Netscaler', description: 'Netscaler'}); + args.response.success({data: items}); + } + } } }, - action: function(args) { - /* var defaultvpcofferingid; - $.ajax({ - url: createURL("listVPCOfferings"), - dataType: "json", - data: { - isdefault: true - }, - async: false, - 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: args.data.loadbalancer // Support for external load balancer - }; - - if(args.data.networkdomain != null && args.data.networkdomain.length > 0) - $.extend(dataObj, { networkdomain: args.data.networkdomain }); - - $.ajax({ - url: createURL("createVPC"), - dataType: "json", - data: dataObj, - async: true, - success: function(json) { - var jid = json.createvpcresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.vpc; - } + action: function(args) { + var vpcOfferingName; + if (args.data.publicLoadBalancerProvider == 'VpcVirtualRouter') + vpcOfferingName = 'Default VPC offering'; + else if (args.data.publicLoadBalancerProvider == 'Netscaler') + vpcOfferingName = 'Default VPC offering with Netscaler'; + + $.ajax({ + url:createURL('listVPCOfferings'), + data: { + name: vpcOfferingName + }, + success:function(json){ + var vpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id; + + var dataObj = { + name: args.data.name, + displaytext: args.data.displaytext, + zoneid: args.data.zoneid, + cidr: args.data.cidr, + vpcofferingid: vpcofferingid + }; + + if(args.data.networkdomain != null && args.data.networkdomain.length > 0) + $.extend(dataObj, { networkdomain: args.data.networkdomain }); + + $.ajax({ + url: createURL("createVPC"), + dataType: "json", + data: dataObj, + async: true, + success: function(json) { + var jid = json.createvpcresponse.jobid; + args.response.success( + {_custom: + {jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.vpc; + } + } + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - }, - + }); + } + }); + + }, notification: { poll: pollAsyncJobResult } From ce8ada030d3150087357d7135c3877c25a4702c2 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 8 Jun 2013 21:46:40 +0200 Subject: [PATCH 30/95] Removed String instantiation String instantiation and redundant method call replaced with a constant. Signed-off-by: Laszlo Hornyak --- .../cloud/network/HAProxyConfigurator.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/core/src/com/cloud/network/HAProxyConfigurator.java b/core/src/com/cloud/network/HAProxyConfigurator.java index 29fdf4ae256..162571fa689 100644 --- a/core/src/com/cloud/network/HAProxyConfigurator.java +++ b/core/src/com/cloud/network/HAProxyConfigurator.java @@ -33,7 +33,6 @@ import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO; import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO; -import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.utils.net.NetUtils; @@ -41,6 +40,7 @@ import com.cloud.utils.net.NetUtils; public class HAProxyConfigurator implements LoadBalancerConfigurator { private static final Logger s_logger = Logger.getLogger(HAProxyConfigurator.class); + private static final String blankLine = "\t "; private static String[] globalSection = { "global", "\tlog 127.0.0.1:3914 local0 warning", "\tmaxconn 4096", @@ -86,9 +86,9 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { List result = new ArrayList(); result.addAll(Arrays.asList(globalSection)); - result.add(getBlankLine()); + result.add(blankLine); result.addAll(Arrays.asList(defaultsSection)); - result.add(getBlankLine()); + result.add(blankLine); if (pools.isEmpty()) { // haproxy cannot handle empty listen / frontend or backend, so add @@ -96,7 +96,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { // on port 9 result.addAll(Arrays.asList(defaultListen)); } - result.add(getBlankLine()); + result.add(blankLine); for (Map.Entry> e : pools.entrySet()) { List poolRules = getRulesForPool(e.getKey(), e.getValue()); @@ -143,7 +143,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { .append(rule.getDstPortRange()[0]).append(" check"); result.add(sb.toString()); } - result.add(getBlankLine()); + result.add(blankLine); return result; } @@ -507,14 +507,10 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { result.add(sb.toString()); } - result.add(getBlankLine()); + result.add(blankLine); return result; } - private String getBlankLine() { - return new String("\t "); - } - private String generateStatsRule(LoadBalancerConfigCommand lbCmd, String ruleName, String statsIp) { StringBuilder rule = new StringBuilder("\nlisten ").append(ruleName) @@ -534,7 +530,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { List result = new ArrayList(); result.addAll(Arrays.asList(globalSection)); - result.add(getBlankLine()); + result.add(blankLine); result.addAll(Arrays.asList(defaultsSection)); if (!lbCmd.lbStatsVisibility.equals("disabled")) { /* new rule : listen admin_page guestip/link-local:8081 */ @@ -568,7 +564,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { } } - result.add(getBlankLine()); + result.add(blankLine); boolean has_listener = false; for (LoadBalancerTO lbTO : lbCmd.getLoadBalancers()) { if ( lbTO.isRevoked() ) { @@ -578,7 +574,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { result.addAll(poolRules); has_listener = true; } - result.add(getBlankLine()); + result.add(blankLine); if ( !has_listener) { // haproxy cannot handle empty listen / frontend or backend, so add // a dummy listener From 564013bec0d4356232d93ac52a3e44638578bff0 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 8 Jun 2013 21:39:52 +0200 Subject: [PATCH 31/95] String instantiation is not needed Removed a String instntiation, test case added Signed-off-by: Laszlo Hornyak --- utils/src/com/cloud/utils/net/NetUtils.java | 2 +- utils/test/com/cloud/utils/net/NetUtilsTest.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 5c13454da79..60993799b41 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -257,7 +257,7 @@ public class NetUtils { return ipFromInetAddress(addr); } - return new String("127.0.0.1"); + return "127.0.0.1"; } public static String ipFromInetAddress(InetAddress addr) { diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index 38fe21d5324..3cfc98fb3b6 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -168,4 +168,9 @@ public class NetUtilsTest extends TestCase { newMac = NetUtils.generateMacOnIncrease(mac, 16); assertTrue(newMac.equals("06:00:0f:00:45:67")); } + + @Test + public void testGetLocalIPString() { + assertNotNull(NetUtils.getLocalIPString()); + } } From c88d8fb3a2f6c418c6c7af8ff702a93bcdb2d752 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sun, 9 Jun 2013 21:40:28 +0200 Subject: [PATCH 32/95] use commons-lang StringUtils commons-lang is already a transitive dependency of the utils project, which allows removing some duplicated functionality. This patch replaces StringUtils.join(String, Object...) with it's commons-lang counterpart. It also replaces calls to String join(Iterable, String) in cases where an array is already exist and it is only wrapped into a List. Signed-off-by: Laszlo Hornyak --- .../com/cloud/storage/s3/S3ManagerImpl.java | 10 +++------- .../resource/NfsSecondaryStorageResource.java | 19 ++++++------------- utils/src/com/cloud/utils/S3Utils.java | 4 ++-- utils/src/com/cloud/utils/StringUtils.java | 6 +----- .../test/com/cloud/utils/StringUtilsTest.java | 5 +++++ 5 files changed, 17 insertions(+), 27 deletions(-) diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index 61e5573394d..91fa9c34f0f 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -41,7 +41,6 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; -import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -193,13 +192,12 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { } - @SuppressWarnings("unchecked") - private String determineLockId(final long accountId, final long templateId) { + static String determineLockId(final long accountId, final long templateId) { // TBD The lock scope may be too coarse grained. Deletes need to lock // the template across all zones where upload and download could // probably safely scoped to the zone ... - return join(asList("S3_TEMPLATE", accountId, templateId), "_"); + return join("_", "S3_TEMPLATE", accountId, templateId); } @@ -397,9 +395,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { throw new CloudRuntimeException(errMsg); } - final String installPath = join( - asList("template", "tmpl", accountId, - templateId), File.separator); + final String installPath = join(File.separator, "template", "tmpl", accountId, templateId); final VMTemplateHostVO tmpltHost = new VMTemplateHostVO( secondaryStorageHost.getId(), templateId, now(), 100, Status.DOWNLOADED, null, null, diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index e7fa5b2f1bc..9ddba8307b8 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -22,7 +22,6 @@ import static com.cloud.utils.S3Utils.putDirectory; import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static java.lang.String.format; -import static java.util.Arrays.asList; import static org.apache.commons.lang.StringUtils.substringAfterLast; import java.io.BufferedWriter; @@ -217,19 +216,16 @@ SecondaryStorageResource { } } - @SuppressWarnings("unchecked") - private String determineS3TemplateDirectory(final Long accountId, + static String determineS3TemplateDirectory(final Long accountId, final Long templateId) { - return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId), - S3Utils.SEPARATOR); + return join(S3Utils.SEPARATOR, TEMPLATE_ROOT_DIR, accountId, templateId); } - @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, final Long accountId, final Long templateId) { - return join( - asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId, - templateId), File.separator); + return join(File.separator, + getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId, + templateId); } private Answer execute( @@ -405,10 +401,7 @@ SecondaryStorageResource { s_logger.debug(String .format("Determining key using account id %1$s and template id %2$s", accountId, templateId)); - return join( - asList(determineS3TemplateDirectory( - accountId, templateId), file - .getName()), S3Utils.SEPARATOR); + return join(S3Utils.SEPARATOR, determineS3TemplateDirectory(accountId, templateId), file.getName()); } }); diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index b7273a14869..33a3ebde660 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -155,8 +155,8 @@ public final class S3Utils { try { tempFile = createTempFile( - join(asList(targetDirectory.getName(), currentTimeMillis(), - "part"), "-"), "tmp", targetDirectory); + join("-", targetDirectory.getName(), currentTimeMillis(), + "part"), "tmp", targetDirectory); tempFile.deleteOnExit(); if (LOGGER.isDebugEnabled()) { diff --git a/utils/src/com/cloud/utils/StringUtils.java b/utils/src/com/cloud/utils/StringUtils.java index 14ff4b1ae94..359b169e1b2 100644 --- a/utils/src/com/cloud/utils/StringUtils.java +++ b/utils/src/com/cloud/utils/StringUtils.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.utils; -import static java.util.Arrays.asList; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -25,8 +23,6 @@ import java.util.regex.Pattern; import org.owasp.esapi.StringUtilities; -// StringUtils exists in Apache Commons Lang, but rather than import the entire JAR to our system, for now -// just implement the method needed public class StringUtils { private static final char[] hexChar = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' @@ -50,7 +46,7 @@ public class StringUtils { public static String join(final String delimiter, final Object... components) { - return join(asList(components), delimiter); + return org.apache.commons.lang.StringUtils.join(components, delimiter); } /** diff --git a/utils/test/com/cloud/utils/StringUtilsTest.java b/utils/test/com/cloud/utils/StringUtilsTest.java index 3c162c75c02..796efbaacd7 100644 --- a/utils/test/com/cloud/utils/StringUtilsTest.java +++ b/utils/test/com/cloud/utils/StringUtilsTest.java @@ -103,4 +103,9 @@ public class StringUtilsTest { assertEquals(result, expected); } + @Test + public void testJoin() { + assertEquals("a-b-c", StringUtils.join("-", "a", "b", "c")); + assertEquals("", StringUtils.join("-")); + } } From 202cd1529054fe60acce0cce54686268797b65bd Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sun, 16 Jun 2013 10:42:17 +0200 Subject: [PATCH 33/95] NPE fix - fixes an NPE in case the pool.scope = null - replaces null checks around toString with ObjectUtils.toString call Signed-off-by: Laszlo Hornyak --- .../cloud/api/query/dao/StoragePoolJoinDaoImpl.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java index 6d0cde1ac6b..f2b9525b2cc 100644 --- a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import com.cloud.capacity.Capacity; import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; +import org.apache.commons.lang.ObjectUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -79,17 +80,12 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase Date: Mon, 17 Jun 2013 11:25:22 -0700 Subject: [PATCH 34/95] Small fix to satisfy the xml validation requirements --- awsapi/web/web.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/awsapi/web/web.xml b/awsapi/web/web.xml index 7efe43d03f3..5ded12b342f 100644 --- a/awsapi/web/web.xml +++ b/awsapi/web/web.xml @@ -22,16 +22,17 @@ - - - org.springframework.web.context.ContextLoaderListener - + CloudBridge + contextConfigLocation classpath:applicationContext.xml - CloudBridge + + org.springframework.web.context.ContextLoaderListener + + EC2MainServlet EC2 Main Servlet From d4477ba8da60290d21afd58ce0901d12c85de3a9 Mon Sep 17 00:00:00 2001 From: Shanker Balan Date: Mon, 11 Mar 2013 18:46:33 +0530 Subject: [PATCH 35/95] CLOUDSTACK-1623: Update documentation to check hosts entry for correct loopback interface setup to fix cloud-setup-databases issues during setup --- docs/en-US/management-server-install-db-local.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/en-US/management-server-install-db-local.xml b/docs/en-US/management-server-install-db-local.xml index 918cdc0a265..310327fcc75 100644 --- a/docs/en-US/management-server-install-db-local.xml +++ b/docs/en-US/management-server-install-db-local.xml @@ -143,6 +143,14 @@ binlog-format = 'ROW' -i <management_server_ip> When this script is finished, you should see a message like “Successfully initialized the database.” + + If the script is unable to connect to the MySQL database, check + the "localhost" loopback address in /etc/hosts. It should + be pointing to the IPv4 loopback address "127.0.0.1" and not the IPv6 loopback + address ::1. Alternatively, reconfigure MySQL to bind to the IPv6 loopback + interface. + + If you are running the KVM hypervisor on the same machine with the Management Server, From 9e7356c686d098185e2481338e4e4169dcb95813 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 14:58:51 -0700 Subject: [PATCH 36/95] CLOUDSTACK-3016: remove zonetype parameter from listSnapshots API. --- .../user/snapshot/ListSnapshotsCmd.java | 11 ++----- .../storage/snapshot/SnapshotManagerImpl.java | 32 ++++++------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java index e4ae76908e8..611b1277320 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java @@ -59,9 +59,6 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.VOLUME_ID, type=CommandType.UUID, entityType = VolumeResponse.class, description="the ID of the disk volume") private Long volumeId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list snapshots by zone id") private Long zoneId; @@ -90,14 +87,10 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { return volumeId; } - public String getZoneType() { - return zoneType; - } - public Long getZoneId() { return zoneId; - } - + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 02e34288766..c720169b2d3 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -58,7 +58,6 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.domain.dao.DomainDao; @@ -572,7 +571,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String keyword = cmd.getKeyword(); String snapshotTypeStr = cmd.getSnapshotType(); String intervalTypeStr = cmd.getIntervalType(); - String zoneType = cmd.getZoneType(); Map tags = cmd.getTags(); Long zoneId = cmd.getZoneId(); @@ -606,23 +604,17 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); - for (int count=0; count < tags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); - } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -640,14 +632,10 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - if (zoneId != null) { sc.setParameters("dataCenterId", zoneId); } - + if (name != null) { sc.setParameters("name", "%" + name + "%"); } From 9d0d02222b4083fe3cb9f5aac9deb5be12bea018 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 15:28:39 -0700 Subject: [PATCH 37/95] CLOUDSTACK-3016: remove zonetype parameter from listClusters API. --- .../admin/cluster/ListClustersCmd.java | 8 +--- .../cloud/server/ManagementServerImpl.java | 45 +++++-------------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java index f2dd3499b84..0417b187e38 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java @@ -70,9 +70,6 @@ public class ListClustersCmd extends BaseListCmd { @Parameter(name=ApiConstants.MANAGED_STATE, type=CommandType.STRING, description="whether this cluster is managed by cloudstack") private String managedState; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the clusters") private Boolean showCapacities; @@ -117,10 +114,7 @@ public class ListClustersCmd extends BaseListCmd { this.managedState = managedstate; } - public String getZoneType() { - return zoneType; - } - + public Boolean getShowCapacities() { return showCapacities; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 96c72e4a4e2..f09aa21fd73 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -996,67 +996,46 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public Pair, Integer> searchForClusters(ListClustersCmd cmd) { - Object id = cmd.getId(); + Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchCriteria sc = _clusterDao.createSearchCriteria(); + + Object id = cmd.getId(); Object name = cmd.getClusterName(); Object podId = cmd.getPodId(); Long zoneId = cmd.getZoneId(); Object hypervisorType = cmd.getHypervisorType(); Object clusterType = cmd.getClusterType(); Object allocationState = cmd.getAllocationState(); - String zoneType = cmd.getZoneType(); String keyword = cmd.getKeyword(); + zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), zoneId); - - Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - - SearchBuilder sb = _clusterDao.createSearchBuilder(); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ); - sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ); - sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ); - - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - - - SearchCriteria sc = sb.create(); if (id != null) { - sc.setParameters("id", id); + sc.addAnd("id", SearchCriteria.Op.EQ, id); } if (name != null) { - sc.setParameters("name", "%" + name + "%"); + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); } if (podId != null) { - sc.setParameters("podId", podId); + sc.addAnd("podId", SearchCriteria.Op.EQ, podId); } if (zoneId != null) { - sc.setParameters("dataCenterId", zoneId); + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } if (hypervisorType != null) { - sc.setParameters("hypervisorType", hypervisorType); + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisorType); } if (clusterType != null) { - sc.setParameters("clusterType", clusterType); + sc.addAnd("clusterType", SearchCriteria.Op.EQ, clusterType); } if (allocationState != null) { - sc.setParameters("allocationState", allocationState); - } - - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); + sc.addAnd("allocationState", SearchCriteria.Op.EQ, allocationState); } if (keyword != null) { From 56d390d54e07aff4aebf85960a89dd2d68f9143f Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 15:51:07 -0700 Subject: [PATCH 38/95] CLOUDSTACK-3016: remove zonetype parameter from listPods API. --- .../api/command/admin/pod/ListPodsByCmd.java | 7 ---- .../cloud/server/ManagementServerImpl.java | 32 +++++-------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java b/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java index db233ae441e..3dace4244ae 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java @@ -55,9 +55,6 @@ public class ListPodsByCmd extends BaseListCmd { @Parameter(name=ApiConstants.ALLOCATION_STATE, type=CommandType.STRING, description="list pods by allocation state") private String allocationState; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the pods") private Boolean showCapacities; @@ -81,10 +78,6 @@ public class ListPodsByCmd extends BaseListCmd { return allocationState; } - public String getZoneType() { - return zoneType; - } - public Boolean getShowCapacities() { return showCapacities; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index f09aa21fd73..2099d2f6432 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1448,29 +1448,17 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public Pair, Integer> searchForPods(ListPodsByCmd cmd) { + Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchCriteria sc = _hostPodDao.createSearchCriteria(); + String podName = cmd.getPodName(); Long id = cmd.getId(); Long zoneId = cmd.getZoneId(); Object keyword = cmd.getKeyword(); Object allocationState = cmd.getAllocationState(); - String zoneType = cmd.getZoneType(); + zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), zoneId); - - Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchBuilder sb = _hostPodDao.createSearchBuilder(); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ); - - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - - SearchCriteria sc = sb.create(); if (keyword != null) { SearchCriteria ssc = _hostPodDao.createSearchCriteria(); ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); @@ -1480,23 +1468,19 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } if (id != null) { - sc.setParameters("id", id); + sc.addAnd("id", SearchCriteria.Op.EQ, id); } if (podName != null) { - sc.setParameters("name", "%" + podName + "%"); + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + podName + "%"); } if (zoneId != null) { - sc.setParameters("dataCenterId", zoneId); + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } if (allocationState != null) { - sc.setParameters("allocationState", allocationState); - } - - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); + sc.addAnd("allocationState", SearchCriteria.Op.EQ, allocationState); } Pair, Integer> result = _hostPodDao.searchAndCount(sc, searchFilter); From 4c26dd6ae5663e75d5303a977e786a2d920ec267 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 17 Jun 2013 15:41:05 -0700 Subject: [PATCH 39/95] CLOUDSTACK-2956:createStoragePools API should ignore passed clusterId and podId parameters in creating zone scoped primary storage --- server/src/com/cloud/storage/StorageManagerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index d38b35ea47c..655eaeab2b1 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -777,6 +777,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C HypervisorType hypervisorType = HypervisorType.KVM; if (scopeType == ScopeType.ZONE) { + // ignore passed clusterId and podId + clusterId = null; + podId = null; String hypervisor = cmd.getHypervisor(); if (hypervisor != null) { try { From cb35ec6f4d640d8864c4c0b0e8f52750d7f00ca9 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 15:57:20 -0700 Subject: [PATCH 40/95] CLOUDSTACK-3016: remove zonetype parameter from listSystemVMs API. --- .../api/command/admin/systemvm/ListSystemVMsCmd.java | 7 ------- server/src/com/cloud/server/ManagementServerImpl.java | 11 ----------- 2 files changed, 18 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java index b5a0f3fdd4d..f230a20d513 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java @@ -74,9 +74,6 @@ public class ListSystemVMsCmd extends BaseListCmd { description="the storage ID where vm's volumes belong to", since="3.0.1") private Long storageId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -113,10 +110,6 @@ public class ListSystemVMsCmd extends BaseListCmd { return storageId; } - public String getZoneType() { - return zoneType; - } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 2099d2f6432..5a332b4abb4 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3078,7 +3078,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public Pair, Integer> searchForSystemVm(ListSystemVMsCmd cmd) { String type = cmd.getSystemVmType(); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); - String zoneType = cmd.getZoneType(); Long id = cmd.getId(); String name = cmd.getSystemVmName(); String state = cmd.getState(); @@ -3105,12 +3104,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); } - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - SearchCriteria sc = sb.create(); if (keyword != null) { @@ -3151,10 +3144,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.setJoinParameters("volumeSearch", "poolId", storageId); } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - Pair, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } From 880029844b7cd63a59e75e7ce0285716a34f1934 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 16:08:38 -0700 Subject: [PATCH 41/95] CLOUDSTACK-3016: remove zonetype parameter from listTemplates, listIsos API. --- .../api/command/user/iso/ListIsosCmd.java | 7 ------- .../user/template/ListTemplatesCmd.java | 8 ------- .../com/cloud/storage/dao/VMTemplateDao.java | 2 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 21 ++++++------------- .../cloud/server/ManagementServerImpl.java | 12 +++++------ 5 files changed, 13 insertions(+), 37 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index f872c120074..3219601156e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -78,9 +78,6 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { description="the ID of the zone") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,10 +115,6 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public boolean listInReadyState() { Account account = UserContext.current().getCaller(); // It is account specific if account is admin type and domainId and accountName are not null diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index f0fc24153f6..aeb76f507f3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -68,10 +68,6 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, description="list templates by zoneId") private Long zoneId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -96,10 +92,6 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public boolean listInReadyState() { Account account = UserContext.current().getCaller(); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java index 852075792df..7c66dd4b46b 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -56,7 +56,7 @@ public interface VMTemplateDao extends GenericDao, StateDao< public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, - ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, String zoneType); + ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 25ae933740d..d45ef73168b 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -521,7 +521,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List permittedAccounts, - Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, String zoneType) { + Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { StringBuilder builder = new StringBuilder(); if (!permittedAccounts.isEmpty()) { for (Account permittedAccount : permittedAccounts) { @@ -565,12 +565,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - - if (zoneType != null) { - dataCenterJoin = " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)"; - dataCenterJoin += " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; - } - + if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){ lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } @@ -697,7 +692,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, - onlyReady, showDomr, zoneType) + groupByClause + getOrderByLimit(pageSize, startIndex); + onlyReady, showDomr) + groupByClause + getOrderByLimit(pageSize, startIndex); pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); @@ -758,7 +753,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return templateZonePairList; } - private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr, String zoneType) { + private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr) { String sql = ""; if (keyword != null) { sql += " t.name LIKE \"%" + keyword + "%\" AND"; @@ -788,15 +783,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sql += " AND h.data_center_id = " +zoneId; } }else if (zoneId != null){ - sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; + sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; }else{ sql += " AND tzr.removed is null "; } - - if (zoneType != null){ - sql += " AND dc.networktype = '" + zoneType + "'"; - } - + if (!showDomr){ sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 5a332b4abb4..dea761df5da 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1719,7 +1719,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, - listProjectResourcesCriteria, tags, cmd.getZoneType()); + listProjectResourcesCriteria, tags); } @Override @@ -1752,12 +1752,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); return listTemplates(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), - cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, cmd.getZoneType()); + cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); } private Set> listTemplates(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, - List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, String zoneType) { + List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { VMTemplateVO template = null; if (templateId != null) { @@ -1798,7 +1798,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, tags); Set> templateZonePairSet2 = new HashSet>(); templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, - startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); + startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags); for (Pair tmpltPair : templateZonePairSet2) { if (!templateZonePairSet.contains(new Pair(tmpltPair.first(), -1L))) { @@ -1822,7 +1822,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Set> templateZonePairSet2 = new HashSet>(); templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, - permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); + permittedAccounts, caller, listProjectResourcesCriteria, tags); for (Pair tmpltPair : templateZonePairSet2) { if (!templateZonePairSet.contains(new Pair(tmpltPair.first(), -1L))) { @@ -1840,7 +1840,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } else { if (template == null) { templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, - startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); + startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags); } else { // if template is not public, perform permission check here if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { From 5d0a1cee13fb3006f3e35cd221e553587ea20ce2 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 17 Jun 2013 16:10:12 -0700 Subject: [PATCH 42/95] CLOUDSTACK-2883: create default network offering with internal lb support (if doesn't exist already) --- .../com/cloud/offering/NetworkOffering.java | 4 +- .../cloud/offerings/NetworkOfferingVO.java | 4 ++ .../ConfigurationManagerImpl.java | 3 +- .../com/cloud/network/NetworkManagerImpl.java | 65 +++++++++++++------ .../cloud/server/ConfigurationServerImpl.java | 25 +++++++ 5 files changed, 78 insertions(+), 23 deletions(-) diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 72e2a2bbbab..5f522ebff6a 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.offering; -import java.util.Map; - import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -61,6 +59,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering"; public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks"; public final static String DefaultIsolatedNetworkOfferingForVpcNetworksNoLB = "DefaultIsolatedNetworkOfferingForVpcNetworksNoLB"; + public final static String DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB = "DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB"; + /** * @return name for the network offering. diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index 3ae0bf38b0b..fae315b01a0 100755 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -414,4 +414,8 @@ public class NetworkOfferingVO implements NetworkOffering { return publicLb; } + public void setInternalLb(boolean internalLb) { + this.internalLb = internalLb; + } + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 12164a26694..6dac26c6954 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -39,7 +39,6 @@ import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; -import com.cloud.utils.Pair; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.api.ApiConstants.LDAPParams; import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; @@ -125,7 +124,6 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.MissingParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; @@ -193,6 +191,7 @@ import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.crypt.DBEncryptionUtil; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index f5633357e56..274e79468e2 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1239,9 +1239,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600); - - - // populate providers Map> defaultSharedNetworkOfferingProviders = new HashMap>(); Set defaultProviders = new HashSet(); @@ -1252,6 +1249,15 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders); Map> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; + defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders); Map> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap>(); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); @@ -1294,9 +1300,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L Transaction txn = Transaction.currentTxn(); txn.start(); - // diff between offering #1 and #2 - securityGroup is enabled for the first, and disabled for the third NetworkOfferingVO offering = null; + //#1 - quick cloud network offering if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, @@ -1306,6 +1312,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + + //#2 - SG enabled network offering if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, @@ -1316,36 +1324,26 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#3 - shared network offering with no SG service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + - Map> defaultINetworkOfferingProvidersForVpcNetwork = new HashMap>(); - defaultProviders.clear(); - defaultProviders.add(Network.Provider.VPCVirtualRouter); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dhcp, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dns, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.UserData, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Firewall, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Gateway, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Lb, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.SourceNat, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.StaticNat, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.PortForwarding, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Vpn, defaultProviders); - + //#4 - default isolated offering with Source nat service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, - null, false, Availability.Required, null, defaultINetworkOfferingProvidersForVpcNetwork, + null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + //#5 - default vpc offering with LB service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, @@ -1355,6 +1353,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#6 - default vpc offering with no LB service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) { //remove LB service defaultVPCOffProviders.remove(Service.Lb); @@ -1366,6 +1365,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#7 - isolated offering with source nat disabled if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, @@ -1374,6 +1374,33 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + + //#8 - network offering with internal lb service + Map> internalLbOffProviders = + new HashMap>(); + Set defaultVpcProvider = new HashSet(); + defaultVpcProvider.add(Network.Provider.VPCVirtualRouter); + + Set defaultInternalLbProvider = new HashSet(); + defaultInternalLbProvider.add(Network.Provider.InternalLbVm); + + internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider); + internalLbOffProviders.put(Service.Dns, defaultVpcProvider); + internalLbOffProviders.put(Service.UserData, defaultVpcProvider); + internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider); + internalLbOffProviders.put(Service.Gateway, defaultVpcProvider); + internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider); + internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider); + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, + null, false, Availability.Optional, null, internalLbOffProviders, + true, Network.GuestType.Isolated, false, null, false, null, false, false, null); + offering.setState(NetworkOffering.State.Enabled); + offering.setInternalLb(true); + _networkOfferingDao.update(offering.getId(), offering); + } Map> netscalerServiceProviders = new HashMap>(); Set vrProvider = new HashSet(); diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index d334d7efb53..510455b5213 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -1151,8 +1151,33 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } + + //offering #8 - network offering with internal lb service + NetworkOfferingVO internalLbOff = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated Vpc networks with Internal LB support", + TrafficType.Guest, + false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, true, false); + internalLbOff.setState(NetworkOffering.State.Enabled); + internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff); + Map internalLbOffProviders = new HashMap(); + internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm); + internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + + for (Service service : internalLbOffProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (internalLbOff.getId(), service, internalLbOffProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } txn.commit(); } From 3e852cc29b428f3e5454d7d415174758f9da0602 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 16:25:25 -0700 Subject: [PATCH 43/95] CLOUDSTACK-3016: remove zonetype parameter from listNetworks API. --- .../command/user/network/ListNetworksCmd.java | 7 ------ .../com/cloud/network/NetworkServiceImpl.java | 25 ++++++++----------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java index d25e2c05597..afce0926e4d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java @@ -48,9 +48,6 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { description="the Zone ID of the network") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="the type of the network. Supported values are: Isolated and Shared") private String guestIpType; @@ -99,10 +96,6 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public String getGuestIpType() { return guestIpType; } diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index f026dbc2a32..aace68d9642 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1355,7 +1355,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Long id = cmd.getId(); String keyword = cmd.getKeyword(); Long zoneId = cmd.getZoneId(); - String zoneType = cmd.getZoneType(); Account caller = UserContext.current().getCaller(); Long domainId = cmd.getDomainId(); String accountName = cmd.getAccountName(); @@ -1503,40 +1502,40 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!permittedAccounts.isEmpty()) { //get account level networks networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, permittedAccounts)); //get domain level networks if (domainId != null) { networksToReturn .addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, domainId, false)); } } else { //add account specific networks networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); //add domain specific networks of domain + parent domains networksToReturn.addAll(listDomainSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); //add networks of subdomains if (domainId == null) { networksToReturn .addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, caller.getDomainId(), true)); } } } else { networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, - guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter); } @@ -1581,7 +1580,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags, String zoneType) { + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags) { SearchCriteria sc = sb.create(); @@ -1603,10 +1602,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } - if(zoneType != null) { - sc.setJoinParameters("zoneSearch", "networkType", zoneType); - } - if (guestIpType != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType); } From fea9a0ed1243f344800acad04493b1708c0ae39f Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 17 Jun 2013 16:39:45 -0700 Subject: [PATCH 44/95] CLOUDSTACK-3016: remove zonetype parameter from listSnapshots API. --- .../cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java index 611b1277320..8859ba53c53 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java @@ -63,6 +63,7 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list snapshots by zone id") private Long zoneId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// From fb31a39efe7d93a67c7b8c141f434b938a491222 Mon Sep 17 00:00:00 2001 From: Prachi Damle Date: Mon, 17 Jun 2013 16:58:42 -0700 Subject: [PATCH 45/95] CLOUDSTACK-2900: Ubuntu 13.04 - Migrate Virtual Router fail - Unable to find the VM by id= Changes: - Have to search the vm_instance table to find the instance --- server/src/com/cloud/vm/UserVmManagerImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 44a7d0668b2..e8ea0242e11 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3804,7 +3804,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use "No permission to migrate VM, Only Root Admin can migrate a VM!"); } - UserVmVO vm = _vmDao.findById(vmId); + VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { throw new InvalidParameterValueException( "Unable to find the VM by id=" + vmId); @@ -3895,7 +3895,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use + " already has max Running VMs(count includes system VMs), cannot migrate to this host"); } - collectVmDiskStatistics(vm); + UserVmVO uservm = _vmDao.findById(vmId); + if (uservm != null) { + collectVmDiskStatistics(uservm); + } VMInstanceVO migratedVm = _itMgr.migrate(vm, srcHostId, dest); return migratedVm; } From 85ed2160876826fa28088a716657f6c7bcbf84ec Mon Sep 17 00:00:00 2001 From: rayeesn Date: Tue, 18 Jun 2013 11:02:08 +0530 Subject: [PATCH 46/95] Removed junk characters from test_netscaler_lb.py Signed-off-by: Prasanna Santhanam --- test/integration/component/test_netscaler_lb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py index b4e6c30497f..9d06275f26c 100644 --- a/test/integration/component/test_netscaler_lb.py +++ b/test/integration/component/test_netscaler_lb.py @@ -1085,7 +1085,7 @@ class TestAddMultipleVmsLb(cloudstackTestCase): # 3. Acquire Ip address and create LB rule on it. Add multiple VMs to # this rule. LB rule should be # In Netscaler: For every Vm added to the LB rule: - # 1. A server and service instance is created using guest VM’s IP and + # 1. A server and service instance is created using guest VMs IP and # port number on the Netscaler LB device, # 2. This service is bound to lb virtual server corresponding to lb # rule. From 93938ca716f85c24f2d9fb07c5856055f0061415 Mon Sep 17 00:00:00 2001 From: Dave Brosius Date: Wed, 22 May 2013 02:06:00 -0400 Subject: [PATCH 47/95] remove dead allocations Signed-off-by: Dave Brosius Signed-off-by: Prasanna Santhanam --- .../api/command/admin/host/FindHostsForMigrationCmd.java | 3 +-- .../apache/cloudstack/api/command/admin/host/ListHostsCmd.java | 3 +-- .../api/command/admin/region/ListPortableIpRangesCmd.java | 3 +-- .../apache/cloudstack/api/command/user/iso/ListIsosCmd.java | 3 +-- .../cloudstack/api/command/user/template/ListTemplatesCmd.java | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java index b2d77b85dd2..e902e650332 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java @@ -70,13 +70,12 @@ public class FindHostsForMigrationCmd extends BaseListCmd { public void execute() { ListResponse response = null; Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Map hostsRequiringStorageMotion; Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); hostsRequiringStorageMotion = hostsForMigration.third(); response = new ListResponse(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java index eaaec3091a7..1e378fae464 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java @@ -171,11 +171,10 @@ public class ListHostsCmd extends BaseListCmd { response = _queryService.searchForServers(this); } else { Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); response = new ListResponse(); List hostResponses = new ArrayList(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java index 75bcce00acf..1f77c2c5164 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java @@ -81,9 +81,8 @@ public class ListPortableIpRangesCmd extends BaseListCmd { public void execute(){ ListResponse response = new ListResponse(); List responses = new ArrayList(); - List portableIpRanges = new ArrayList(); - portableIpRanges = _configService.listPortableIpRanges(this); + List portableIpRanges = _configService.listPortableIpRanges(this); if (portableIpRanges != null && !portableIpRanges.isEmpty()) { for (PortableIpRange range : portableIpRanges) { PortableIpRangeResponse rangeResponse = _responseGenerator.createPortableIPRangeResponse(range); diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 3219601156e..9e6abec74e2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -153,8 +153,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { List templateResponses = new ArrayList(); for (Pair iso : isoZonePairSet) { - List responses = new ArrayList(); - responses = _responseGenerator.createIsoResponses(iso.first(), iso.second(), listInReadyState()); + List responses = _responseGenerator.createIsoResponses(iso.first(), iso.second(), listInReadyState()); templateResponses.addAll(responses); } response.setResponses(templateResponses); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index aeb76f507f3..dc94d676661 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -125,8 +125,7 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { List templateResponses = new ArrayList(); for (Pair template : templateZonePairSet) { - List responses = new ArrayList(); - responses = _responseGenerator.createTemplateResponses(template.first().longValue(), template.second(), listInReadyState()); + List responses = _responseGenerator.createTemplateResponses(template.first().longValue(), template.second(), listInReadyState()); templateResponses.addAll(responses); } From 76520e807f2595818baaab383e71dbcf3708e94d Mon Sep 17 00:00:00 2001 From: rayeesn Date: Mon, 17 Jun 2013 07:22:00 -0700 Subject: [PATCH 48/95] import tag missing from test_shared_networks.py Signed-off-by: Prasanna Santhanam --- test/integration/component/test_shared_networks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/component/test_shared_networks.py b/test/integration/component/test_shared_networks.py index cb2b55f705a..6bcfbfdfb39 100644 --- a/test/integration/component/test_shared_networks.py +++ b/test/integration/component/test_shared_networks.py @@ -19,6 +19,7 @@ """ #Import Local Modules import marvin +from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * From 8801205fcf5c0fa8553e41d9730828134a16a7fd Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 18 Jun 2013 12:45:39 +0530 Subject: [PATCH 49/95] CLOUDSTACK-2882: Correct the secondary disk device on KVM On kvm the disk device serial order is /dev/vda|vdb|vdc and so on. This also fixes CLOUDSTACK-3018 and removes the redundant test in blocker bugs. The snapshot related tests are now include in snapshots suite. Signed-off-by: Prasanna Santhanam --- .../component/test_blocker_bugs.py | 303 ------------------ test/integration/component/test_snapshots.py | 247 ++++++++------ 2 files changed, 150 insertions(+), 400 deletions(-) diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py index d099bf1a448..1f7ac97afb3 100644 --- a/test/integration/component/test_blocker_bugs.py +++ b/test/integration/component/test_blocker_bugs.py @@ -68,11 +68,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, # in GBs - "diskdevice": "/dev/xvdb", # Data Disk - }, "templates": { "displaytext": 'Template from snapshot', "name": 'Template from snapshot', @@ -86,13 +81,6 @@ class Services: "isextractable": True, "passwordenabled": True, }, - "paths": { - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - }, "static_nat": { "startport": 22, "endport": 22, @@ -104,297 +92,6 @@ class Services: } -class TestSnapshots(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services['mode'] = cls.zone.networktype - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["zoneid"] = cls.zone.id - - cls.services["template"] = cls.template.id - cls.services["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags = ["advanced", "advancedns"]) - def test_01_volume_from_snapshot(self): - """TS_BUG_001-Test Creating snapshot from volume having spaces in name(KVM) - """ - - - # Validate the following - #1. Create a virtual machine and data volume - #2. Attach data volume to VM - #3. Login to machine; create temp/test directories on data volume - #4. Snapshot the Volume - #5. Create another Volume from snapshot - #6. Mount/Attach volume to another server - #7. Compare data - - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume with ID: %s" % volume.id) - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - self.debug("Attach volume: %s to VM: %s" % - (volume.id, self.virtual_machine.id)) - try: - ssh_client = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH failed for VM: %s" % - self.virtual_machine.ipaddress) - - self.debug("Formatting volume: %s to ext3" % volume.id) - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["volume"]["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - ), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - list_volume_response = Volume.list( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volume response for valid data" - ) - volume_response = list_volume_response[0] - #Create snapshot from attached volume - snapshot = Snapshot.create( - self.apiclient, - volume_response.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.debug("Created snapshot: %s" % snapshot.id) - #Create volume from snapshot - volume_from_snapshot = Volume.create_from_snapshot( - self.apiclient, - snapshot.id, - self.services["volume"], - account=self.account.name, - domainid=self.account.domainid - ) - self.debug("Created Volume: %s from Snapshot: %s" % ( - volume_from_snapshot.id, - snapshot.id)) - volumes = Volume.list( - self.apiclient, - id=volume_from_snapshot.id - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(volumes), - None, - "Check Volume list Length" - ) - self.assertEqual( - volumes[0].id, - volume_from_snapshot.id, - "Check Volume in the List Volumes" - ) - #Attaching volume to new VM - new_virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - mode=self.services["mode"] - ) - self.debug("Deployed new VM for account: %s" % self.account.name) - self.cleanup.append(new_virtual_machine) - - self.debug("Attaching volume: %s to VM: %s" % ( - volume_from_snapshot.id, - new_virtual_machine.id - )) - - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume_from_snapshot.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) - - try: - #Login to VM to verify test directories and files - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - ] - - for c in cmds: - self.debug("Command: %s" % c) - ssh.execute(c) - - returned_data_0 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - )) - returned_data_1 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - )) - except Exception as e: - self.fail("SSH access failed for VM: %s" % - new_virtual_machine.ipaddress) - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - return - - class TestTemplate(cloudstackTestCase): def setUp(self): diff --git a/test/integration/component/test_snapshots.py b/test/integration/component/test_snapshots.py index 014b55afcc1..708a8b29996 100644 --- a/test/integration/component/test_snapshots.py +++ b/test/integration/component/test_snapshots.py @@ -108,6 +108,18 @@ class Services: "ostype": "CentOS 5.3 (64-bit)", "templatefilter": 'self', }, + "volume": { + "diskname": "APP Data Volume", + "size": 1, # in GBs + "diskdevice": "/dev/xvdb", # Data Disk + }, + "paths": { + "mount_dir": "/mnt/tmp", + "sub_dir": "test", + "sub_lvl_dir1": "test1", + "sub_lvl_dir2": "test2", + "random_data": "random.data", + }, "diskdevice": "/dev/xvda", "diskname": "TestDiskServ", "size": 1, # GBs @@ -377,6 +389,11 @@ class TestSnapshots(cloudstackTestCase): cls.services["zoneid"] = cls.zone.id cls.services["diskoffering"] = cls.disk_offering.id + #determine device type from hypervisor + hosts = Host.list(cls.api_client, id=cls.virtual_machine.hostid) + if len(hosts) > 0 and hosts[0].hypervisor.lower() == "kvm": + cls.service["volume"]["diskdevice"] = "/dev/vdb" + # Create VMs, NAT Rules etc cls.account = Account.create( cls.api_client, @@ -583,81 +600,102 @@ class TestSnapshots(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke", "xen"]) - def test_03_volume_from_snapshot(self): - """Create volumes from snapshots + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + def test_01_volume_from_snapshot(self): + """Test Creating snapshot from volume having spaces in name(KVM) """ - #1. Login to machine; create temp/test directories on data volume - #2. Snapshot the Volume - #3. Create another Volume from snapshot - #4. Mount/Attach volume to another server - #5. Compare data + # Validate the following + #1. Create a virtual machine and data volume + #2. Attach data volume to VM + #3. Login to machine; create temp/test directories on data volume + #4. Snapshot the Volume + #5. Create another Volume from snapshot + #6. Mount/Attach volume to another server + #7. Compare data + random_data_0 = random_gen(100) random_data_1 = random_gen(100) + volume = Volume.create( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.disk_offering.id + ) + self.debug("Created volume with ID: %s" % volume.id) + self.virtual_machine.attach_volume( + self.apiclient, + volume + ) + self.debug("Attach volume: %s to VM: %s" % + (volume.id, self.virtual_machine.id)) + + try: ssh_client = self.virtual_machine.get_ssh_client() + except Exception as e: + self.fail("SSH failed for VM: %s" % + self.virtual_machine.ipaddress) - #Format partition using ext3 - format_volume_to_ext3( + self.debug("Formatting volume: %s to ext3" % volume.id) + #Format partition using ext3 + format_volume_to_ext3( ssh_client, - self.services["diskdevice"] + self.services["volume"]["diskdevice"] ) - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], + cmds = [ + "mkdir -p %s" % self.services["paths"]["mount_dir"], "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] + self.services["volume"]["diskdevice"], + self.services["paths"]["mount_dir"] ), "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["sub_lvl_dir2"] + ), "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), + random_data_0, + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["random_data"] + ), "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), + random_data_1, + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir2"], + self.services["paths"]["random_data"] + ), ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) # Unmount the Sec Storage cmds = [ - "umount %s" % (self.services["mount_dir"]), + "umount %s" % (self.services["paths"]["mount_dir"]), ] + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', listall=True ) + self.assertEqual( + isinstance(list_volume_response, list), + True, + "Check list volume response for valid data" + ) volume_response = list_volume_response[0] #Create snapshot from attached volume snapshot = Snapshot.create( @@ -666,81 +704,94 @@ class TestSnapshots(cloudstackTestCase): account=self.account.name, domainid=self.account.domainid ) - self.debug("Created Snapshot from volume: %s" % volume_response.id) - + self.debug("Created snapshot: %s" % snapshot.id) #Create volume from snapshot - self.debug("Creating volume from snapshot: %s" % snapshot.id) - volume = Volume.create_from_snapshot( + volume_from_snapshot = Volume.create_from_snapshot( self.apiclient, snapshot.id, - self.services, + self.services["volume"], account=self.account.name, domainid=self.account.domainid ) - - volumes = list_volumes( + self.debug("Created Volume: %s from Snapshot: %s" % ( + volume_from_snapshot.id, + snapshot.id)) + volumes = Volume.list( self.apiclient, - id=volume.id + id=volume_from_snapshot.id ) self.assertEqual( isinstance(volumes, list), True, "Check list response returns a valid list" ) + self.assertNotEqual( len(volumes), None, "Check Volume list Length" ) - self.assertEqual( volumes[0].id, - volume.id, + volume_from_snapshot.id, "Check Volume in the List Volumes" ) #Attaching volume to new VM - new_virtual_machine = self.virtual_machine_without_disk + new_virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server_without_disk"], + templateid=self.template.id, + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.services["mode"] + ) + self.debug("Deployed new VM for account: %s" % self.account.name) self.cleanup.append(new_virtual_machine) - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) + self.debug("Attaching volume: %s to VM: %s" % ( + volume_from_snapshot.id, + new_virtual_machine.id + )) + + self.new_virtual_machine.attach_volume( + self.apiclient, + volume_from_snapshot + ) try: #Login to VM to verify test directories and files ssh = new_virtual_machine.get_ssh_client() cmds = [ - "mkdir -p %s" % self.services["mount_dir"], + "mkdir -p %s" % self.services["paths"]["mount_dir"], "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] + self.services["volume"]["diskdevice"], + self.services["paths"]["mount_dir"] ), ] for c in cmds: - self.debug(c) - result = ssh.execute(c) - self.debug(result) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) + self.debug("Command: %s" % c) + ssh.execute(c) + returned_data_0 = ssh.execute( + "cat %s/%s/%s/%s" % ( + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["random_data"] + )) + returned_data_1 = ssh.execute( + "cat %s/%s/%s/%s" % ( + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir2"], + self.services["paths"]["random_data"] + )) except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) - + self.fail("SSH access failed for VM: %s" % + new_virtual_machine.ipaddress) #Verify returned data self.assertEqual( random_data_0, @@ -754,15 +805,11 @@ class TestSnapshots(cloudstackTestCase): ) # Unmount the Sec Storage cmds = [ - "umount %s" % (self.services["mount_dir"]), + "umount %s" % (self.services["paths"]["mount_dir"]), ] - try: - for c in cmds: - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) return @attr(speed = "slow") @@ -1182,6 +1229,7 @@ class TestSnapshots(cloudstackTestCase): new_virtual_machine.ipaddress) return + class TestCreateVMsnapshotTemplate(cloudstackTestCase): @classmethod @@ -1560,7 +1608,7 @@ class TestAccountSnapshotClean(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) def test_02_accountSnapshotClean(self): """Test snapshot cleanup after account deletion """ @@ -1852,6 +1900,11 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): cls.services["template"] = template.id + #determine device type from hypervisor + hosts = Host.list(cls.api_client, id=cls.virtual_machine.hostid) + if len(hosts) > 0 and hosts[0].hypervisor.lower() == "kvm": + cls.service["volume"]["diskdevice"] = "/dev/vdb" + # Create VMs, NAT Rules etc cls.account = Account.create( cls.api_client, @@ -1905,7 +1958,7 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "xen"]) + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) def test_03_snapshot_detachedDisk(self): """Test snapshot from detached disk """ @@ -1941,7 +1994,7 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): #Format partition using ext3 format_volume_to_ext3( ssh_client, - self.services["diskdevice"] + self.services["volume"]["diskdevice"] ) cmds = [ "mkdir -p %s" % self.services["mount_dir"], From 9e2eeb21ab8da66e50618838f225a4df4ad51309 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 18 Jun 2013 12:47:50 +0530 Subject: [PATCH 50/95] Remove invalid references to diskdevice from tests Signed-off-by: Prasanna Santhanam --- test/integration/component/test_explicit_dedication.py | 3 --- test/integration/component/test_implicit_planner.py | 3 --- test/integration/component/test_redundant_router.py | 7 ------- test/integration/component/test_storage_motion.py | 3 --- test/integration/component/test_volumes.py | 3 --- test/integration/smoke/test_nic.py | 3 --- test/integration/smoke/test_resource_detail.py | 3 --- test/integration/smoke/test_scale_vm.py | 3 --- test/integration/smoke/test_vm_life_cycle.py | 2 +- test/integration/smoke/test_volumes.py | 1 - 10 files changed, 1 insertion(+), 30 deletions(-) diff --git a/test/integration/component/test_explicit_dedication.py b/test/integration/component/test_explicit_dedication.py index 21a4904e71b..e1991ac5219 100644 --- a/test/integration/component/test_explicit_dedication.py +++ b/test/integration/component/test_explicit_dedication.py @@ -87,9 +87,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, "ostype": 'CentOS 5.3 (64-bit)' diff --git a/test/integration/component/test_implicit_planner.py b/test/integration/component/test_implicit_planner.py index ffcd248b462..854b48148c6 100644 --- a/test/integration/component/test_implicit_planner.py +++ b/test/integration/component/test_implicit_planner.py @@ -80,9 +80,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/component/test_redundant_router.py b/test/integration/component/test_redundant_router.py index a87818a4ccb..914b17496dc 100644 --- a/test/integration/component/test_redundant_router.py +++ b/test/integration/component/test_redundant_router.py @@ -65,13 +65,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, - # in GBs - "diskdevice": "/dev/xvdb", - # Data Disk - }, "static_nat": { "startport": 22, "endport": 22, diff --git a/test/integration/component/test_storage_motion.py b/test/integration/component/test_storage_motion.py index 0dcc7f8e8d1..eda77d1a629 100644 --- a/test/integration/component/test_storage_motion.py +++ b/test/integration/component/test_storage_motion.py @@ -79,9 +79,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py index 34a067930de..369cefcaf34 100644 --- a/test/integration/component/test_volumes.py +++ b/test/integration/component/test_volumes.py @@ -26,10 +26,7 @@ from marvin.integration.lib.base import * from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient #Import System modules -import os -import urllib import time -import tempfile class Services: diff --git a/test/integration/smoke/test_nic.py b/test/integration/smoke/test_nic.py index 8e8d3407dfb..0d43a920e97 100644 --- a/test/integration/smoke/test_nic.py +++ b/test/integration/smoke/test_nic.py @@ -122,9 +122,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_resource_detail.py b/test/integration/smoke/test_resource_detail.py index 1d5db3ae4e6..93bc2ffc1f1 100644 --- a/test/integration/smoke/test_resource_detail.py +++ b/test/integration/smoke/test_resource_detail.py @@ -91,9 +91,6 @@ class Services: "name": "xs", "passwordenabled": False, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index fa2418b7cd8..b23ddd1b2cd 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -85,9 +85,6 @@ class Services: "name": "xs", "passwordenabled": False, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index 9aaa13fcb57..a7283478879 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -739,7 +739,7 @@ class TestVMLifeCycle(cloudstackTestCase): self.debug("Found %s host" % hosts[0].hypervisor) if hosts[0].hypervisor.lower() == "kvm": - self.services["diskdevice"] = "/dev/vda" + self.services["diskdevice"] = "/dev/vdb" try: ssh_client = self.virtual_machine.get_ssh_client() diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 7039c6ffe66..4c4b78076e7 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -80,7 +80,6 @@ class Services: "privateport": 22, "publicport": 22, "protocol": 'TCP', - "diskdevice": "/dev/xvdb", "ostype": 'CentOS 5.5 (64-bit)', "sleep": 10, "timeout": 600, From 882220e802bb449081ad454251c856e1cd0d7fda Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 18 Jun 2013 10:02:55 +0200 Subject: [PATCH 51/95] CLOUDSTACK-1301: VM Disk I/O Throttling --- api/src/com/cloud/agent/api/to/VolumeTO.java | 37 ++++ api/src/com/cloud/offering/DiskOffering.java | 16 ++ api/src/com/cloud/vm/DiskProfile.java | 36 ++++ .../apache/cloudstack/api/ApiConstants.java | 4 + .../admin/offering/CreateDiskOfferingCmd.java | 28 +++ .../offering/CreateServiceOfferingCmd.java | 28 +++ .../api/response/DiskOfferingResponse.java | 28 +++ .../api/response/ServiceOfferingResponse.java | 28 +++ .../api/response/VolumeResponse.java | 44 +++++ .../classes/resources/messages.properties | 4 + .../cloud/agent/api/AttachVolumeCommand.java | 36 ++++ .../src/com/cloud/storage/DiskOfferingVO.java | 44 +++++ .../resource/LibvirtComputingResource.java | 31 ++- .../kvm/resource/LibvirtDomainXMLParser.java | 25 +++ .../hypervisor/kvm/resource/LibvirtVMDef.java | 48 +++++ .../query/dao/DiskOfferingJoinDaoImpl.java | 5 + .../query/dao/ServiceOfferingJoinDaoImpl.java | 4 + .../api/query/dao/VolumeJoinDaoImpl.java | 5 + .../api/query/vo/DiskOfferingJoinVO.java | 42 ++++ .../api/query/vo/ServiceOfferingJoinVO.java | 41 ++++ .../com/cloud/api/query/vo/VolumeJoinVO.java | 43 ++++ .../src/com/cloud/configuration/Config.java | 4 + .../configuration/ConfigurationManager.java | 14 +- .../ConfigurationManagerImpl.java | 33 +++- .../src/com/cloud/storage/StorageManager.java | 10 + .../com/cloud/storage/StorageManagerImpl.java | 65 ++++++ .../com/cloud/storage/VolumeManagerImpl.java | 67 ++++++- server/src/com/cloud/test/DatabaseConfig.java | 28 +++ .../vpc/MockConfigurationManagerImpl.java | 6 +- setup/db/db/schema-410to420.sql | 29 ++- ui/dictionary.jsp | 4 + ui/scripts/configuration.js | 185 +++++++++++++++++- 32 files changed, 1007 insertions(+), 15 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index 4cbe82b357b..cc0e8182390 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -37,6 +37,10 @@ public class VolumeTO implements InternalIdentity { private long deviceId; private String chainInfo; private String guestOsType; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; public VolumeTO(long id, Volume.Type type, StoragePoolType poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo) { this.id = id; @@ -133,4 +137,37 @@ public class VolumeTO implements InternalIdentity { public String toString() { return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString(); } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + } diff --git a/api/src/com/cloud/offering/DiskOffering.java b/api/src/com/cloud/offering/DiskOffering.java index dd77c70abd9..ae4528cc81a 100644 --- a/api/src/com/cloud/offering/DiskOffering.java +++ b/api/src/com/cloud/offering/DiskOffering.java @@ -52,4 +52,20 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId boolean isCustomized(); void setDiskSize(long diskSize); + + void setBytesReadRate(Long bytesReadRate); + + Long getBytesReadRate(); + + void setBytesWriteRate(Long bytesWriteRate); + + Long getBytesWriteRate(); + + void setIopsReadRate(Long iopsReadRate); + + Long getIopsReadRate(); + + void setIopsWriteRate(Long iopsWriteRate); + + Long getIopsWriteRate(); } diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index e3a3386d1e5..3d4c9e730f4 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -35,6 +35,10 @@ public class DiskProfile { private Long templateId; private long volumeId; private String path; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; private HypervisorType hyperType; @@ -154,4 +158,36 @@ public class DiskProfile { public void setSize(long size) { this.size = size; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index ab1402ccde9..1704ca3d132 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -31,6 +31,8 @@ public class ApiConstants { public static final String BOOTABLE = "bootable"; public static final String BIND_DN = "binddn"; public static final String BIND_PASSWORD = "bindpass"; + public static final String BYTES_READ_RATE = "bytesreadrate"; + public static final String BYTES_WRITE_RATE = "byteswriterate"; public static final String CATEGORY = "category"; public static final String CERTIFICATE = "certificate"; public static final String PRIVATE_KEY = "privatekey"; @@ -104,6 +106,8 @@ public class ApiConstants { public static final String INTERNAL_DNS1 = "internaldns1"; public static final String INTERNAL_DNS2 = "internaldns2"; public static final String INTERVAL_TYPE = "intervaltype"; + public static final String IOPS_READ_RATE = "iopsreadrate"; + public static final String IOPS_WRITE_RATE = "iopswriterate"; public static final String IP_ADDRESS = "ipaddress"; public static final String IP6_ADDRESS = "ip6address"; public static final String IP_ADDRESS_ID = "ipaddressid"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java index aa11599a69e..a2c5f77f583 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java @@ -62,6 +62,18 @@ public class CreateDiskOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the disk offering. Values are local and shared.") private String storageType = ServiceOffering.StorageType.shared.toString(); + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @Parameter(name=ApiConstants.DISPLAY_OFFERING, type=CommandType.BOOLEAN, description="an optional field, whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -93,6 +105,22 @@ public class CreateDiskOfferingCmd extends BaseCmd { return domainId; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public String getStorageType() { return storageType; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index 4c54a4e5ec6..decac29ae6b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -93,6 +93,18 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters") private Map details; + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -171,6 +183,22 @@ public class CreateServiceOfferingCmd extends BaseCmd { return params; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java index 377e66ec2b1..35cf21a3b17 100644 --- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java @@ -58,6 +58,18 @@ public class DiskOfferingResponse extends BaseResponse { @SerializedName("storagetype") @Param(description="the storage type for this disk offering") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @SerializedName("displayoffering") @Param(description="whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -149,4 +161,20 @@ public class DiskOfferingResponse extends BaseResponse { public void setStorageType(String storageType) { this.storageType = storageType; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 31533f87728..288f76b4463 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -87,6 +87,18 @@ public class ServiceOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.NETWORKRATE) @Param(description="data transfer rate in megabits per second allowed.") private Integer networkRate; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the service offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the service offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the service offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the service offering") + private Long iopsWriteRate; + @SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description="deployment strategy used to deploy VM.") private String deploymentPlanner; @@ -248,4 +260,20 @@ public class ServiceOfferingResponse extends BaseResponse { public void setVolatileVm(boolean isVolatile) { this.isVolatile = isVolatile; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index 21d7d1a449f..e3463bd24d5 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -110,6 +110,18 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "shared or local storage") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk volume") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk volume") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk volume") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk volume") + private Long iopsWriteRate; + @SerializedName(ApiConstants.HYPERVISOR) @Param(description = "Hypervisor the volume belongs to") private String hypervisor; @@ -258,6 +270,38 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.storageType = storageType; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; } diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 2b173596b73..a0a36c8dd65 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -466,6 +466,10 @@ label.disable.vpn=Disable VPN label.disabled=Disabled label.disabling.vpn.access=Disabling VPN Access label.disk.allocated=Disk Allocated +label.disk.bytes.read.rate=Disk Read Rate (BPS) +label.disk.bytes.write.rate=Disk Write Rate (BPS) +label.disk.iops.read.rate=Disk Read Rate (IOPS) +label.disk.iops.write.rate=Disk Write Rate (IOPS) label.disk.offering=Disk Offering label.disk.read.bytes=Disk Read (Bytes) label.disk.read.io=Disk Read (IO) diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java index 302b8f80af3..2658262a6cd 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -29,6 +29,10 @@ public class AttachVolumeCommand extends Command { String volumeName; Long deviceId; String chainInfo; + Long bytesReadRate; + Long bytesWriteRate; + Long iopsReadRate; + Long iopsWriteRate; protected AttachVolumeCommand() { } @@ -96,4 +100,36 @@ public class AttachVolumeCommand extends Command { public String getChainInfo() { return chainInfo; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index 909d7fe6325..44f9e8f7b1c 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -100,6 +100,18 @@ public class DiskOfferingVO implements DiskOffering { @Column(name="sort_key") int sortKey; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @Column(name="display_offering") boolean displayOffering; @@ -327,4 +339,36 @@ public class DiskOfferingVO implements DiskOffering { public void setDisplayOffering(boolean displayOffering) { this.displayOffering = displayOffering; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index f90edd863e5..7d90f6a5cc3 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -336,6 +336,8 @@ ServerResource { protected HypervisorType _hypervisorType; protected String _hypervisorURI; + protected long _hypervisorLibvirtVersion; + protected long _hypervisorQemuVersion; protected String _hypervisorPath; protected String _networkDirectSourceMode; protected String _networkDirectDevice; @@ -735,6 +737,8 @@ ServerResource { try { _hvVersion = conn.getVersion(); _hvVersion = (_hvVersion % 1000000) / 1000; + _hypervisorLibvirtVersion = conn.getLibVirVersion(); + _hypervisorQemuVersion = conn.getVersion(); } catch (LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -1411,6 +1415,10 @@ ServerResource { VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null); + volume.setBytesReadRate(dskch.getBytesReadRate()); + volume.setBytesWriteRate(dskch.getBytesWriteRate()); + volume.setIopsReadRate(dskch.getIopsReadRate()); + volume.setIopsWriteRate(dskch.getIopsWriteRate()); return new CreateAnswer(cmd, volume); } catch (CloudRuntimeException e) { s_logger.debug("Failed to create volume: " + e.toString()); @@ -2626,7 +2634,7 @@ ServerResource { cmd.getPoolUuid()); KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, - cmd.getDeviceId().intValue()); + cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate()); } catch (LibvirtException e) { return new AttachVolumeAnswer(cmd, e.toString()); } catch (InternalErrorException e) { @@ -3224,6 +3232,8 @@ ServerResource { } else { guest.setGuestType(GuestDef.guestType.KVM); vm.setHvsType(HypervisorType.KVM.toString().toLowerCase()); + vm.setLibvirtVersion(_hypervisorLibvirtVersion); + vm.setQemuVersion(_hypervisorQemuVersion); } guest.setGuestArch(vmTO.getArch()); guest.setMachineType("pc"); @@ -3497,6 +3507,15 @@ ServerResource { } + if ((volume.getBytesReadRate() != null) && (volume.getBytesReadRate() > 0)) + disk.setBytesReadRate(volume.getBytesReadRate()); + if ((volume.getBytesWriteRate() != null) && (volume.getBytesWriteRate() > 0)) + disk.setBytesWriteRate(volume.getBytesWriteRate()); + if ((volume.getIopsReadRate() != null) && (volume.getIopsReadRate() > 0)) + disk.setIopsReadRate(volume.getIopsReadRate()); + if ((volume.getIopsWriteRate() != null) && (volume.getIopsWriteRate() > 0)) + disk.setIopsWriteRate(volume.getIopsWriteRate()); + vm.getDevices().addDevice(disk); } @@ -3630,7 +3649,7 @@ ServerResource { protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, KVMPhysicalDisk attachingDisk, - int devId) throws LibvirtException, InternalErrorException { + int devId, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; @@ -3670,6 +3689,14 @@ ServerResource { diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO); } + if ((bytesReadRate != null) && (bytesReadRate > 0)) + diskdef.setBytesReadRate(bytesReadRate); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + diskdef.setBytesWriteRate(bytesWriteRate); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + diskdef.setIopsReadRate(iopsReadRate); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + diskdef.setIopsWriteRate(iopsWriteRate); } String xml = diskdef.toString(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index b8645e1664a..8514a5bd270 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -105,6 +105,31 @@ public class LibvirtDomainXMLParser { DiskDef.diskBus.valueOf(bus.toUpperCase())); } } + + NodeList iotune = disk.getElementsByTagName("iotune"); + if ((iotune != null) && (iotune.getLength() !=0)) { + String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0)); + if (bytesReadRateStr != null) { + Long bytesReadRate = Long.parseLong(bytesReadRateStr); + def.setBytesReadRate(bytesReadRate); + } + String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0)); + if (bytesWriteRateStr != null) { + Long bytesWriteRate = Long.parseLong(bytesWriteRateStr); + def.setBytesWriteRate(bytesWriteRate); + } + String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0)); + if (iopsReadRateStr != null) { + Long iopsReadRate = Long.parseLong(iopsReadRateStr); + def.setIopsReadRate(iopsReadRate); + } + String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0)); + if (iopsWriteRateStr != null) { + Long iopsWriteRate = Long.parseLong(iopsWriteRateStr); + def.setIopsWriteRate(iopsWriteRate); + } + } + diskDefs.add(def); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index e91e3477b0b..0aa0e148dd1 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -22,8 +22,12 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import com.cloud.utils.script.Script; + public class LibvirtVMDef { private String _hvsType; + private static long _libvirtVersion; + private static long _qemuVersion; private String _domName; private String _domUUID; private String _desc; @@ -439,6 +443,10 @@ public class LibvirtVMDef { private boolean _readonly = false; private boolean _shareable = false; private boolean _deferAttach = false; + private Long _bytesReadRate; + private Long _bytesWriteRate; + private Long _iopsReadRate; + private Long _iopsWriteRate; public void setDeviceType(deviceType deviceType) { _deviceType = deviceType; @@ -584,6 +592,22 @@ public class LibvirtVMDef { return suffix - 'a'; } + public void setBytesReadRate(Long bytesReadRate) { + _bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + _bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + _iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + _iopsWriteRate = iopsWriteRate; + } + @Override public String toString() { StringBuilder diskBuilder = new StringBuilder(); @@ -627,6 +651,22 @@ public class LibvirtVMDef { diskBuilder.append(" bus='" + _bus + "'"); } diskBuilder.append("/>\n"); + + if ((_deviceType != deviceType.CDROM) && (_libvirtVersion >= 9008) && (_qemuVersion >= 1001000) + && (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + || ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) )) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0 + diskBuilder.append("\n"); + if ((_bytesReadRate != null) && (_bytesReadRate > 0)) + diskBuilder.append("" + _bytesReadRate + "\n"); + if ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + diskBuilder.append("" + _bytesWriteRate + "\n"); + if ((_iopsReadRate != null) && (_iopsReadRate > 0)) + diskBuilder.append("" + _iopsReadRate + "\n"); + if ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) + diskBuilder.append("" + _iopsWriteRate + "\n"); + diskBuilder.append("\n"); + } + diskBuilder.append("\n"); return diskBuilder.toString(); } @@ -1012,6 +1052,14 @@ public class LibvirtVMDef { return _hvsType; } + public void setLibvirtVersion(long libvirtVersion) { + _libvirtVersion = libvirtVersion; + } + + public void setQemuVersion(long qemuVersion) { + _qemuVersion = qemuVersion; + } + public void setDomainName(String domainName) { _domName = domainName; } diff --git a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java index 283181f5245..7022ee60fbb 100644 --- a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java @@ -75,7 +75,12 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase implem } volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared .toString()); + volResponse.setBytesReadRate(volume.getBytesReadRate()); + volResponse.setBytesWriteRate(volume.getBytesReadRate()); + volResponse.setIopsReadRate(volume.getIopsWriteRate()); + volResponse.setIopsWriteRate(volume.getIopsWriteRate()); + } Long poolId = volume.getPoolId(); String poolName = (poolId == null) ? "none" : volume.getPoolName(); diff --git a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java index 6d3cdcb7fef..2336a48ad14 100644 --- a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java +++ b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java @@ -64,6 +64,18 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, @Column(name="sort_key") int sortKey; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @Column(name="type") Type type; @@ -239,6 +251,36 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, this.type = type; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java index e87a1018bdd..05ff5f3f44a 100644 --- a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java @@ -90,6 +90,17 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit @Column(name="sort_key") int sortKey; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; @Column(name=GenericDao.CREATED_COLUMN) private Date created; @@ -329,5 +340,35 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit this.volatileVm = volatileVm; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index 6ef8c912efe..735cf9ad08f 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -184,6 +184,18 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="use_local_storage") private boolean useLocalStorage; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @Column(name="pool_id") private long poolId; @@ -742,6 +754,37 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } public long getPoolId() { return poolId; diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 5432ab6dd4e..f6fa97418bd 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -239,6 +239,10 @@ public enum Config { VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null), VmTransitionWaitInterval("Advanced", ManagementServer.class, Integer.class, "vm.tranisition.wait.interval", "3600", "Time (in seconds) to wait before taking over a VM in transition state", null), VmDestroyForcestop("Advanced", ManagementServer.class, Boolean.class, "vm.destroy.forcestop", "false", "On destroy, force-stop takes this value ", null), + VmDiskThrottlingIopsReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_read_rate", "0", "Default disk I/O read rate in requests per second allowed in User vm's disk.", null), + VmDiskThrottlingIopsWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_write_rate", "0", "Default disk I/O writerate in requests per second allowed in User vm's disk.", null), + VmDiskThrottlingBytesReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_read_rate", "0", "Default disk I/O read rate in bytes per second allowed in User vm's disk.", null), + VmDiskThrottlingBytesWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_write_rate", "0", "Default disk I/O writerate in bytes per second allowed in User vm's disk.", null), ControlCidr("Advanced", ManagementServer.class, String.class, "control.cidr", "169.254.0.0/16", "Changes the cidr for the control network traffic. Defaults to using link local. Must be unique within pods", null), ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 8db037b24ff..93cadfa23a6 100755 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -81,10 +81,15 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param useVirtualNetwork * @param deploymentPlanner * @param details + * @param bytesReadRate + * @param bytesWriteRate + * @param iopsReadRate + * @param iopsWriteRate * @return ID */ ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, - boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details); + boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate); /** * Creates a new disk offering @@ -97,9 +102,14 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param isCustomized * @param localStorageRequired * @param isDisplayOfferingEnabled + * @param bytesReadRate + * @param bytesWriteRate + * @param iopsReadRate + * @param iopsWriteRate * @return newly created disk offering */ - DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled); + DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate); /** * Creates a new pod diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 6dac26c6954..e7e3f74e0ee 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2031,7 +2031,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return createServiceOffering(userId, cmd.getIsSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), - cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails()); + cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails(), + cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate()); } @Override @@ -2039,11 +2040,20 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_type, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, - Integer networkRate, String deploymentPlanner, Map details) { + Integer networkRate, String deploymentPlanner, Map details, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { tags = cleanupTags(tags); ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA, limitResourceUse, volatileVm, displayText, localStorageRequired, false, tags, isSystem, vm_type, domainId, hostTag, deploymentPlanner); + if ((bytesReadRate != null) && (bytesReadRate > 0)) + offering.setBytesReadRate(bytesReadRate); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + offering.setBytesWriteRate(bytesWriteRate); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + offering.setIopsReadRate(iopsReadRate); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + offering.setIopsWriteRate(iopsWriteRate); + if ((offering = _serviceOfferingDao.persist(offering)) != null) { if (details != null) { _serviceOfferingDetailsDao.persist(offering.getId(), details); @@ -2129,7 +2139,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering") - public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled) { + public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { long diskSize = 0;// special case for custom disk offerings if (numGibibytes != null && (numGibibytes <= 0)) { throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb."); @@ -2149,6 +2160,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, diskSize, tags, isCustomized); newDiskOffering.setUseLocalStorage(localStorageRequired); newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled); + + if (bytesReadRate != null && (bytesReadRate > 0)) + newDiskOffering.setBytesReadRate(bytesReadRate); + if (bytesWriteRate != null && (bytesWriteRate > 0)) + newDiskOffering.setBytesWriteRate(bytesWriteRate); + if (iopsReadRate != null && (iopsReadRate > 0)) + newDiskOffering.setIopsReadRate(iopsReadRate); + if (iopsWriteRate != null && (iopsWriteRate > 0)) + newDiskOffering.setIopsWriteRate(iopsWriteRate); + UserContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId()); DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering); if (offering != null) { @@ -2189,7 +2210,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled); + Long bytesReadRate = cmd.getBytesReadRate(); + Long bytesWriteRate = cmd.getBytesWriteRate(); + Long iopsReadRate = cmd.getIopsReadRate(); + Long iopsWriteRate = cmd.getIopsWriteRate(); + return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled, bytesReadRate, bytesWriteRate, iopsReadRate, iopsWriteRate); } @Override diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index d49a7f86e94..29c7ebcef00 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -35,6 +35,8 @@ import com.cloud.exception.ConnectionException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.Pair; import com.cloud.vm.DiskProfile; @@ -122,4 +124,12 @@ public interface StorageManager extends StorageService { DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws ConnectionException; BigDecimal getStorageOverProvisioningFactor(Long dcId); + + Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 655eaeab2b1..20b435c60dc 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -127,6 +127,7 @@ import com.cloud.resource.ResourceState; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Type; @@ -142,6 +143,7 @@ import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; @@ -1886,4 +1888,67 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return null; } + // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate + @Override + public Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getBytesReadRate() != null) && (offering.getBytesReadRate() > 0)) { + return offering.getBytesReadRate(); + } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) { + return diskOffering.getBytesReadRate(); + } else { + Long bytesReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesReadRate.key())); + if ((bytesReadRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return bytesReadRate; + } + } + return 0L; + } + + // get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate + @Override + public Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getBytesWriteRate() != null) && (offering.getBytesWriteRate() > 0)) { + return offering.getBytesWriteRate(); + } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) { + return diskOffering.getBytesWriteRate(); + } else { + Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key())); + if ((bytesWriteRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return bytesWriteRate; + } + } + return 0L; + } + + // get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate + @Override + public Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getIopsReadRate() != null) && (offering.getIopsReadRate() > 0)) { + return offering.getIopsReadRate(); + } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) { + return diskOffering.getIopsReadRate(); + } else { + Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key())); + if ((iopsReadRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return iopsReadRate; + } + } + return 0L; + } + + // get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate + @Override + public Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getIopsWriteRate() != null) && (offering.getIopsWriteRate() > 0)) { + return offering.getIopsWriteRate(); + } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) { + return diskOffering.getIopsWriteRate(); + } else { + Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key())); + if ((iopsWriteRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return iopsWriteRate; + } + } + return 0L; + } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 4297efb6e99..e5868d3d603 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -115,6 +115,7 @@ import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.StorageManager; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Event; import com.cloud.storage.Volume.Type; @@ -336,6 +337,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null); dskCh.setHyperType(dataDiskHyperType); + dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); + DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId); HostPodVO destPoolPod = _podDao.findById(destPoolPodId); @@ -511,6 +517,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { DataCenterVO dc = _dcDao.findById(volume.getDataCenterId()); DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType()); + dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); // Determine what pod to store the volume in while ((pod = _resourceMgr.findPod(null, null, dc, account.getId(), @@ -611,6 +621,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); dskCh.setHyperType(vm.getHypervisorType()); + dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); + // Find a suitable storage to create volume on StoragePool destPool = storageMgr.findStoragePool(dskCh, dc, pod, clusterId, null, vm, avoidPools); @@ -649,13 +664,21 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { dskCh = createDiskCharacteristics(volume, template, dc, offering); + dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering)); + dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering)); + dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering)); + dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering)); } else { dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); + dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); } dskCh.setHyperType(hyperType); - + final HashSet avoidPools = new HashSet( avoids); @@ -1546,6 +1569,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.getFolder(), volume.getPath(), volume.getName(), deviceId, volume.getChainInfo()); cmd.setPoolUuid(volumePool.getUuid()); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); + cmd.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + cmd.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + cmd.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + cmd.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); try { answer = (AttachVolumeAnswer) _agentMgr.send(hostId, cmd); @@ -1906,6 +1934,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { StoragePoolVO volumePool = _storagePoolDao.findById(volume .getPoolId()); cmd.setPoolUuid(volumePool.getUuid()); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); + cmd.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + cmd.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + cmd.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + cmd.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); // Collect vm disk statistics from host before stopping Vm _userVmMgr.collectVmDiskStatistics(vm); @@ -2233,7 +2266,21 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { for (VolumeVO vol : vols) { PrimaryDataStoreInfo pool = (PrimaryDataStoreInfo)this.dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary); - vm.addDisk(new VolumeTO(vol, pool)); + ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId()); + VolumeTO newVolume = new VolumeTO(vol, pool); + if (vol.getVolumeType() == Type.ROOT) { + newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering)); + newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering)); + newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering)); + newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering)); + } else { + newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); + } + vm.addDisk(newVolume); } if (vm.getType() == VirtualMachine.Type.User) { @@ -2463,7 +2510,21 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { pool = (StoragePool)dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary); vol = result.first(); } - vm.addDisk(new VolumeTO(vol, pool)); + ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId()); + VolumeTO newVolume = new VolumeTO(vol, pool); + if (vol.getVolumeType() == Type.ROOT) { + newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering)); + newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering)); + newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering)); + newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering)); + } else { + newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering)); + newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering)); + newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering)); + newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering)); + } + vm.addDisk(newVolume); } } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 70c81781959..ef0259d7c60 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -918,6 +918,20 @@ public class DatabaseConfig { } ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false); + + Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate")); + if ((bytesReadRate != null) && (bytesReadRate > 0)) + serviceOffering.setBytesReadRate(bytesReadRate); + Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate")); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + serviceOffering.setBytesWriteRate(bytesWriteRate); + Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate")); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + serviceOffering.setIopsReadRate(iopsReadRate); + Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate")); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + serviceOffering.setIopsWriteRate(iopsWriteRate); + ServiceOfferingDaoImpl dao = ComponentContext.inject(ServiceOfferingDaoImpl.class); try { dao.persist(serviceOffering); @@ -967,6 +981,20 @@ public class DatabaseConfig { } DiskOfferingVO diskOffering = new DiskOfferingVO(domainId, name, displayText, diskSpace , tags, false); diskOffering.setUseLocalStorage(local); + + Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate")); + if (bytesReadRate != null && (bytesReadRate > 0)) + diskOffering.setBytesReadRate(bytesReadRate); + Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate")); + if (bytesWriteRate != null && (bytesWriteRate > 0)) + diskOffering.setBytesWriteRate(bytesWriteRate); + Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate")); + if (iopsReadRate != null && (iopsReadRate > 0)) + diskOffering.setIopsReadRate(iopsReadRate); + Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate")); + if (iopsWriteRate != null && (iopsWriteRate > 0)) + diskOffering.setIopsWriteRate(iopsWriteRate); + DiskOfferingDaoImpl offering = ComponentContext.inject(DiskOfferingDaoImpl.class); try { offering.persist(diskOffering); diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java index 21b3590282d..6e3d187d598 100755 --- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -489,7 +489,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu */ @Override public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details) { + boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { // TODO Auto-generated method stub return null; } @@ -654,7 +655,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu * @see com.cloud.configuration.ConfigurationManager#createDiskOffering(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.String, boolean, boolean, boolean) */ @Override - public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled) { + public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { // TODO Auto-generated method stub return null; } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 272fc4276a6..bcdf2d986d5 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -290,6 +290,14 @@ ALTER TABLE `cloud`.`nics` ADD COLUMN `display_nic` tinyint(1) NOT NULL DEFAULT ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `display_offering` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should disk offering be displayed to the end user'; +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_read_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_write_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_read_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_write_rate` bigint(20); + CREATE TABLE `cloud`.`volume_details` ( `id` bigint unsigned NOT NULL auto_increment, `volume_id` bigint unsigned NOT NULL COMMENT 'volume id', @@ -762,6 +770,10 @@ CREATE VIEW `cloud`.`volume_view` AS disk_offering.display_text disk_offering_display_text, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, storage_pool.id pool_id, storage_pool.uuid pool_uuid, storage_pool.name pool_name, @@ -1070,6 +1082,10 @@ CREATE VIEW `cloud`.`service_offering_view` AS disk_offering.removed, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, service_offering.cpu, service_offering.speed, service_offering.ram_size, @@ -1376,6 +1392,10 @@ CREATE VIEW `cloud`.`disk_offering_view` AS disk_offering.removed, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, disk_offering.sort_key, disk_offering.type, disk_offering.display_offering, @@ -1616,6 +1636,10 @@ CREATE VIEW `cloud`.`volume_view` AS disk_offering.display_text disk_offering_display_text, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, storage_pool.id pool_id, storage_pool.uuid pool_uuid, storage_pool.name pool_name, @@ -1846,7 +1870,10 @@ CREATE TABLE `cloud_usage`.`usage_vm_disk` ( ) ENGINE=InnoDB CHARSET=utf8; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.stats.interval', 0, 'Interval (in seconds) to report vm disk statistics.'); - +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_read_rate', 0, 'Default disk I/O read rate in requests per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_write_rate', 0, 'Default disk I/O write rate in requests per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_read_rate', 0, 'Default disk I/O read rate in bytes per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_write_rate', 0, 'Default disk I/O write rate in bytes per second allowed in User vm\'s disk. '); -- Re-enable foreign key checking, at the end of the upgrade path SET foreign_key_checks = 1; diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index a5f0662e0bf..7809cdb6c9d 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -472,6 +472,10 @@ dictionary = { 'label.disable.vpn': '', 'label.disabling.vpn.access': '', 'label.disk.allocated': '', +'label.disk.bytes.read.rate': '', +'label.disk.bytes.write.rate': '', +'label.disk.iops.write.rate': '', +'label.disk.iops.read.rate': '', 'label.disk.read.bytes': '', 'label.disk.read.io': '', 'label.disk.offering': '', diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index cadde8c91a7..150f244ff3c 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -109,6 +109,34 @@ number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, offerHA: { label: 'label.offer.ha', docID: 'helpComputeOfferingHA', @@ -227,7 +255,26 @@ networkrate: args.data.networkRate }); } - + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.extend(data, { offerha: (args.data.offerHA == "on") }); @@ -396,6 +443,10 @@ } }, networkrate: { label: 'label.network.rate' }, + diskBytesReadRate: { label: 'label.disk.bytes.read.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.read.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, offerha: { label: 'label.offer.ha', converter: cloudStack.converters.toBooleanText @@ -534,6 +585,34 @@ number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, offerHA: { label: 'label.offer.ha', docID: 'helpSystemOfferingHA', @@ -602,6 +681,26 @@ networkrate: args.data.networkRate }); } + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.extend(data, { offerha: (args.data.offerHA == "on") @@ -781,6 +880,10 @@ } }, networkrate: { label: 'label.network.rate' }, + diskBytesReadRate: { label: 'label.disk.bytes.write.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.write.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, offerha: { label: 'label.offer.ha', converter: cloudStack.converters.toBooleanText @@ -840,6 +943,34 @@ else return "N/A"; } + }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } } }, @@ -911,6 +1042,34 @@ dependsOn: 'isCustomized', validation: { required: true, number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, tags: { label: 'label.storage.tags', docID: 'helpDiskOfferingStorageTags' @@ -972,6 +1131,26 @@ domainid: args.data.domainId }); } + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.ajax({ url: createURL('createDiskOffering'), @@ -1084,6 +1263,10 @@ return "N/A"; } }, + diskBytesReadRate: { label: 'label.disk.bytes.write.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.write.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, tags: { label: 'label.storage.tags' }, domain: { label: 'label.domain' }, storagetype: { label: 'label.storage.type' } From 97eb35c82b1a5a638818391d6a1dbdcb2a9e3990 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 18 Jun 2013 14:22:26 +0530 Subject: [PATCH 52/95] NAT rule creation gives ipaddress as nat_rule.ipaddress Signed-off-by: Prasanna Santhanam --- test/integration/smoke/test_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index a75ffeb8953..121bda03506 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -1163,7 +1163,7 @@ class TestRebootRouter(cloudstackTestCase): self.debug("SSH into VM (ID : %s ) after reboot" % self.vm_1.id) remoteSSHClient( - self.nat_rule.ipaddress.ipaddress, + self.nat_rule.ipaddress, self.services["natrule"]["publicport"], self.vm_1.username, self.vm_1.password From 746af2bb6f5d356a0ea3fd274d192e2eb9bb83a0 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 18 Jun 2013 15:06:46 +0530 Subject: [PATCH 53/95] CLOUDSTACK-3049: marvin-nose causes other plugins to fail when not enabled enabled by default. Running regular nosetests with plugins other than marvin will fail because of this. Failure manifests itself as nose looking for the config file when using the marivn-nose plugin Signed-off-by: Prasanna Santhanam --- tools/marvin/marvin/marvinPlugin.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index 46a8a4f3445..846f73577c1 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -34,9 +34,15 @@ class MarvinPlugin(Plugin): """ name = "marvin" + def configure(self, options, config): - self.enabled = 1 - self.enableOpt = "--with-marvin" + if hasattr(options,self.enableOpt): + if not getattr(options, self.enableOpt): + self.enabled = False + return + else: + self.enabled = True + self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") if options.debug_log: From 9d7c7c14c793e86a182e6a7c2b60b95262aa9859 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 18 Jun 2013 12:56:19 +0200 Subject: [PATCH 54/95] CLOUDSTACK-1866: create iptables rules for network usage in finalizeSshAndVersionAndNetworkUsageOnStart only for non-Vpc network --- .../network/router/VirtualNetworkApplianceManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 8da51763982..8edd5bd7b8f 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2351,7 +2351,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V // Network usage command to create iptables rules boolean forVpc = profile.getVirtualMachine().getVpcId() != null; - cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); + if (!forVpc) + cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); } protected void finalizeUserDataAndDhcpOnStart(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { From 10e80afdeb7f631113ec62d86a4e734fa614b0be Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 18 Jun 2013 15:29:46 +0200 Subject: [PATCH 55/95] remove duplicated VPC router in return value of functions in DomainRouterDaoImpl --- .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 391fa5895b0..65b9d3b27c7 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.vm.dao; +import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; @@ -44,6 +45,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; @@ -103,6 +105,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im IdNetworkIdStatesSearch.done(); HostUpSearch = createSearchBuilder(); + HostUpSearch.select(null, Func.DISTINCT, HostUpSearch.entity().getId()); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN); SearchBuilder joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder(); @@ -112,6 +115,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im HostUpSearch.done(); StateNetworkTypeSearch = createSearchBuilder(); + StateNetworkTypeSearch.select(null, Func.DISTINCT, StateNetworkTypeSearch.entity().getId()); StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ); SearchBuilder joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder(); joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ); @@ -214,7 +218,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("host", hostId); } sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override @@ -253,7 +262,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("state", state); sc.setJoinParameters("networkRouter", "type", type); sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override From 779763fdfd34c00f19481d88c6cccb1edf8bf532 Mon Sep 17 00:00:00 2001 From: Ian Service Date: Tue, 18 Jun 2013 10:39:31 -0400 Subject: [PATCH 56/95] CLOUDSTACK-3054 - Have ssh key initscript handle SELinux permissions --- setup/bindir/cloud-set-guest-sshkey.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/bindir/cloud-set-guest-sshkey.in b/setup/bindir/cloud-set-guest-sshkey.in index 15008b8d514..f3f02b15fb0 100755 --- a/setup/bindir/cloud-set-guest-sshkey.in +++ b/setup/bindir/cloud-set-guest-sshkey.in @@ -71,6 +71,7 @@ fi homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}') sshdir=$homedir/.ssh authorized=$sshdir/authorized_keys +restorecon=/sbin/restorecon if [ ! -e $sshdir ] @@ -86,6 +87,10 @@ fi cat $authorized|grep -v "$publickey" > $authorized echo "$publickey" >> $authorized +if [ -e $restorecon ] +then + $restorecon -R -v $sshdir +fi exit 0 From 0dd45513e307cd955dbf91b3fb4ebb8233dd685e Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 18 Jun 2013 17:00:44 +0200 Subject: [PATCH 57/95] CLOUDSTACK-2885: show cpuNumber and cpuSpeed on VM Statistics page --- server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index dbfe94dad26..305d2b2b271 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -123,6 +123,8 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) { userVmResponse.setServiceOfferingId(userVm.getServiceOfferingUuid()); userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName()); + } + if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff) || details.contains(VMDetails.stats)) { userVmResponse.setCpuNumber(userVm.getCpu()); userVmResponse.setCpuSpeed(userVm.getSpeed()); userVmResponse.setMemory(userVm.getRamSize()); From f2e6ababababd917137948b4638ffee6cd2f0432 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 18 Jun 2013 17:50:07 +0200 Subject: [PATCH 58/95] CLOUDSTACK-3055: change data transfer rate unit from MB to Mb in service/network offerings --- ui/scripts/docs.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 48db443f7a8..5aa352afdbf 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -231,7 +231,7 @@ cloudStack.docs = { externalLink: '' }, helpComputeOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpComputeOfferingHA: { @@ -482,7 +482,7 @@ cloudStack.docs = { externalLink: '' }, helpNetworkOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpNetworkOfferingTrafficType: { @@ -699,7 +699,7 @@ cloudStack.docs = { externalLink: '' }, helpSystemOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpSystemOfferingHA: { From b5abc0862b8877f8aee0df2b33cd0d55ea9f9649 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 18 Jun 2013 10:40:14 -0700 Subject: [PATCH 59/95] CLOUDSTACK-3016: remove zonetype parameter from listRouters API, listInternalLbVms API. --- .../admin/internallb/ListInternalLBVMsCmd.java | 10 ++-------- .../api/command/admin/router/ListRoutersCmd.java | 7 ------- .../src/com/cloud/api/query/QueryManagerImpl.java | 14 ++++---------- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java index e314b3245c7..68370e8131e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java @@ -75,10 +75,7 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC Internal LB VMs") private Boolean forVpc; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -123,10 +120,7 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd public String getRole() { return Role.INTERNAL_LB_VM.toString(); } - - public String getZoneType() { - return zoneType; - } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index 78c3554ae73..a74eb897dba 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -65,9 +65,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { description="the Zone ID of the router") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, description="list by network id") private Long networkId; @@ -107,10 +104,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public Long getNetworkId() { return networkId; } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index f70f5aef599..10ab8f1475a 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -981,7 +981,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { public ListResponse searchForRouters(ListRoutersCmd cmd) { Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), - cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); @@ -994,17 +994,17 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { public ListResponse searchForInternalLbVms(ListInternalLBVMsCmd cmd) { Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), - cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); response.setResponses(routerResponses, result.second()); return response; } - + private Pair, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, - String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String zoneType) { + String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role) { Account caller = UserContext.current().getCaller(); @@ -1032,7 +1032,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.IN); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); @@ -1082,11 +1081,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("podId", podId); } - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } - - if (hostId != null) { sc.setParameters("hostId", hostId); } From 26c1be6447283fb0e0000417e065fa4fb8d9f314 Mon Sep 17 00:00:00 2001 From: Joe Brockmeier Date: Tue, 18 Jun 2013 15:46:37 -0500 Subject: [PATCH 60/95] updating URLs in source-build.xml so they're not borked when Confluence is upgraded this weekend. --- docs/en-US/source-build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en-US/source-build.xml b/docs/en-US/source-build.xml index 8504385ee29..a56d304245f 100644 --- a/docs/en-US/source-build.xml +++ b/docs/en-US/source-build.xml @@ -28,8 +28,8 @@ Prior to the 4.0.0 incubating release, Ant was used to build &PRODUCT;. A migration to Maven started in the 4.0.0 cycle, and has completed in 4.1.0. The website and the wiki contain up to date information on the build procedure at: - https://cwiki.apache.org/CLOUDSTACK/building-with-maven.html - https://cwiki.apache.org/CLOUDSTACK/setting-up-cloudstack-development-environment.html + https://cwiki.apache.org/confluence/display/CLOUDSTACK/How+to+build+on+master+branch + https://cwiki.apache.org/confluence/display/CLOUDSTACK/Setting+up+CloudStack+Development+Environment The overarching steps to build &PRODUCT; are:. From ddf274edf96c0f613269ec8477cb1293e5a4d404 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 18 Jun 2013 13:47:38 -0700 Subject: [PATCH 61/95] UI Project switcher: Better appearance --- ui/css/cloudstack3.css | 68 +++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index a86b2a25ca5..e145603b3a8 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -9087,29 +9087,63 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t /*** View switcher (drop-down)*/ .project-switcher { float: left; - width: 141px; + width: 223px; padding: 9px 17px 0 0; -} - -.project-switcher label { - position: absolute; - top: -2px; - color: #FFFFFF; - font-size: 11px; -} - -.project-switcher select { - width: 100%; - font-size: 12px; - border: 1px solid #000000; - border-bottom: #FFFFFF; /*+border-radius:4px;*/ -moz-border-radius: 4px; -webkit-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; - background: #ECECEC; - margin-top: 2px; +} + +.project-switcher label { + position: absolute; + top: 15px; + color: #FFFFFF; + font-size: 12px; + font-weight: bold; +} + +.project-switcher select { + width: 79%; + font-weight: bold; + font-size: 12px; + /*+text-shadow:0px -1px 1px #000000;*/ + -moz-text-shadow: 0px -1px 1px #000000; + -webkit-text-shadow: 0px -1px 1px #000000; + -o-text-shadow: 0px -1px 1px #000000; + text-shadow: 0px -1px 1px #000000; + border: 1px solid #9A9A9A; + border-bottom: #FFFFFF; + /*+box-shadow:inset 0px -1px #A2A2A2;*/ + -moz-box-shadow: inset 0px -1px #A2A2A2; + -webkit-box-shadow: inset 0px -1px #A2A2A2; + -o-box-shadow: inset 0px -1px #A2A2A2; + box-shadow: inset 0px -1px #A2A2A2; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + color: #FFFFFF; + margin-top: -2px; + margin-left: 53px; + background: url(../images/bg-gradients.png) 0px -867px; + padding: 5px; +} + +.project-switcher select:hover { + /*+box-shadow:inset 0px 2px 6px #3B3B3B;*/ + -moz-box-shadow: inset 0px 2px 6px #3B3B3B; + -webkit-box-shadow: inset 0px 2px 6px #3B3B3B; + -o-box-shadow: inset 0px 2px 6px #3B3B3B; + box-shadow: inset 0px 2px 6px #3B3B3B; + cursor: pointer; + border-bottom: 1px solid #828282; +} + +.project-switcher select option { + background: #7F8487; } /*** Select project*/ From b7def4342752fcfbe732a1c4ba1883bb3d68c9d8 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 18 Jun 2013 13:48:00 -0700 Subject: [PATCH 62/95] CLOUDSTACK-2080: Fix error handling for multi-edit actions --- ui/scripts/ui/widgets/multiEdit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js index 936c20c48a0..ea177c57848 100755 --- a/ui/scripts/ui/widgets/multiEdit.js +++ b/ui/scripts/ui/widgets/multiEdit.js @@ -354,7 +354,7 @@ error: function(message) { cloudStack.dialog.notice({ message: message }); $item.show(); - $loading.remove(); + $dataItem.find('.loading-overlay').remove(); } } }); From 0a8343e750e94e494e2e408f7d151b0b20cb146e Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 18 Jun 2013 13:52:13 -0700 Subject: [PATCH 63/95] CLOUDSTACK-3016: remove zonetype property from API response (cluster, domainRouter, host, pod, storagePool, systemVM) --- .../cloudstack/api/response/ClusterResponse.java | 9 +-------- .../api/response/DomainRouterResponse.java | 11 ----------- .../apache/cloudstack/api/response/HostResponse.java | 9 +-------- .../apache/cloudstack/api/response/PodResponse.java | 9 +-------- .../cloudstack/api/response/StoragePoolResponse.java | 12 +----------- .../cloudstack/api/response/SystemVmResponse.java | 11 ----------- server/src/com/cloud/api/ApiResponseHelper.java | 3 --- .../cloud/api/query/dao/DomainRouterJoinDaoImpl.java | 1 - .../src/com/cloud/api/query/dao/HostJoinDaoImpl.java | 1 - .../cloud/api/query/dao/StoragePoolJoinDaoImpl.java | 1 - .../com/cloud/api/query/vo/DomainRouterJoinVO.java | 12 ------------ server/src/com/cloud/api/query/vo/HostJoinVO.java | 11 ----------- .../com/cloud/api/query/vo/StoragePoolJoinVO.java | 11 ----------- 13 files changed, 4 insertions(+), 97 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java index ef8cca65040..68aa8928165 100644 --- a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java @@ -45,10 +45,7 @@ public class ClusterResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the cluster") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - + @SerializedName("hypervisortype") @Param(description="the hypervisor type of the cluster") private String hypervisorType; @@ -118,10 +115,6 @@ public class ClusterResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getClusterType() { return clusterType; } diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 852d98815a3..1d31b58a481 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -42,9 +42,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the router") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.DNS1) @Param(description="the first DNS for the router") private String dns1; @@ -188,14 +185,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setDns1(String dns1) { this.dns1 = dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java index be1a4b443be..687687d37fc 100644 --- a/api/src/org/apache/cloudstack/api/response/HostResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java @@ -59,10 +59,7 @@ public class HostResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the host") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - + @SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID of the host") private String podId; @@ -212,10 +209,6 @@ public class HostResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setPodId(String podId) { this.podId = podId; } diff --git a/api/src/org/apache/cloudstack/api/response/PodResponse.java b/api/src/org/apache/cloudstack/api/response/PodResponse.java index 471cac1aa47..f31c289217e 100644 --- a/api/src/org/apache/cloudstack/api/response/PodResponse.java +++ b/api/src/org/apache/cloudstack/api/response/PodResponse.java @@ -36,13 +36,10 @@ public class PodResponse extends BaseResponse { @SerializedName("zoneid") @Param(description="the Zone ID of the Pod") private String zoneId; - + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the Pod") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("gateway") @Param(description="the gateway of the Pod") private String gateway; @@ -89,10 +86,6 @@ public class PodResponse extends BaseResponse { return zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setZoneName(String zoneName) { this.zoneName = zoneName; } diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java index 965407d9952..00500007c18 100644 --- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java +++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java @@ -37,14 +37,12 @@ public class StoragePoolResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the storage pool") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; @SerializedName("podid") @Param(description="the Pod ID of the storage pool") private String podId; @SerializedName("podname") @Param(description="the Pod name of the storage pool") - private String podName; + private String podName; @SerializedName("name") @Param(description="the name of the storage pool") private String name; @@ -143,14 +141,6 @@ public class StoragePoolResponse extends BaseResponse { this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getPodId() { return podId; } diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java index 3439dc025e3..8d2798a9d04 100644 --- a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java @@ -46,9 +46,6 @@ public class SystemVmResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the system VM") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("dns1") @Param(description="the first DNS for the system VM") private String dns1; @@ -153,15 +150,7 @@ public class SystemVmResponse extends BaseResponse { public void setZoneName(String zoneName) { this.zoneName = zoneName; } - - public String getZoneType() { - return zoneType; - } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getDns1() { return dns1; } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 94c5d6c1fa1..82b08f739d1 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -824,7 +824,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { podResponse.setZoneId(zone.getUuid()); podResponse.setZoneName(zone.getName()); - podResponse.setZoneType(zone.getNetworkType().toString()); } podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize())); podResponse.setStartIp(ipRange[0]); @@ -969,7 +968,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (dc != null) { clusterResponse.setZoneId(dc.getUuid()); clusterResponse.setZoneName(dc.getName()); - clusterResponse.setZoneType(dc.getNetworkType().toString()); } clusterResponse.setHypervisorType(cluster.getHypervisorType().toString()); clusterResponse.setClusterType(cluster.getClusterType().toString()); @@ -1174,7 +1172,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { vmResponse.setZoneId(zone.getUuid()); vmResponse.setZoneName(zone.getName()); - vmResponse.setZoneType(zone.getNetworkType().toString()); vmResponse.setDns1(zone.getDns1()); vmResponse.setDns2(zone.getDns2()); } diff --git a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java index a7a83de14a1..e1724d403bf 100644 --- a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java @@ -149,7 +149,6 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase implements hostResponse.setOsCategoryId(host.getOsCategoryUuid()); hostResponse.setOsCategoryName(host.getOsCategoryName()); hostResponse.setZoneName(host.getZoneName()); - hostResponse.setZoneType(host.getZoneType().toString()); hostResponse.setPodName(host.getPodName()); if ( host.getClusterId() > 0) { hostResponse.setClusterName(host.getClusterName()); diff --git a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java index f2b9525b2cc..4254a7cb825 100644 --- a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java @@ -79,7 +79,6 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase Date: Tue, 18 Jun 2013 14:42:38 -0700 Subject: [PATCH 64/95] CLOUDSTACK-3016: remove zonetype property from API response (snapshot, ISO, template, network, volume) --- .../api/response/NetworkResponse.java | 7 ------- .../api/response/SnapshotResponse.java | 17 +---------------- .../api/response/TemplateResponse.java | 7 ------- .../cloudstack/api/response/VolumeResponse.java | 8 -------- server/src/com/cloud/api/ApiResponseHelper.java | 10 ---------- .../cloud/api/query/dao/VolumeJoinDaoImpl.java | 3 +-- .../com/cloud/api/query/vo/VolumeJoinVO.java | 15 --------------- 7 files changed, 2 insertions(+), 65 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java index 70c3d79c4c0..31024330dcd 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java @@ -66,9 +66,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone the network belongs to") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone the network belongs to") - private String zoneType; @SerializedName("networkofferingid") @Param(description="network offering id the network is created from") private String networkOfferingId; @@ -309,10 +306,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setCidr(String cidr) { this.cidr = cidr; } diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index ca74a18043b..e9cb109bf31 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -97,14 +97,6 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @Param(description = "id of the availability zone") private String zoneId; - @SerializedName(ApiConstants.ZONE_NAME) - @Param(description = "name of the availability zone") - private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List tags; @@ -188,14 +180,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setZoneId(String zoneId) { this.zoneId = zoneId; } - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - + public void setTags(List tags) { this.tags = tags; } diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index 896154aa9e9..ed933ff18c3 100644 --- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java @@ -87,9 +87,6 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone for this template") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone for this template") - private String zoneType; @SerializedName(ApiConstants.STATUS) @Param(description="the status of the template") private String status; @@ -159,10 +156,6 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setAccountId(String accountId) { this.accountId = accountId; } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index e3463bd24d5..b643de12585 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -47,10 +47,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @SerializedName(ApiConstants.ZONE_NAME) @Param(description = "name of the availability zone") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; @SerializedName(ApiConstants.TYPE) @Param(description = "type of the disk volume (ROOT or DATADISK)") @@ -217,10 +213,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setVolumeType(String volumeType) { this.volumeType = volumeType; } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 82b08f739d1..7ffa30f6260 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -435,13 +435,6 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setVolumeId(volume.getUuid()); snapshotResponse.setVolumeName(volume.getName()); snapshotResponse.setVolumeType(volume.getVolumeType().name()); - - DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId()); - if (zone != null) { - snapshotResponse.setZoneName(zone.getName()); - snapshotResponse.setZoneType(zone.getNetworkType().toString()); - snapshotResponse.setZoneId(zone.getUuid()); - } } snapshotResponse.setCreated(snapshot.getCreated()); snapshotResponse.setName(snapshot.getName()); @@ -1462,7 +1455,6 @@ public class ApiResponseHelper implements ResponseGenerator { // Add the zone ID templateResponse.setZoneId(datacenter.getUuid()); templateResponse.setZoneName(datacenter.getName()); - templateResponse.setZoneType(datacenter.getNetworkType().toString()); } boolean isAdmin = false; @@ -1751,7 +1743,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (datacenter != null) { isoResponse.setZoneId(datacenter.getUuid()); isoResponse.setZoneName(datacenter.getName()); - isoResponse.setZoneType(datacenter.getNetworkType().toString()); } // If the user is an admin, add the template download status @@ -2239,7 +2230,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { response.setZoneId(zone.getUuid()); response.setZoneName(zone.getName()); - response.setZoneType(zone.getNetworkType().toString()); } if (network.getPhysicalNetworkId() != null) { PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId()); diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 453e82e83d2..ed2732e184d 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -86,8 +86,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem volResponse.setZoneId(volume.getDataCenterUuid()); volResponse.setZoneName(volume.getDataCenterName()); - volResponse.setZoneType(volume.getDataCenterType()); - + volResponse.setVolumeType(volume.getVolumeType().toString()); volResponse.setDeviceId(volume.getDeviceId()); diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index 735cf9ad08f..1f07f52973a 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -117,9 +117,6 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="data_center_name") private String dataCenterName; - - @Column(name="data_center_type") - private String dataCenterType; @Column(name="vm_id") private long vmId; @@ -1060,20 +1057,8 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { this.dataCenterName = dataCenterName; } - - - public String getDataCenterType() { - return dataCenterType; - } - - public void setDataCenterType(String dataCenterType) { - this.dataCenterType = dataCenterType; - } - - - public long getPodId() { return podId; } From 2f2bb6b3169a17ff018ee3c80aa87a38d420605e Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 18 Jun 2013 14:55:56 -0700 Subject: [PATCH 65/95] CLOUDSTACK-3016: remove zonetype property from API response (userVM) --- .../cloudstack/api/response/UserVmResponse.java | 7 ------- .../com/cloud/api/query/dao/UserVmJoinDaoImpl.java | 1 - server/src/com/cloud/api/query/vo/UserVmJoinVO.java | 13 ------------- 3 files changed, 21 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index 1f9eb1ac63f..5b71ba228cc 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -80,9 +80,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the availability zone for the virtual machine") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the network type of the availability zone for the virtual machine") - private String zoneType; - @SerializedName(ApiConstants.HOST_ID) @Param(description="the ID of the host for the virtual machine") private String hostId; @@ -273,10 +270,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setHostId(String hostId) { this.hostId = hostId; } diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 305d2b2b271..f9877ab98b4 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -102,7 +102,6 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem } userVmResponse.setZoneId(userVm.getDataCenterUuid()); userVmResponse.setZoneName(userVm.getDataCenterName()); - userVmResponse.setZoneType(userVm.getDataCenterType()); if ((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)) { userVmResponse.setInstanceName(userVm.getInstanceName()); userVmResponse.setHostId(userVm.getHostUuid()); diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 8ad0fdd6457..c97d71a81ed 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -156,9 +156,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="data_center_name") private String dataCenterName = null; - @Column(name="data_center_type") - private String dataCenterType = null; - @Column(name="security_group_enabled") private boolean securityGroupEnabled; @@ -813,18 +810,8 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { public void setDataCenterName(String zoneName) { this.dataCenterName = zoneName; } - - - public String getDataCenterType() { - return dataCenterType; - } - public void setDataCenterType(String zoneType) { - this.dataCenterType = zoneType; - } - - public boolean isSecurityGroupEnabled() { return securityGroupEnabled; } From 231c4b5b10849edfc06a884bfb8d4f6cc7453536 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 18 Jun 2013 15:16:32 -0700 Subject: [PATCH 66/95] CLOUDSTACK-2716: Truncate long values For cases such as in global setting values, truncate long text if new option 'truncate: true' is specified in field properties. This will reduce td's max-width and add ellipses. Edit field on truncate: true columns will overflow into action column, to prevent input area from being too cramped. --- ui/css/cloudstack3.css | 19 ++++++++++++++++++- ui/scripts/globalSettings.js | 2 +- ui/scripts/ui/widgets/listView.js | 4 ++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index e145603b3a8..7113dbcb557 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -140,6 +140,17 @@ table tbody td.loading { border-top: 1px solid #FBFBFB; } +table tbody td.truncated { + overflow: visible; + max-width: 88px; +} + +table tbody td.truncated > span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + /** Actions table cell*/ table tbody td.actions { width: 130px; @@ -441,7 +452,7 @@ body.login { div.list-view table tbody td span { display: block; float: left; - max-width: 100%; + max-width: 89%; word-wrap: break-word; text-indent: 0; margin-left: 12px; @@ -3457,6 +3468,12 @@ div.view table td.editable div.edit { top: 0px; } +div.view table td.truncated.editable div.edit { + top: 1px; + width: 285px; + left: 1px; +} + div.view table td.editable div.edit input { float: left; width: 66%; diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js index 2687fcaac03..1ae73b70604 100644 --- a/ui/scripts/globalSettings.js +++ b/ui/scripts/globalSettings.js @@ -57,7 +57,7 @@ fields: { name: { label: 'label.name', id: true }, description: { label: 'label.description' }, - value: { label: 'label.value', editable: true } + value: { label: 'label.value', editable: true, truncate: true } }, dataProvider: function(args) { var data = { diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 8dbc2f6ffbc..bc68a7241ce 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -949,6 +949,10 @@ .appendTo($tr); var content = dataItem[key]; + if (field.truncate) { + $td.addClass('truncated'); + } + if (field.indicator) { $td.addClass('state').addClass(field.indicator[content]); From 643447e78ce338bc18a1dea5282780cea25fdbc7 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 18 Jun 2013 15:24:32 -0700 Subject: [PATCH 67/95] UI: Remove excessive fields from disk offering list view Several new fields were causing disk offering list view to overflow. These were removed from the table listing, and are still viewable from the detail page. --- ui/scripts/configuration.js | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 150f244ff3c..b1a68512382 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -943,34 +943,6 @@ else return "N/A"; } - }, - diskBytesReadRate: { - label: 'label.disk.bytes.read.rate', - validation: { - required: false, //optional - number: true - } - }, - diskBytesWriteRate: { - label: 'label.disk.bytes.write.rate', - validation: { - required: false, //optional - number: true - } - }, - diskIopsReadRate: { - label: 'label.disk.iops.read.rate', - validation: { - required: false, //optional - number: true - } - }, - diskIopsWriteRate: { - label: 'label.disk.iops.write.rate', - validation: { - required: false, //optional - number: true - } } }, From 236dc12d8a384be545d7823470f3a93286477b12 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 18 Jun 2013 15:56:21 -0700 Subject: [PATCH 68/95] CLOUDSTACK-2770: UI - Infrastructure menu - physical netework - network service providers - add Baremetal DHCP, Baremetal PXE. --- ui/scripts/system.js | 646 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 645 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index df37f31d5fe..bcd555da4ac 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -4019,6 +4019,328 @@ } }, + //Baremetal DHCP provider detail view + BaremetalDhcpProvider: { + type: 'detailView', + id: 'BaremetalDhcpProvider', + label: 'Baremetal DHCP Provider', + viewAll: { label: 'label.devices', path: '_zone.BaremetalDhcpDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("BaremetalDhcpProvider"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "BaremetalDhcpProvider") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('BaremetalDhcpProvider') + }); + } + } + }, + actions: { + add: { + label: 'Add Baremetal DHCP Device', + createForm: { + title: 'Add Baremetal DHCP Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalDhcpDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal DHCP Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + }, + + //Baremetal PXE provider detail view + BaremetalPxeProvider: { + type: 'detailView', + id: 'BaremetalPxeProvider', + label: 'Baremetal PXE Provider', + viewAll: { label: 'label.devices', path: '_zone.BaremetalPxeDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("BaremetalPxeProvider"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "BaremetalPxeProvider") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('BaremetalPxeProvider') + }); + } + } + }, + actions: { + add: { + label: 'Add Baremetal PXE Device', + createForm: { + title: 'Add Baremetal PXE Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalPxeDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal PXE Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + }, + //f5 provider detail view f5: { type: 'detailView', @@ -7925,6 +8247,134 @@ } }, + // Baremetal DHCP devices listView + BaremetalDhcpDevices: { + id: 'BaremetalDhcpDevices', + title: 'Baremetal DHCP Devices', + listView: { + id: 'BaremetalDhcpDevices', + fields: { + url: { label: 'label.url' } + }, + actions: { + add: { + label: 'Add Baremetal DHCP Device', + createForm: { + title: 'Add Baremetal DHCP Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalDhcpDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal DHCP Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + }, + dataProvider: function(args) { + $.ajax({ + url: createURL('listBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listexternaldhcpresponse.baremetaldhcp; + args.response.success({data: items}); + } + }); + } + } + }, + + // Baremetal PXE devices listView + BaremetalPxeDevices: { + id: 'BaremetalPxeDevices', + title: 'Baremetal PXE Devices', + listView: { + id: 'BaremetalPxeDevices', + fields: { + url: { label: 'label.url' } + }, + actions: { + add: { + label: 'Add Baremetal PXE Device', + createForm: { + title: 'Add Baremetal PXE Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + }, + tftpdir: { + label: 'Tftp root directory', + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalPxeDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal PXE Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + }, + dataProvider: function(args) { + $.ajax({ + url: createURL('listBaremetalPxePingServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listpingpxeserverresponse.pingpxeserver; + args.response.success({data: items}); + } + }); + } + } + }, + // F5 devices listView f5Devices: { id: 'f5Devices', @@ -12675,6 +13125,184 @@ } }; + function addBaremetalDhcpDeviceFn(args) { + if(nspMap["BaremetalDhcpProvider"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BaremetalDhcpProvider&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBaremetalDhcpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addBaremetalDhcpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["BaremetalDhcpProvider"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + + $.ajax({ + url: createURL('addBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + dhcpservertype: 'DHCPD', + url: args.data.url, + username: args.data.username, + password: args.data.password + }, + success: function(json) { + var jid = json.addexternaldhcpresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.baremetaldhcp; + return item; + } + } + } + ); + } + }); + } + else if (result.jobstatus == 2) { + alert(_s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + alert(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else { + $.ajax({ + url: createURL('addBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + dhcpservertype: 'DHCPD', + url: args.data.url, + username: args.data.username, + password: args.data.password + }, + success: function(json) { + var jid = json.addexternaldhcpresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.baremetaldhcp; + return item; + } + } + } + ); + } + }); + } + } + + function addBaremetalPxeDeviceFn(args) { + if(nspMap["BaremetalPxeProvider"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BaremetalPxeProvider&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBaremetalPxeProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addBaremetalPxeProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["BaremetalPxeProvider"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + + $.ajax({ + url: createURL('addBaremetalPxeKickStartServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + pxeservertype: 'KICK_START', + url: args.data.url, + username: args.data.username, + password: args.data.password, + tftpdir: args.data.tftpdir + }, + success: function(json) { + var jid = json.addexternalpxeresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.externalpxe; + return item; + } + } + } + ); + } + }); + } + else if (result.jobstatus == 2) { + alert(_s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + alert(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else { + $.ajax({ + url: createURL('addBaremetalPxeKickStartServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + pxeservertype: 'KICK_START', + url: args.data.url, + username: args.data.username, + password: args.data.password, + tftpdir: args.data.tftpdir + }, + success: function(json) { + var jid = json.addexternalpxeresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.externalpxe; + return item; + } + } + } + ); + } + }); + } + } + function addExternalLoadBalancer(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { var array1 = []; array1.push("&physicalnetworkid=" + physicalNetworkObj.id); @@ -13626,6 +14254,12 @@ case "MidoNet": nspMap["midoNet"] = items[i]; break; + case "BaremetalDhcpProvider": + nspMap["BaremetalDhcpProvider"] = items[i]; + break; + case "BaremetalPxeProvider": + nspMap["BaremetalPxeProvider"] = items[i]; + break; case "F5BigIp": nspMap["f5"] = items[i]; break; @@ -13667,7 +14301,17 @@ id: 'bigswitchVns', name: 'BigSwitch Vns', state: nspMap.bigswitchVns ? nspMap.bigswitchVns.state : 'Disabled' - } + }, + { + id: 'BaremetalDhcpProvider', + name: 'Baremetal DHCP', + state: nspMap.BaremetalDhcpProvider ? nspMap.BaremetalDhcpProvider.state : 'Disabled' + }, + { + id: 'BaremetalPxeProvider', + name: 'Baremetal PXE', + state: nspMap.BaremetalPxeProvider ? nspMap.BaremetalPxeProvider.state : 'Disabled' + } ]; $(window).trigger('cloudStack.system.serviceProviders.makeHarcodedArray', { From a16af4380b5a5e9c80c9d65c86e36d7184b4d9fa Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 18 Jun 2013 15:57:11 -0700 Subject: [PATCH 69/95] CLOUDSTACK-2770: UI - Infrastructure menu - physical netework - network service providers - Baremetal PXE - Add Baremetal PXE Device dialog - add Tftp Root Diectory field. --- ui/scripts/system.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index bcd555da4ac..452249ae512 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -4231,7 +4231,11 @@ label: 'label.password', isPassword: true, validation: { required: true } - } + }, + tftpdir: { + label: 'Tftp root directory', + validation: { required: true } + } } }, action: function(args) { From 5d70e1928c19dc18b0479354b24649081f79c277 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 18 Jun 2013 17:34:21 -0700 Subject: [PATCH 70/95] CLOUDSTACK-2534: Modify id_rsa.cloud's permission to 600 644 is too open for ssh. --- scripts/vm/systemvm/injectkeys.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh index c17a3c61935..f33aa502033 100755 --- a/scripts/vm/systemvm/injectkeys.sh +++ b/scripts/vm/systemvm/injectkeys.sh @@ -65,7 +65,7 @@ copy_priv_key() { local newprivkey=$1 diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0 $SUDO cp -fb $newprivkey $(dirname $0)/id_rsa.cloud - $SUDO chmod 644 $(dirname $0)/id_rsa.cloud + $SUDO chmod 600 $(dirname $0)/id_rsa.cloud return $? } From c8bc7a0af51b14c41184274b8ddb3241e73992d4 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 18 Jun 2013 18:02:32 -0700 Subject: [PATCH 71/95] Revert "CLOUDSTACK-2534: Modify id_rsa.cloud's permission to 600" This reverts commit 5d70e1928c19dc18b0479354b24649081f79c277. Wrong fix. The correct key is at: /var/cloudstack/management/.ssh/id_rsa --- scripts/vm/systemvm/injectkeys.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh index f33aa502033..c17a3c61935 100755 --- a/scripts/vm/systemvm/injectkeys.sh +++ b/scripts/vm/systemvm/injectkeys.sh @@ -65,7 +65,7 @@ copy_priv_key() { local newprivkey=$1 diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0 $SUDO cp -fb $newprivkey $(dirname $0)/id_rsa.cloud - $SUDO chmod 600 $(dirname $0)/id_rsa.cloud + $SUDO chmod 644 $(dirname $0)/id_rsa.cloud return $? } From 168fb29d69da3a1bf03498f5070ff656d01cd4c7 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 18 Jun 2013 16:32:31 +0530 Subject: [PATCH 72/95] add some logging to NioTest Signed-off-by: Prasanna Santhanam --- utils/test/com/cloud/utils/testcase/NioTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/test/com/cloud/utils/testcase/NioTest.java b/utils/test/com/cloud/utils/testcase/NioTest.java index e20532c8204..3b8fe692683 100644 --- a/utils/test/com/cloud/utils/testcase/NioTest.java +++ b/utils/test/com/cloud/utils/testcase/NioTest.java @@ -16,20 +16,18 @@ // under the License. package com.cloud.utils.testcase; -import java.nio.channels.ClosedChannelException; -import java.util.Random; - -import org.apache.log4j.Logger; - import com.cloud.utils.nio.HandlerFactory; import com.cloud.utils.nio.Link; import com.cloud.utils.nio.NioClient; import com.cloud.utils.nio.NioServer; import com.cloud.utils.nio.Task; import com.cloud.utils.nio.Task.Type; - -import org.junit.Assert; import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.junit.Assert; + +import java.nio.channels.ClosedChannelException; +import java.util.Random; /** * @@ -83,6 +81,7 @@ public class NioTest extends TestCase { while (_clientLink == null) { try { + s_logger.debug("Link is not up! Waiting ..."); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -94,6 +93,7 @@ public class NioTest extends TestCase { public void tearDown() { while (!isTestsDone()) { try { + s_logger.debug(this._completedCount + "/" + this._testCount + " tests done. Waiting for completion"); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block From b6850c28dc664e88c0128ddbae7c3ee468290350 Mon Sep 17 00:00:00 2001 From: Rayees Namathponnan Date: Tue, 18 Jun 2013 02:43:52 -0400 Subject: [PATCH 73/95] CLOUDSTACK-3021: Correct the order of resources Resources are ordered so that the cleanup succeeds. domains are deleted after accounts under the domain are removed. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_accounts.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index ec135b1de4f..39ff3eaaf11 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -753,13 +753,14 @@ class TestServiceOfferingHierarchy(cloudstackTestCase): domainid=cls.domain_2.id ) - cls._cleanup = [ - cls.account_1, - cls.account_2, - cls.service_offering, - cls.domain_1, - cls.domain_2, - ] + cls._cleanup = [ + cls.account_2, + cls.domain_2, + cls.service_offering, + cls.account_1, + cls.domain_1, + ] + return @classmethod From 2f659d6d86fc167cf1447807e67157a163aa1049 Mon Sep 17 00:00:00 2001 From: Hiroaki KAWAI Date: Wed, 19 Jun 2013 15:36:26 +0900 Subject: [PATCH 74/95] Add comment Comment for RBD explanation. --- api/src/com/cloud/storage/Storage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java index c130fe222bf..0c3bb8bc2e5 100755 --- a/api/src/com/cloud/storage/Storage.java +++ b/api/src/com/cloud/storage/Storage.java @@ -97,8 +97,8 @@ public class Storage { Iscsi(true), // for e.g., ZFS Comstar ISO(false), // for iso image LVM(false), // XenServer local LVM SR - CLVM(true), - RBD(true), + CLVM(true), + RBD(true), // http://libvirt.org/storage.html#StorageBackendRBD SharedMountPoint(true), VMFS(true), // VMware VMFS storage PreSetup(true), // for XenServer, Storage Pool is set up by customers. From 6e63bb78220a057bca329ee6a8779f0e4c476586 Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Wed, 19 Jun 2013 12:10:09 +0530 Subject: [PATCH 75/95] CLOUDSTACK-1758: Update ssh key location for vmware Signed-off-by: Prasanna Santhanam --- tools/marvin/marvin/integration/lib/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/marvin/marvin/integration/lib/utils.py b/tools/marvin/marvin/integration/lib/utils.py index 6892c41d1ec..839ec89f4fd 100644 --- a/tools/marvin/marvin/integration/lib/utils.py +++ b/tools/marvin/marvin/integration/lib/utils.py @@ -160,7 +160,7 @@ def get_process_status(hostip, port, username, password, linklocalip, process, h #SSH to the machine ssh = remoteSSHClient(hostip, port, username, password) if str(hypervisor).lower() == 'vmware': - ssh_command = "ssh -i /var/lib/cloud/management/.ssh/id_rsa -ostricthostkeychecking=no " + ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no " else: ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no " From 24258648bf2fc298318e8cf446b62ecf6b8afef8 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 12:46:36 +0530 Subject: [PATCH 76/95] serviceCapabilityList is case sensitive Signed-off-by: Prasanna Santhanam --- test/integration/component/test_netscaler_configs.py | 2 +- test/integration/component/test_netscaler_lb.py | 2 +- test/integration/component/test_netscaler_nw_off.py | 5 ++--- test/integration/component/test_vpc_network.py | 2 +- test/integration/component/test_vpc_network_lbrules.py | 3 --- test/integration/component/test_vpc_network_pfrules.py | 3 --- test/integration/component/test_vpc_network_staticnatrule.py | 3 --- 7 files changed, 5 insertions(+), 15 deletions(-) diff --git a/test/integration/component/test_netscaler_configs.py b/test/integration/component/test_netscaler_configs.py index 3c18c0050fd..5de0843b49b 100644 --- a/test/integration/component/test_netscaler_configs.py +++ b/test/integration/component/test_netscaler_configs.py @@ -104,7 +104,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py index 9d06275f26c..534ffb1cfab 100644 --- a/test/integration/component/test_netscaler_lb.py +++ b/test/integration/component/test_netscaler_lb.py @@ -93,7 +93,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, diff --git a/test/integration/component/test_netscaler_nw_off.py b/test/integration/component/test_netscaler_nw_off.py index cd3b48e5930..256d1be0308 100644 --- a/test/integration/component/test_netscaler_nw_off.py +++ b/test/integration/component/test_netscaler_nw_off.py @@ -117,7 +117,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, @@ -157,11 +157,10 @@ class Services: "publicport": 22, "openfirewall": False, }, - "ostypeid": '01853327-513e-4508-9628-f1f55db1946f', + "ostype": 'Cent OS 5.3 (64 bit)', # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, - "mode": 'advanced' } diff --git a/test/integration/component/test_vpc_network.py b/test/integration/component/test_vpc_network.py index a997f43a612..9d5081f8e95 100644 --- a/test/integration/component/test_vpc_network.py +++ b/test/integration/component/test_vpc_network.py @@ -752,7 +752,7 @@ class TestVPCNetwork(cloudstackTestCase): self.validate_vpc_network(vpc) # Enable redundant router capability for the network offering - self.services["network"]["servicecapabilitylist"] = { + self.services["network"]["serviceCapabilityList"] = { "SourceNat": { "RedundantRouter": "true", }, diff --git a/test/integration/component/test_vpc_network_lbrules.py b/test/integration/component/test_vpc_network_lbrules.py index 3461bb4e426..b0357fa8de1 100644 --- a/test/integration/component/test_vpc_network_lbrules.py +++ b/test/integration/component/test_vpc_network_lbrules.py @@ -87,8 +87,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -176,7 +174,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } class TestVPCNetworkLBRules(cloudstackTestCase): diff --git a/test/integration/component/test_vpc_network_pfrules.py b/test/integration/component/test_vpc_network_pfrules.py index 8d1d9eccd0b..b478b6a1780 100644 --- a/test/integration/component/test_vpc_network_pfrules.py +++ b/test/integration/component/test_vpc_network_pfrules.py @@ -84,8 +84,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -175,7 +173,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } diff --git a/test/integration/component/test_vpc_network_staticnatrule.py b/test/integration/component/test_vpc_network_staticnatrule.py index bed1b5298b3..c5d9e57434d 100644 --- a/test/integration/component/test_vpc_network_staticnatrule.py +++ b/test/integration/component/test_vpc_network_staticnatrule.py @@ -83,8 +83,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -174,7 +172,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } From b0d186ce5bd42a9120243d1f32adabc6851865a5 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 12:47:42 +0530 Subject: [PATCH 77/95] Remove wait during cleanup Cleanups need not wait at teardown for accounts to be removed. This slows down the test case. Send the cleanup request and forget instead Signed-off-by: Prasanna Santhanam --- .../component/test_redundant_router.py | 301 ++---------------- 1 file changed, 28 insertions(+), 273 deletions(-) diff --git a/test/integration/component/test_redundant_router.py b/test/integration/component/test_redundant_router.py index 914b17496dc..814f3e24218 100644 --- a/test/integration/component/test_redundant_router.py +++ b/test/integration/component/test_redundant_router.py @@ -23,10 +23,8 @@ from marvin.integration.lib.utils import * from marvin.integration.lib.common import * #Import Local Modules -from marvin.cloudstackTestCase import * +from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackAPI import * -from marvin import remoteSSHClient - class Services: """Test Services for customer defects @@ -88,10 +86,10 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount", - "RedundantRouter": 'true', + "RedundantRouter": "true", }, "lb": { "SupportedLbIsolation": "dedicated" @@ -190,6 +188,7 @@ class TestCreateRvRNetworkOffering(cloudstackTestCase): # Validate the following # 1. Redundant Router offering should be created successfully and # listed in listNetworkOfferings response + # assert if RvR capability is enabled self.debug("Creating network offering with redundant VR capability") try: @@ -281,22 +280,7 @@ class TestCreateRvRNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -487,22 +471,7 @@ class TestCreateRvRNetworkNonDefaultGuestCidr(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -701,22 +670,7 @@ class TestRVRInternals(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -1029,22 +983,7 @@ class TestRedundancy(cloudstackTestCase): networkids=[str(self.network.id)] ) self.debug("Deployed VM in network: %s" % self.network.id) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -1100,9 +1039,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the MASTER router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = master_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1144,9 +1081,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Starting the old MASTER router") try: - cmd = startRouter.startRouter(cmd) - cmd.id = master_router.id - self.apiclient.startRouter(cmd) + Router.start(self.apiclient, id=master_router.id) self.debug("old MASTER router started") except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1227,9 +1162,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the BACKUP router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = backup_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to stop backup router: %s" % e) @@ -1271,9 +1204,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Starting the old BACKUP router") try: - cmd = startRouter.startRouter(cmd) - cmd.id = backup_router.id - self.apiclient.startRouter(cmd) + Router.start(self.apiclient, id=backup_router.id) self.debug("old BACKUP router started") except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1348,9 +1279,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Rebooting the master router") try: - cmd = rebootRouter.rebootRouterCmd() - cmd.id = master_router.id - self.apiclient.rebootRouter(cmd) + Router.reboot(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to reboot MASTER router: %s" % e) @@ -1442,9 +1371,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Rebooting the backuo router") try: - cmd = rebootRouter.rebootRouterCmd() - cmd.id = backup_router.id - self.apiclient.rebootRouter(cmd) + Router.reboot(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to reboot BACKUP router: %s" % e) @@ -1536,9 +1463,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the backup router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = backup_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to stop BACKUP router: %s" % e) @@ -1665,21 +1590,7 @@ class TestApplyAndDeleteNetworkRulesOnRvR(cloudstackTestCase): domainid=self.domain.id ) self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self.cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -1989,22 +1900,7 @@ class TestEnableVPNOverRvR(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -2245,22 +2141,7 @@ class TestNetworkRulesMasterDownDeleteNetworkRules(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -2393,10 +2274,7 @@ class TestNetworkRulesMasterDownDeleteNetworkRules(cloudstackTestCase): self.debug("Stopping router ID: %s" % master_router.id) try: - #Stop the router - cmd = stopRouter.stopRouterCmd() - cmd.id = master_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to stop master router..") @@ -2545,10 +2423,7 @@ class TestNetworkRulesMasterDownDeleteNetworkRules(cloudstackTestCase): self.debug("Starting router ID: %s" % master_router.id) try: - #Stop the router - cmd = startRouter.startRouterCmd() - cmd.id = master_router.id - self.apiclient.startRouter(cmd) + Router.start(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to start master router..") @@ -2633,22 +2508,7 @@ class TestApplyDeleteNetworkRulesRebootRouter(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._clean.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -3013,22 +2873,7 @@ class TestRestartRvRNetworkWithoutCleanup(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -3234,22 +3079,7 @@ class TestRestartRvRNetworkWithCleanup(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -3455,22 +3285,7 @@ class TestDeleteRvRNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -3671,22 +3486,7 @@ class TestNetworkGCRvR(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -3936,22 +3736,7 @@ class TestApplyRulesRestartRvRNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -4373,22 +4158,7 @@ class TestUpgradeDowngradeRVR(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -4741,22 +4511,7 @@ class TestRVRWithDiffEnvs(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) From 13e1f4fc1ec2fde00050f964553524a630bb9b57 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 14:17:50 +0530 Subject: [PATCH 78/95] Split Redundant Router tests Each module of redundant router contains related tests for services, network rules, upgrades, redundancy etc. Signed-off-by: Prasanna Santhanam --- .../component/test_redundant_router.py | 3814 +---------------- .../test_redundant_router_cleanups.py | 675 +++ ...st_redundant_router_deployment_planning.py | 1006 +++++ .../test_redundant_router_network_rules.py | 1416 ++++++ .../test_redundant_router_services.py | 376 ++ .../test_redundant_router_upgrades.py | 486 +++ 6 files changed, 3970 insertions(+), 3803 deletions(-) create mode 100644 test/integration/component/test_redundant_router_cleanups.py create mode 100644 test/integration/component/test_redundant_router_deployment_planning.py create mode 100644 test/integration/component/test_redundant_router_network_rules.py create mode 100644 test/integration/component/test_redundant_router_services.py create mode 100644 test/integration/component/test_redundant_router_upgrades.py diff --git a/test/integration/component/test_redundant_router.py b/test/integration/component/test_redundant_router.py index 814f3e24218..5f7b1caf32c 100644 --- a/test/integration/component/test_redundant_router.py +++ b/test/integration/component/test_redundant_router.py @@ -15,8 +15,6 @@ # specific language governing permissions and limitations # under the License. -from random import random -import marvin from nose.plugins.attrib import attr from marvin.integration.lib.base import * from marvin.integration.lib.utils import * @@ -132,8 +130,6 @@ class Services: }, "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, - "mode": 'advanced', - # Networking mode, Advanced, Basic } @@ -221,6 +217,14 @@ class TestCreateRvRNetworkOffering(cloudstackTestCase): 1, "List network off should have newly created network off" ) + for service in network_offs[0].service: + if service.name == 'SourceNat': + self.debug("Verifying SourceNat capabilites") + for capability in service.capability: + if capability.name == 'RedundantRouter': + self.assertTrue(capability.value=='true') + self.debug("RedundantRouter is enabled") + return @@ -476,7 +480,7 @@ class TestCreateRvRNetworkNonDefaultGuestCidr(cloudstackTestCase): @attr(tags=["advanced", "advancedns", "ssh"]) def test_createRvRNetwork(self): - """Test create network with redundant routers + """Test create network with non-default guest cidr with redundant routers """ # Validate the following: @@ -903,12 +907,12 @@ class TestRVRInternals(cloudstackTestCase): return -class TestRedundancy(cloudstackTestCase): +class TestRvRRedundancy(cloudstackTestCase): @classmethod def setUpClass(cls): cls.api_client = super( - TestRedundancy, + TestRvRRedundancy, cls ).getClsTestClient().getApiClient() cls.services = Services().services @@ -1531,3799 +1535,3 @@ class TestRedundancy(cloudstackTestCase): "Redundant state of the router should be BACKUP" ) return - - -class TestApplyAndDeleteNetworkRulesOnRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyAndDeleteNetworkRulesOnRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - self.cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_apply_and__delete_NetworkRulesOnRvR(self): - """Test apply and delete network rules on redundant router - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP - # 6. listRemoteAccessVpns for the network associated should show the - # VPN created - # 7. listRemoteAccessVpns for the network associated should return - # empty response - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - return - - -class TestEnableVPNOverRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestEnableVPNOverRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_enableVPNOverRvR(self): - """Test redundant router internals - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listRemoteAccessVpns for the network associated should show VPN - # created - # 7. listRemoteAccessVpns for the network associated should return - # empty response - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating a remote access VPN for account: %s" % - self.account.name) - - try: - vpn = Vpn.create( - self.apiclient, - publicipid=public_ip.ipaddress.id, - account=self.account.name, - domainid=self.account.domainid - ) - except Exception as e: - self.fail("Failed to create VPN for account: %s - %s" % ( - self.account.name, e)) - - try: - vpnuser = VpnUser.create( - self.apiclient, - username="root", - password="password", - account=self.account.name, - domainid=self.account.domainid - ) - except Exception as e: - self.fail("Failed to create VPN user: %s" % e) - - self.debug("Checking if the remote access VPN is created or not?") - remote_vpns = Vpn.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - publicipid=public_ip.ipaddress.id, - listall=True - ) - self.assertEqual( - isinstance(remote_vpns, list), - True, - "List remote VPNs should not return empty response" - ) - self.debug("Deleting the remote access VPN for account: %s" % - self.account.name) - - try: - vpn.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete VPN : %s" % e) - - self.debug("Checking if the remote access VPN is created or not?") - remote_vpns = Vpn.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - publicipid=public_ip.ipaddress.id, - listall=True - ) - self.assertEqual( - remote_vpns, - None, - "List remote VPNs should not return empty response" - ) - return - - -class TestNetworkRulesMasterDownDeleteNetworkRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetworkRulesMasterDownDeleteNetworkRules, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): - """Test apply network rules when master down and delete network rules - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show both routers MASTER and BACKUP in - # Running state - # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 20. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Stopping router ID: %s" % master_router.id) - - try: - Router.stop(self.apiclient, id=master_router.id) - except Exception as e: - self.fail("Failed to stop master router..") - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Starting router ID: %s" % master_router.id) - - try: - Router.start(self.apiclient, id=master_router.id) - except Exception as e: - self.fail("Failed to start master router..") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - return - - -class TestApplyDeleteNetworkRulesRebootRouter(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyDeleteNetworkRulesRebootRouter, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._clean.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): - """Test apply network rules when master & backup routers rebooted - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show both routers MASTER and BACKUP in - # Running state - # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 20. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Starting router ID: %s" % master_router.id) - - for router in routers: - try: - self.debug("Rebooting router ID: %s" % master_router.id) - #Stop the router - cmd = rebootRouter.rebootRouterCmd() - cmd.id = router.id - self.apiclient.rebootRouter(cmd) - except Exception as e: - self.fail("Failed to reboot router..") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - return - - -class TestRestartRvRNetworkWithoutCleanup(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRestartRvRNetworkWithoutCleanup, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withoutCleanup(self): - """Test apply rules after network restart - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("restarting network with cleanup=False") - try: - network.restart(self.apiclient, cleanup=False) - except Exception as e: - self.fail("Failed to cleanup network - %s" % e) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.assertIn( - router.linklocalip, - [master_router.linklocalip, backup_router.linklocalip], - "Routers should have same linklocal IP after nw restart" - ) - return - - -class TestRestartRvRNetworkWithCleanup(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRestartRvRNetworkWithCleanup, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withCleanup(self): - """Test Restart network with cleanup - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("restarting network with cleanup=True") - try: - network.restart(self.apiclient, cleanup=True) - except Exception as e: - self.fail("Failed to cleanup network - %s" % e) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.assertIn( - router.linklocalip, - [master_router.linklocalip, backup_router.linklocalip], - "Routers should have same linklocal IP after nw restart" - ) - return - - -class TestDeleteRvRNetwork(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestDeleteRvRNetwork, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withCleanup(self): - """Test Restart network with cleanup - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Trying to delete the network with running Vms") - with self.assertRaises(Exception): - network.delete(self.apiclient, cleanup=True) - - self.debug("Network delete failed!") - self.debug("Destroying the user VMs for account: %s" % - self.account.name) - - try: - virtual_machine.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete guest Vm from account: %s - %s" % - (self.account.name, e)) - - interval = list_configurations( - self.apiclient, - name='expunge.delay' - ) - delay = int(interval[0].value) - interval = list_configurations( - self.apiclient, - name='expunge.interval' - ) - exp = int(interval[0].value) - - self.debug("Sleeping for exp delay + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - self.debug("Trying to delete guest network for account: %s" % - self.account.name) - try: - network.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete network: %s" % e) - return - - -class TestNetworkGCRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetworkGCRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_networkGC_RvR(self): - """Test network garbage collection with RVR - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. stop the running user VM - # 5. wait for network.gc time - # 6. listRouters - # 7. start the routers MASTER and BACK - # 8. wait for network.gc time and listRouters - # 9. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Stopping the user VM: %s" % virtual_machine.name) - - try: - virtual_machine.stop(self.apiclient) - except Exception as e: - self.fail("Failed to stop guest Vm: %s - %s" % - (virtual_machine.name, e)) - - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - delay = int(interval[0].value) - interval = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - exp = int(interval[0].value) - - self.debug("Sleeping for network gc wait + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Stopped", - "Router should be in stopped state" - ) - self.debug("Starting the stopped router again") - cmd = startRouter.startRouterCmd() - cmd.id = router.id - self.apiclient.startRouter(cmd) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router should be in running state" - ) - - self.debug("Sleeping for network gc wait + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Stopped", - "Router should be in stopped state" - ) - return - - -class TestApplyRulesRestartRvRNetwork(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyRulesRestartRvRNetwork, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyRules_restartRvRNetwork(self): - """Test apply rules after network restart - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running & - # one in BACKUP and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show one Router in MASTER state and Running & - # one in BACKUP and Running - # 19. ssh should work for PF, FW, and LB ips - # 20. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 21. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Restarting network ID: %s with cleanup true" % - network.id) - - try: - network.restart(self.apiclient, cleanup=True) - except Exception as e: - self.fail("Failed to cleanup network") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Restarting network ID: %s with cleanup false" % - network.id) - - try: - network.restart(self.apiclient, cleanup=False) - except Exception as e: - self.fail("Failed to cleanup network") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - return - - -class TestUpgradeDowngradeRVR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestUpgradeDowngradeRVR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_upgradeVR_to_redundantVR(self): - """Test upgrade virtual router to redundant virtual router - """ - - # Steps to validate - # 1. create a network with DefaultNetworkOfferingWithSourceNATservice - # (all VR based services) - # 2. deploy a VM in the above network and listRouters - # 3. create a network Offering that has redundant router enabled and - # all VR based services - # 4. updateNetwork created above to the offfering in 3. - # 5. listRouters in the network - # 6. delete account in which resources are created - # Validate the following - # 1. listNetworks should show the created network in allocated state - # 2. VM should be deployed and in Running state and there should be - # one Router running for this network - # 3. listNetworkOfferings should show craeted offering for RvR - # 4. listNetworks shows the network still successfully implemented - # 5. listRouters shows two routers Up and Running (MASTER and BACKUP) - - network_offerings = NetworkOffering.list( - self.apiclient, - name='DefaultIsolatedNetworkOfferingWithSourceNatService', - listall=True - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "List network offering should not return empty response" - ) - - network_off_vr = network_offerings[0] - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - network_off_vr.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=network_off_vr.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in the account: %s" % - self.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return only one router" - ) - self.assertEqual( - len(routers), - 1, - "Length of the list router should be 1" - ) - - self.debug("Upgrading the network to RVR network offering..") - try: - network.update( - self.apiclient, - networkofferingid=self.network_offering.id - ) - except Exception as e: - self.fail("Failed to upgrade the network from VR to RVR: %s" % e) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return two routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (MASTER & BACKUP)" - ) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_downgradeRvR_to_VR(self): - """Test downgrade redundant virtual router to virtual router - """ - - # Steps to validate - # 1. create a network Offering that has redundant router enabled and - # all VR based services - # 2. create a network with above offering - # 3. deploy a VM in the above network and listRouters - # 4. create a network Offering that has redundant router disabled and - # all VR based services - # 5. updateNetwork - downgrade - created above to the offfering in 4. - # 6. listRouters in the network - # 7. delete account in which resources are created - # Validate the following - # 1. listNetworkOfferings should show craeted offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and there should be - # two routers (MASTER and BACKUP) for this network - # 4. listNetworkOfferings should show craeted offering for VR - # 5. listNetworks shows the network still successfully implemented - # 6. listRouters shows only one router for this network in Running - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in the account: %s" % - self.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return two routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (MASTER & BACKUP)" - ) - - network_offerings = NetworkOffering.list( - self.apiclient, - name='DefaultIsolatedNetworkOfferingWithSourceNatService', - listall=True - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "List network offering should not return empty response" - ) - - network_off_vr = network_offerings[0] - - self.debug("Upgrading the network to RVR network offering..") - try: - network.update( - self.apiclient, - networkofferingid=network_off_vr.id - ) - except Exception as e: - self.fail("Failed to upgrade the network from VR to RVR: %s" % e) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return only one router" - ) - self.assertEqual( - len(routers), - 1, - "Length of the list router should be 1" - ) - return - - -class TestRVRWithDiffEnvs(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRVRWithDiffEnvs, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self._cleanup.insert(0, self.account) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multipods(self): - """Test RvR with muti pods - """ - - # Steps to validate - # 0. listPods should have at least 2 pods - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network - # 4. listRouters - # 5. delete the account - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different pods - - self.debug("Checking if the current zone has 2 active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - if len(pods) < 2: - raise unittest.SkipTest("The env don't have 2 pods req for test") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].podid, - routers[1].podid, - "Both the routers should be in different pods" - ) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multicluster(self): - """Test RvR with muti clusters - """ - - # Steps to validate - # 0. listClusters should have at least two clusters (if there are - # multiple pods, disable all except one with two clusters) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in either of clusters - # found in 0. (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable all disabled pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different pods - - self.debug("Checking if the current zone has 2 active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - enabled_pod = pods[0] - - self.debug("Cheking if pod has atleast 2 clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - if len(clusters) < 2: - raise unittest.SkipTest( - "The env don't have 2 clusters req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - hosts = Host.list( - self.apiclient, - id=routers[0].hostid, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List host should return a valid data" - ) - first_host = hosts[0] - - hosts = Host.list( - self.apiclient, - id=routers[1].hostid, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List host should return a valid data" - ) - second_host = hosts[0] - - # Checking if the cluster IDs of both routers are different? - self.assertNotEqual( - first_host.clusterid, - second_host.clusterid, - "Both the routers should be in different clusters" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multiprimarystorage(self): - """Test RvR with muti primary storage - """ - - # Steps to validate - # 0. listStoragePools should have atleast two pools in a single - # cluster (disable pods/clusters as necessary) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in the cluster from 0 - # (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable the clusters and pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and on the specified - # host - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different storage pools - - self.debug( - "Checking if the current zone has multiple active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - enabled_pod = pods[0] - self.debug("Cheking if pod has multiple clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - - enabled_cluster = clusters[0] - - self.debug("Cheking if cluster has multiple storage pools") - storage_pools = StoragePool.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(storage_pools, list), - True, - "List storage pools should not return empty response" - ) - - if len(storage_pools) < 2: - raise unittest.SkipTest( - "The env don't have 2 storage pools req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - self.debug("disable all clusters except one!") - if len(pods) > 1: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Disabled' - self.apiclient.updateCluster(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updateCluster.updateClusterCmd() - cmd.id = clusters[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - self.debug("Enabled first cluster for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Retrieving the list of hosts in the cluster") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return an empty response" - ) - host = hosts[0] - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)], - hostid=host.id - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].hostid, - routers[1].hostid, - "Both the routers should be in different storage pools" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - - clusters = Cluster.list( - self.apiclient, - allocationstate="Disabled", - podid=enabled_pod.id, - listall=True - ) - - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multihosts(self): - """Test RvR with muti hosts - """ - - # Steps to validate - # 0. listHosts should have atleast two hosts in a single cluster - # (disable pods/clusters as necessary) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in the cluster from 0 - # (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable the clusters and pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and on specified host - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different hosts - - self.debug( - "Checking if the current zone has multiple active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - enabled_pod = pods[0] - self.debug("Cheking if pod has multiple clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - - enabled_cluster = clusters[0] - - self.debug("Cheking if cluster has multiple hosts") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return empty response" - ) - - if len(hosts) < 2: - raise unittest.SkipTest( - "The env don't have 2 hosts req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - self.debug("disable all clusters except one!") - if len(pods) > 1: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Disabled' - self.apiclient.updateCluster(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updateCluster.updateClusterCmd() - cmd.id = clusters[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - self.debug("Enabled first cluster for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Retrieving the list of hosts in the cluster") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return an empty response" - ) - host = hosts[0] - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)], - hostid=host.id - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].hostid, - routers[1].hostid, - "Both the routers should be in different hosts" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - - if pods is not None: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - - clusters = Cluster.list( - self.apiclient, - allocationstate="Disabled", - podid=enabled_pod.id, - listall=True - ) - if clusters is not None: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - return diff --git a/test/integration/component/test_redundant_router_cleanups.py b/test/integration/component/test_redundant_router_cleanups.py new file mode 100644 index 00000000000..694db862876 --- /dev/null +++ b/test/integration/component/test_redundant_router_cleanups.py @@ -0,0 +1,675 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + 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, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + + +class TestRedundantRouterNetworkCleanups(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRedundantRouterNetworkCleanups, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_restart_ntwk_no_cleanup(self): + """Test restarting RvR network without cleanup + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. restartNetwork cleanup=false + # 5. listRouters in the account + # 6. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("restarting network with cleanup=False") + try: + network.restart(self.apiclient, cleanup=False) + except Exception as e: + self.fail("Failed to cleanup network - %s" % e) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.assertIn( + router.linklocalip, + [master_router.linklocalip, backup_router.linklocalip], + "Routers should have same linklocal IP after nw restart" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_restart_ntwk_with_cleanup(self): + """Test restart RvR network with cleanup + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. restartNetwork cleanup=false + # 5. listRouters in the account + # 6. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("restarting network with cleanup=True") + try: + network.restart(self.apiclient, cleanup=True) + except Exception as e: + self.fail("Failed to cleanup network - %s" % e) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.assertIn( + router.linklocalip, + [master_router.linklocalip, backup_router.linklocalip], + "Routers should have same linklocal IP after nw restart" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_network_gc(self): + """Test network garbage collection with RVR + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. stop the running user VM + # 5. wait for network.gc time + # 6. listRouters + # 7. start the routers MASTER and BACK + # 8. wait for network.gc time and listRouters + # 9. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Stopping the user VM: %s" % virtual_machine.name) + + try: + virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop guest Vm: %s - %s" % + (virtual_machine.name, e)) + + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + delay = int(interval[0].value) + interval = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + exp = int(interval[0].value) + + self.debug("Sleeping for network gc wait + interval time") + # Sleep to ensure that all resources are deleted + time.sleep((delay + exp) * 2) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Stopped", + "Router should be in stopped state" + ) + self.debug("Starting the stopped router again") + cmd = startRouter.startRouterCmd() + cmd.id = router.id + self.apiclient.startRouter(cmd) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router should be in running state" + ) + + self.debug("Sleeping for network gc wait + interval time") + # Sleep to ensure that all resources are deleted + time.sleep((delay + exp) * 2) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Stopped", + "Router should be in stopped state" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_deployment_planning.py b/test/integration/component/test_redundant_router_deployment_planning.py new file mode 100644 index 00000000000..5f0679420ff --- /dev/null +++ b/test/integration/component/test_redundant_router_deployment_planning.py @@ -0,0 +1,1006 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + 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, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRvRDeploymentPlanning(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRvRDeploymentPlanning, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multipods(self): + """Test RvR with muti pods + """ + + # Steps to validate + # 0. listPods should have at least 2 pods + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network + # 4. listRouters + # 5. delete the account + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different pods + + self.debug("Checking if the current zone has 2 active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + if len(pods) < 2: + raise unittest.SkipTest("The env don't have 2 pods req for test") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].podid, + routers[1].podid, + "Both the routers should be in different pods" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multicluster(self): + """Test RvR with muti clusters + """ + + # Steps to validate + # 0. listClusters should have at least two clusters (if there are + # multiple pods, disable all except one with two clusters) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in either of clusters + # found in 0. (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable all disabled pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different pods + + self.debug("Checking if the current zone has 2 active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + enabled_pod = pods[0] + + self.debug("Cheking if pod has atleast 2 clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + if len(clusters) < 2: + raise unittest.SkipTest( + "The env don't have 2 clusters req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + hosts = Host.list( + self.apiclient, + id=routers[0].hostid, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List host should return a valid data" + ) + first_host = hosts[0] + + hosts = Host.list( + self.apiclient, + id=routers[1].hostid, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List host should return a valid data" + ) + second_host = hosts[0] + + # Checking if the cluster IDs of both routers are different? + self.assertNotEqual( + first_host.clusterid, + second_host.clusterid, + "Both the routers should be in different clusters" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multiprimarystorage(self): + """Test RvR with muti primary storage + """ + + # Steps to validate + # 0. listStoragePools should have atleast two pools in a single + # cluster (disable pods/clusters as necessary) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in the cluster from 0 + # (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable the clusters and pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and on the specified + # host + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different storage pools + + self.debug( + "Checking if the current zone has multiple active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + enabled_pod = pods[0] + self.debug("Cheking if pod has multiple clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + + enabled_cluster = clusters[0] + + self.debug("Cheking if cluster has multiple storage pools") + storage_pools = StoragePool.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(storage_pools, list), + True, + "List storage pools should not return empty response" + ) + + if len(storage_pools) < 2: + raise unittest.SkipTest( + "The env don't have 2 storage pools req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + self.debug("disable all clusters except one!") + if len(pods) > 1: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Disabled' + self.apiclient.updateCluster(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updateCluster.updateClusterCmd() + cmd.id = clusters[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + self.debug("Enabled first cluster for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Retrieving the list of hosts in the cluster") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return an empty response" + ) + host = hosts[0] + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + hostid=host.id + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].hostid, + routers[1].hostid, + "Both the routers should be in different storage pools" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + + clusters = Cluster.list( + self.apiclient, + allocationstate="Disabled", + podid=enabled_pod.id, + listall=True + ) + + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multihosts(self): + """Test RvR with muti hosts + """ + + # Steps to validate + # 0. listHosts should have atleast two hosts in a single cluster + # (disable pods/clusters as necessary) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in the cluster from 0 + # (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable the clusters and pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and on specified host + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different hosts + + self.debug( + "Checking if the current zone has multiple active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + enabled_pod = pods[0] + self.debug("Cheking if pod has multiple clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + + enabled_cluster = clusters[0] + + self.debug("Cheking if cluster has multiple hosts") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return empty response" + ) + + if len(hosts) < 2: + raise unittest.SkipTest( + "The env don't have 2 hosts req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + self.debug("disable all clusters except one!") + if len(pods) > 1: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Disabled' + self.apiclient.updateCluster(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updateCluster.updateClusterCmd() + cmd.id = clusters[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + self.debug("Enabled first cluster for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Retrieving the list of hosts in the cluster") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return an empty response" + ) + host = hosts[0] + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + hostid=host.id + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].hostid, + routers[1].hostid, + "Both the routers should be in different hosts" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + + if pods is not None: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + + clusters = Cluster.list( + self.apiclient, + allocationstate="Disabled", + podid=enabled_pod.id, + listall=True + ) + if clusters is not None: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_network_rules.py b/test/integration/component/test_redundant_router_network_rules.py new file mode 100644 index 00000000000..d2d63b48873 --- /dev/null +++ b/test/integration/component/test_redundant_router_network_rules.py @@ -0,0 +1,1416 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + 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, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRedundantRouterRulesLifeCycle(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRedundantRouterRulesLifeCycle, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._clean.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): + """Test apply network rules when master & backup routers rebooted + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show both routers MASTER and BACKUP in + # Running state + # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 20. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Starting router ID: %s" % master_router.id) + + for router in routers: + try: + self.debug("Rebooting router ID: %s" % master_router.id) + #Stop the router + cmd = rebootRouter.rebootRouterCmd() + cmd.id = router.id + self.apiclient.rebootRouter(cmd) + except Exception as e: + self.fail("Failed to reboot router..") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyRules_restartRvRNetwork(self): + """Test apply rules after network restart + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running & + # one in BACKUP and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show one Router in MASTER state and Running & + # one in BACKUP and Running + # 19. ssh should work for PF, FW, and LB ips + # 20. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 21. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Restarting network ID: %s with cleanup true" % + network.id) + + try: + network.restart(self.apiclient, cleanup=True) + except Exception as e: + self.fail("Failed to cleanup network") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Restarting network ID: %s with cleanup false" % + network.id) + + try: + network.restart(self.apiclient, cleanup=False) + except Exception as e: + self.fail("Failed to cleanup network") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_apply_and__delete_NetworkRulesOnRvR(self): + """Test apply and delete network rules on redundant router + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP + # 6. listRemoteAccessVpns for the network associated should show the + # VPN created + # 7. listRemoteAccessVpns for the network associated should return + # empty response + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): + """Test apply network rules when master down and delete network rules + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show both routers MASTER and BACKUP in + # Running state + # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 20. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Stopping router ID: %s" % master_router.id) + + try: + Router.stop(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to stop master router..") + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Starting router ID: %s" % master_router.id) + + try: + Router.start(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to start master router..") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_services.py b/test/integration/component/test_redundant_router_services.py new file mode 100644 index 00000000000..cc4d367e016 --- /dev/null +++ b/test/integration/component/test_redundant_router_services.py @@ -0,0 +1,376 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + 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, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + + +class TestEnableVPNOverRvR(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestEnableVPNOverRvR, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_enableVPNOverRvR(self): + """Test redundant router internals + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listRemoteAccessVpns for the network associated should show VPN + # created + # 7. listRemoteAccessVpns for the network associated should return + # empty response + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating a remote access VPN for account: %s" % + self.account.name) + + try: + vpn = Vpn.create( + self.apiclient, + publicipid=public_ip.ipaddress.id, + account=self.account.name, + domainid=self.account.domainid + ) + except Exception as e: + self.fail("Failed to create VPN for account: %s - %s" % ( + self.account.name, e)) + + try: + vpnuser = VpnUser.create( + self.apiclient, + username="root", + password="password", + account=self.account.name, + domainid=self.account.domainid + ) + except Exception as e: + self.fail("Failed to create VPN user: %s" % e) + + self.debug("Checking if the remote access VPN is created or not?") + remote_vpns = Vpn.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + publicipid=public_ip.ipaddress.id, + listall=True + ) + self.assertEqual( + isinstance(remote_vpns, list), + True, + "List remote VPNs should not return empty response" + ) + self.debug("Deleting the remote access VPN for account: %s" % + self.account.name) + + try: + vpn.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete VPN : %s" % e) + + self.debug("Checking if the remote access VPN is created or not?") + remote_vpns = Vpn.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + publicipid=public_ip.ipaddress.id, + listall=True + ) + self.assertEqual( + remote_vpns, + None, + "List remote VPNs should not return empty response" + ) + return + diff --git a/test/integration/component/test_redundant_router_upgrades.py b/test/integration/component/test_redundant_router_upgrades.py new file mode 100644 index 00000000000..654faeb03be --- /dev/null +++ b/test/integration/component/test_redundant_router_upgrades.py @@ -0,0 +1,486 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + 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, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRvRUpgradeDowngrade(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRvRUpgradeDowngrade, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_upgradeVR_to_redundantVR(self): + """Test upgrade virtual router to redundant virtual router + """ + + # Steps to validate + # 1. create a network with DefaultNetworkOfferingWithSourceNATservice + # (all VR based services) + # 2. deploy a VM in the above network and listRouters + # 3. create a network Offering that has redundant router enabled and + # all VR based services + # 4. updateNetwork created above to the offfering in 3. + # 5. listRouters in the network + # 6. delete account in which resources are created + # Validate the following + # 1. listNetworks should show the created network in allocated state + # 2. VM should be deployed and in Running state and there should be + # one Router running for this network + # 3. listNetworkOfferings should show craeted offering for RvR + # 4. listNetworks shows the network still successfully implemented + # 5. listRouters shows two routers Up and Running (MASTER and BACKUP) + + network_offerings = NetworkOffering.list( + self.apiclient, + name='DefaultIsolatedNetworkOfferingWithSourceNatService', + listall=True + ) + self.assertEqual( + isinstance(network_offerings, list), + True, + "List network offering should not return empty response" + ) + + network_off_vr = network_offerings[0] + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + network_off_vr.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=network_off_vr.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in the account: %s" % + self.account.name) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return only one router" + ) + self.assertEqual( + len(routers), + 1, + "Length of the list router should be 1" + ) + + self.debug("Upgrading the network to RVR network offering..") + try: + network.update( + self.apiclient, + networkofferingid=self.network_offering.id + ) + except Exception as e: + self.fail("Failed to upgrade the network from VR to RVR: %s" % e) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return two routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (MASTER & BACKUP)" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_downgradeRvR_to_VR(self): + """Test downgrade redundant virtual router to virtual router + """ + + # Steps to validate + # 1. create a network Offering that has redundant router enabled and + # all VR based services + # 2. create a network with above offering + # 3. deploy a VM in the above network and listRouters + # 4. create a network Offering that has redundant router disabled and + # all VR based services + # 5. updateNetwork - downgrade - created above to the offfering in 4. + # 6. listRouters in the network + # 7. delete account in which resources are created + # Validate the following + # 1. listNetworkOfferings should show craeted offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and there should be + # two routers (MASTER and BACKUP) for this network + # 4. listNetworkOfferings should show craeted offering for VR + # 5. listNetworks shows the network still successfully implemented + # 6. listRouters shows only one router for this network in Running + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in the account: %s" % + self.account.name) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return two routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (MASTER & BACKUP)" + ) + + network_offerings = NetworkOffering.list( + self.apiclient, + name='DefaultIsolatedNetworkOfferingWithSourceNatService', + listall=True + ) + self.assertEqual( + isinstance(network_offerings, list), + True, + "List network offering should not return empty response" + ) + + network_off_vr = network_offerings[0] + + self.debug("Upgrading the network to RVR network offering..") + try: + network.update( + self.apiclient, + networkofferingid=network_off_vr.id + ) + except Exception as e: + self.fail("Failed to upgrade the network from VR to RVR: %s" % e) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return only one router" + ) + self.assertEqual( + len(routers), + 1, + "Length of the list router should be 1" + ) + return From b91978545acd2513754e20b7dfabcbf4b745dd0a Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 15:16:45 +0530 Subject: [PATCH 79/95] Don't wait for account gc Account GC is automatic, it's not required to wait for cleanup in the tearDown method Signed-off-by: Prasanna Santhanam --- test/integration/component/test_vpc.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index cc7069533db..742f6ae11eb 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -224,25 +224,7 @@ class TestVPC(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): From ffcd693afd4d2240a7d59122b3bbf8d298a3b1dd Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Wed, 19 Jun 2013 16:30:48 +0530 Subject: [PATCH 80/95] CLOUDSTACK-3056:Intelligence mechanism on the UI in case of addVmwareDC API call failure --- ui/scripts/zoneWizard.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 046b12210ac..84d19e890f2 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -3394,7 +3394,13 @@ } }); } - } + }, + + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addCluster', errorMsg, { fn: 'addCluster', args: args }); + } + }); } else{ From 7d6b4a4a97ff6c2b7cfa956e765f18b40bc10da0 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 16:52:45 +0530 Subject: [PATCH 81/95] Fix vpc network tests and reduce delay by removing wait for cleanup CIDR dictionary changes in the test causing the subsequent test to fail. Reinitialize the dictionary at the beginning of the test Signed-off-by: Prasanna Santhanam --- test/integration/component/test_vpc.py | 24 +++--- .../integration/component/test_vpc_network.py | 78 +++---------------- 2 files changed, 20 insertions(+), 82 deletions(-) diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 742f6ae11eb..63c10aacdb2 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -202,7 +202,6 @@ class TestVPC(cloudstackTestCase): cls.vpc_off.update(cls.api_client, state='Enabled') cls._cleanup = [ cls.service_offering, - cls.vpc_off ] return @@ -435,7 +434,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_04_delete_vpc_with_networks(self): - """ Test delete VPC having with networks + """ Test delete VPC having networks """ # Validate the following @@ -757,7 +756,7 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"], ) - self.cleanup.append(self.user) + self._cleanup.append(self.user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -1841,7 +1840,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_13_deploy_vm_with_vpc_netdomain(self): - """ Test deployment of vm in a VPC with netdomain + """ Test deployment of vm in a VPC with network domain """ # 1. Create VPC with providing networkDomain. @@ -1918,7 +1917,7 @@ class TestVPC(cloudstackTestCase): self.services["account"] ) self.debug("Created account: %s" % user.name) - self.cleanup.append(user) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -1999,7 +1998,7 @@ class TestVPC(cloudstackTestCase): self.services["account"] ) self.debug("Created account: %s" % user.name) - self.cleanup.append(user) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -2075,7 +2074,7 @@ class TestVPC(cloudstackTestCase): self.services["account"] ) self.debug("Created account: %s" % user.name) - self.cleanup.append(user) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -2159,7 +2158,7 @@ class TestVPC(cloudstackTestCase): self.services["domain_admin"] ) self.debug("Created account: %s" % domain_admin.name) - self.cleanup.append(domain_admin) + self._cleanup.append(domain_admin) da_apiclient = self.testClient.getUserApiClient( account=domain_admin.name, domain=domain_admin.domain, @@ -2170,7 +2169,7 @@ class TestVPC(cloudstackTestCase): self.services["account"] ) self.debug("Created account: %s" % user.name) - self.cleanup.append(user) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -2194,8 +2193,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_18_create_net_for_user_diff_domain_by_doadmin(self): - """ Test creation of network by domain admin for user from different - domain. + """ Test creation of network by domain admin for user from different domain """ #1. As domain admin account , Create VPC(name,zoneId,cidr,vpcOfferingId,networkDomain) without passing Account/domain ID. @@ -2211,7 +2209,7 @@ class TestVPC(cloudstackTestCase): self.services["domain_admin"] ) self.debug("Created account: %s" % domain_admin.name) - self.cleanup.append(domain_admin) + self._cleanup.append(domain_admin) da_apiclient = self.testClient.getUserApiClient( account=domain_admin.name, domain=self.services["domain"]["name"], @@ -2222,7 +2220,7 @@ class TestVPC(cloudstackTestCase): self.services["account"] ) self.debug("Created account: %s" % user.name) - self.cleanup.append(user) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % diff --git a/test/integration/component/test_vpc_network.py b/test/integration/component/test_vpc_network.py index 9d5081f8e95..d76996ae85b 100644 --- a/test/integration/component/test_vpc_network.py +++ b/test/integration/component/test_vpc_network.py @@ -72,7 +72,6 @@ class Services: }, "serviceCapabilityList": { "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"} }, }, "network_off_netscaler": { @@ -95,7 +94,6 @@ class Services: }, "serviceCapabilityList": { "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"} }, }, "network_off_shared": { @@ -229,25 +227,7 @@ class TestVPCNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -394,7 +374,7 @@ class TestVPCNetwork(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_create_network_fail(self): - """ Test create network in VPC + """ Test create network in VPC mismatched services (Should fail) """ # Validate the following @@ -712,7 +692,7 @@ class TestVPCNetwork(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_06_create_network_with_rvr(self): - """ Test create network with eredundant router capability + """ Test create network with redundant router capability """ # Validate the following @@ -1094,25 +1074,7 @@ class TestVPCNetworkRanges(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -1365,6 +1327,7 @@ class TestVPCNetworkRanges(cloudstackTestCase): # 3. Add network2 with cidr - 10.1.1.1/24 to this VPC # 4. Add network3 with cidr - 10.1.1.1/26 to this VPC # 5. Network creation in step 3 & 4 should fail. + self.services = Services().services self.debug("Creating a VPC offering") vpc_off = VpcOffering.create( @@ -1606,19 +1569,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - wait_for_cleanup(self.apiclient, [ - "network.gc.interval", - "network.gc.wait"]) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -1673,8 +1624,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_01_network_services_upgrade(self): - """ Test update Network that is part of a VPC to a network offering - that has more services. + """ Test update Network that is part of a VPC to a network offering that has more services """ # Validate the following @@ -2027,8 +1977,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_network_vpcvr2vr_upgrade(self): - """ Test update Network that is NOT part of a VPC to a nw offering - that has services that are provided by VPCVR and vice versa. + """ Test update Network that is NOT part of a VPC to a nw offering that has services that are provided by VPCVR and vice versa """ # Validate the following @@ -2298,7 +2247,6 @@ class TestVPCNetworkGc(cloudstackTestCase): cmd = stopVirtualMachine.stopVirtualMachineCmd() cmd.id = vm.id self.apiclient.stopVirtualMachine(cmd) - self.cleanup = [] return def tearDown(self): @@ -2311,15 +2259,7 @@ class TestVPCNetworkGc(cloudstackTestCase): ) for vm in vms: if vm.state == "Stopped": - cmd = startVirtualMachine.startVirtualMachineCmd() - cmd.id = vm.id - self.apiclient.startVirtualMachine(cmd) - - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + vm.start(self.apiclient) return def validate_vpc_offering(self, vpc_offering): From 1af928570cba3d6df8e74e34bc3e26c1f3512aec Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 17 Jun 2013 18:50:56 +0530 Subject: [PATCH 82/95] CLOUDSTACK-3062. Dedication of a guest vlan range that extends 2 ranges dedicated to different accounts removes an old dedication --- .../com/cloud/network/NetworkServiceImpl.java | 76 ++++++++++++------- .../network/DedicateGuestVlanRangesTest.java | 4 +- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index aace68d9642..6796adc3dae 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -27,6 +27,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -2949,6 +2951,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { String updatedVlanRange = null; long guestVlanMapId = 0; long guestVlanMapAccountId = 0; + long vlanOwnerId = 0; // Verify account is valid Account vlanOwner = null; @@ -2969,6 +2972,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Unable to find account by name " + accountName); } } + vlanOwnerId = vlanOwner.getAccountId(); // Verify physical network isolation type is VLAN PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -3024,40 +3028,59 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } List guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId); + // Verify if vlan range is already dedicated for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) { List vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange()); int dedicatedStartVlan = vlanTokens.get(0).intValue(); int dedicatedEndVlan = vlanTokens.get(1).intValue(); - guestVlanMapId = guestVlanMap.getId(); - guestVlanMapAccountId = guestVlanMap.getAccountId(); - - // Verify if range is already dedicated - if (startVlan >= dedicatedStartVlan && endVlan <= dedicatedEndVlan) { - if (guestVlanMap.getAccountId() != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is already dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } else { - s_logger.debug("Vlan range " + vlan +" is already dedicated to the specified account" + accountName); - return guestVlanMap; - } - } - // Verify if range overlaps with an existing range - if (startVlan < dedicatedStartVlan & endVlan+1 >= dedicatedStartVlan & endVlan <= dedicatedEndVlan) { // extend to the left - updatedVlanRange = startVlan + "-" + dedicatedEndVlan; - break; - } else if (startVlan >= dedicatedStartVlan & startVlan-1 <= dedicatedEndVlan & endVlan > dedicatedEndVlan) { // extend to right - updatedVlanRange = dedicatedStartVlan + "-" + endVlan; - break; - } else if (startVlan < dedicatedStartVlan & endVlan > dedicatedEndVlan){ // extend to the left and right - updatedVlanRange = startVlan + "-" + endVlan; - break; + if ((startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan) || + (startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan)) { + throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + + " dedicate guest vlan range " + vlan); } } + // Sort the existing dedicated vlan ranges + Collections.sort(guestVlanMaps, new Comparator() { + @Override + public int compare( AccountGuestVlanMapVO obj1 , AccountGuestVlanMapVO obj2) { + List vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange()); + List vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange()); + return vlanTokens1.get(0).compareTo(vlanTokens2.get(0)); + } + }); + + // Verify if vlan range extends an already dedicated range + for (int i=0; i < guestVlanMaps.size(); i++) { + guestVlanMapId = guestVlanMaps.get(i).getId(); + guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId(); + List vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange()); + // Range extends a dedicated vlan range to the left + if (endVlan == (vlanTokens1.get(0).intValue()-1)) { + if(guestVlanMapAccountId == vlanOwnerId) { + updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue(); + } + break; + } + // Range extends a dedicated vlan range to the right + if (startVlan == (vlanTokens1.get(1).intValue()+1) & guestVlanMapAccountId == vlanOwnerId) { + if (i != (guestVlanMaps.size()-1)) { + List vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i+1).getGuestVlanRange()); + // Range extends 2 vlan ranges, both to the right and left + if (endVlan == (vlanTokens2.get(0).intValue()-1) & guestVlanMaps.get(i+1).getAccountId() == vlanOwnerId) { + _datacneter_vnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i+1).getId()); + _accountGuestVlanMapDao.remove(guestVlanMaps.get(i+1).getId()); + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue(); + break; + } + } + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan; + break; + } + } + // Dedicate vlan range AccountGuestVlanMapVO accountGuestVlanMapVO; if (updatedVlanRange != null) { - if (guestVlanMapAccountId != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is partially dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId); accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange); _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO); @@ -3070,7 +3093,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { txn.commit(); } // For every guest vlan set the corresponding account guest vlan map id - for (int i = startVlan; i <= endVlan; i++) { + List finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange()); + for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) { List dataCenterVnet = _datacneter_vnet.findVnet(physicalNetwork.getDataCenterId(),((Integer)i).toString()); dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId()); _datacneter_vnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0)); diff --git a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java index e81d7222a60..e5d33296b00 100644 --- a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java +++ b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java @@ -291,7 +291,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangeDedicatedRange"); } @@ -320,7 +320,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is partially dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangePartiallyDedicated"); } From c8f744dbc36b192620c8b494cc41cfb18e1d81be Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 19 Jun 2013 17:05:24 +0530 Subject: [PATCH 83/95] Prevent waits at cleanup Do not wait until gc finishes cleanup of resources. This delays tests and is dependant on the deployment. Some have large cleanup.intervals. Assume cleanup succeeds and proceed Signed-off-by: Prasanna Santhanam --- .../component/test_vpc_offerings.py | 52 ++++--------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/test/integration/component/test_vpc_offerings.py b/test/integration/component/test_vpc_offerings.py index a111d7d9059..cf37d907d5e 100644 --- a/test/integration/component/test_vpc_offerings.py +++ b/test/integration/component/test_vpc_offerings.py @@ -130,7 +130,6 @@ class Services: # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, - "mode": 'advanced' } @@ -181,36 +180,7 @@ class TestVPCOffering(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offering - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -273,7 +243,7 @@ class TestVPCOffering(cloudstackTestCase): ) self.debug("Check if the VPC offering is created successfully?") - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) return @@ -581,7 +551,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -700,7 +670,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -821,7 +791,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -934,7 +904,7 @@ class TestVPCOffering(cloudstackTestCase): ) self.validate_vpc_offering(vpc_off) # Appending to cleanup to delete after test - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) except Exception as e: self.fail("Failed to create the VPC offering - %s" % e) return @@ -958,7 +928,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -1054,7 +1024,7 @@ class TestVPCOffering(cloudstackTestCase): self.apiclient, self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_1) + self._cleanup.append(vpc_off_1) self.validate_vpc_offering(vpc_off_1) self.debug("Disabling the VPC offering created") vpc_off_1.update(self.apiclient, state='Disabled') @@ -1064,7 +1034,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_2) + self._cleanup.append(vpc_off_2) self.validate_vpc_offering(vpc_off_2) self.debug("Enabling the VPC offering created") vpc_off_2.update(self.apiclient, state='Enabled') @@ -1074,7 +1044,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_3) + self._cleanup.append(vpc_off_3) self.validate_vpc_offering(vpc_off_3) self.debug("Enabling the VPC offering created") vpc_off_3.update(self.apiclient, state='Enabled') @@ -1083,7 +1053,7 @@ class TestVPCOffering(cloudstackTestCase): self.apiclient, self.services["vpc_offering"] ) - self.validate_vpc_offering(vpc_off_4) + self._cleanup.append(vpc_off_4) self.debug("Enabling the VPC offering created") vpc_off_4.update(self.apiclient, state='Enabled') From 2d678063fac318776f60b7f3b1d27323cac06dfc Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 19 Jun 2013 15:37:39 +0200 Subject: [PATCH 84/95] Shared networks is only supported in Basic zone and Advanced zone with SG in Infracstructure->Zone->Physical Network->Guest->Network --- ui/scripts/system.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 452249ae512..7d0ea37e891 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1321,6 +1321,20 @@ } }, + preFilter: function(args) { //Isolated networks is only supported in Advanced (SG-disabled) zone + if(selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled != true) + return false; + else + return true; + }, + + preFilter: function(args) { //Shared networks is only supported in Basic zone and Advanced zone with SG + if(selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled != true) + return false; + else + return true; + }, + createForm: { title: 'label.add.guest.network', //Add guest network in advanced zone From 5e5bb2cae7917cf5f16d74fdd5b299eff0599588 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 19 Jun 2013 15:46:51 +0200 Subject: [PATCH 85/95] remove duplicate lines of 2d678063fac318776f60b7f3b1d27323cac06dfc --- ui/scripts/system.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 7d0ea37e891..6e61397fe4b 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1321,13 +1321,6 @@ } }, - preFilter: function(args) { //Isolated networks is only supported in Advanced (SG-disabled) zone - if(selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled != true) - return false; - else - return true; - }, - preFilter: function(args) { //Shared networks is only supported in Basic zone and Advanced zone with SG if(selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled != true) return false; From fe8eca2c76ee4a7be1f50cb2ee9c854caee59ecf Mon Sep 17 00:00:00 2001 From: Joe Brockmeier Date: Wed, 19 Jun 2013 09:59:52 -0500 Subject: [PATCH 86/95] Correcting URLs in building-devcloud.xml for Confluence changeover. --- docs/en-US/building-devcloud.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en-US/building-devcloud.xml b/docs/en-US/building-devcloud.xml index 5f792c375a2..f3c4d19a5d9 100644 --- a/docs/en-US/building-devcloud.xml +++ b/docs/en-US/building-devcloud.xml @@ -27,6 +27,6 @@ The DevCloud appliance can be downloaded from the wiki at . It can also be built from scratch. Code is being developed to provide this alternative build. It is based on veewee, Vagrant and Puppet. The goal is to automate the DevCloud build and make this automation capability available to all within the source release of &PRODUCT; This is under heavy development. The code is located in the source tree under tools/devcloud - A preliminary wiki page describes the build at https://cwiki.pache.org/CLOUDSTACK/building-devcloud.html + A preliminary wiki page describes the build at https://cwiki.apache.org/confluence/display/CLOUDSTACK/Building+DevCloud
From 5140473f2b754c1f178aae7946798d95027ec69a Mon Sep 17 00:00:00 2001 From: Girish Shilamkar Date: Wed, 19 Jun 2013 20:26:43 +0530 Subject: [PATCH 87/95] CLOUDSTACK-1758: Fix ssvm test failures, where ssh to ssvm failed. Signed-off-by: Prasanna Santhanam --- test/integration/smoke/test_ssvm.py | 42 ++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/test/integration/smoke/test_ssvm.py b/test/integration/smoke/test_ssvm.py index d637f966a0b..6893472ebe1 100644 --- a/test/integration/smoke/test_ssvm.py +++ b/test/integration/smoke/test_ssvm.py @@ -334,7 +334,19 @@ class TestSSVMs(cloudstackTestCase): self.debug("Running SSVM check script") - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for Vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + ssvm.privateip, + "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], @@ -358,7 +370,19 @@ class TestSSVMs(cloudstackTestCase): ) #Check status of cloud service - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for Vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + ssvm.privateip, + "service cloud status", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], @@ -426,7 +450,19 @@ class TestSSVMs(cloudstackTestCase): self.debug("Checking cloud process status") - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + cpvm.privateip, + "service cloud status", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], From d66e9c7b518895c28461118523698b6a7f0fd830 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 18 Jun 2013 14:56:07 -0700 Subject: [PATCH 88/95] CLOUDSTACK-2843: Provideded an ability to turn off the synchronization being done on the CS agent side, for number of commands participating in Vm deployment process, as parallel deployment is supported on the hypervisor side. The behavior is controlled by global config varirables: "execute.in.sequence.hypervisor.commands" (false by default) sets/resets the synchronization for commands: ========================= StartCommand StopCommand CreateCommand CopyVolumeCommand "execute.in.sequence.network.element.commands" (false by default) sets/resets the synchronization for commands: ========================== DhcpEntryCommand SavePasswordCommand UserDataCommand VmDataCommand As a part of the fix, increased the global lock timeout to 30 mins in several VR scripts: =========================== edithosts.sh savepassword.sh userdata.sh to support situations when multiple concurrent calls to the script are being made. --- api/src/com/cloud/network/NetworkModel.java | 2 ++ .../src/com/cloud/agent/api/StartCommand.java | 10 +++--- core/src/com/cloud/agent/api/StopCommand.java | 15 ++++++--- .../agent/api/routing/DhcpEntryCommand.java | 10 +++--- .../api/routing/SavePasswordCommand.java | 6 ++-- .../agent/api/routing/UserDataCommand.java | 6 ++-- .../agent/api/routing/VmDataCommand.java | 10 +++--- .../agent/api/storage/CopyVolumeCommand.java | 6 ++-- .../agent/api/storage/CreateCommand.java | 32 +++++++++++-------- .../motion/AncientDataMotionStrategy.java | 18 +++++++---- .../systemvm/debian/config/root/edithosts.sh | 4 ++- .../debian/config/root/savepassword.sh | 4 ++- .../systemvm/debian/config/root/userdata.sh | 4 ++- .../BaremetalDhcpManagerImpl.java | 5 ++- .../BaremetalPxeManagerImpl.java | 4 ++- .../CloudStackPrimaryDataStoreDriverImpl.java | 10 +++--- .../src/com/cloud/configuration/Config.java | 8 +++-- .../src/com/cloud/network/NetworkManager.java | 1 + .../com/cloud/network/NetworkManagerImpl.java | 4 +-- .../com/cloud/network/NetworkModelImpl.java | 11 +++++++ .../element/CloudZonesNetworkElement.java | 4 +-- .../VirtualNetworkApplianceManagerImpl.java | 7 ++-- .../com/cloud/server/ManagementServer.java | 2 ++ .../cloud/server/ManagementServerImpl.java | 14 ++++++-- .../cloud/vm/VirtualMachineManagerImpl.java | 15 +++++---- .../cloud/network/MockNetworkModelImpl.java | 6 ++++ .../com/cloud/vpc/MockNetworkModelImpl.java | 6 ++++ setup/db/db/schema-410to420.sql | 4 +++ 28 files changed, 155 insertions(+), 73 deletions(-) diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 05307eb47aa..ea39d835eb7 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -274,4 +274,6 @@ public interface NetworkModel { Networks.IsolationType[] listNetworkIsolationMethods(); Nic getNicInNetworkIncludingRemoved(long vmId, long networkId); + + boolean getExecuteInSeqNtwkElmtCmd(); } \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index ec707d6e851..308730ab5b7 100644 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -24,6 +24,7 @@ import com.cloud.host.Host; public class StartCommand extends Command { VirtualMachineTO vm; String hostIp; + boolean executeInSequence = false; public VirtualMachineTO getVirtualMachine() { return vm; @@ -31,19 +32,16 @@ public class StartCommand extends Command { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } protected StartCommand() { } - public StartCommand(VirtualMachineTO vm) { - this.vm = vm; - } - - public StartCommand(VirtualMachineTO vm, Host host) { + public StartCommand(VirtualMachineTO vm, Host host, boolean executeInSequence) { this.vm = vm; this.hostIp = host.getPrivateIpAddress(); + this.executeInSequence = executeInSequence; } public String getHostIp() { diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index 1c67f3816ca..a3ee3c967d3 100755 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -23,28 +23,33 @@ public class StopCommand extends RebootCommand { private boolean isProxy=false; private String urlPort=null; private String publicConsoleProxyIpAddress=null; + boolean executeInSequence = false; protected StopCommand() { } - public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress) { + public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence) { super(vm); this.isProxy = isProxy; this.urlPort = urlPort; this.publicConsoleProxyIpAddress = publicConsoleProxyIpAddress; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm, String vnet) { + public StopCommand(VirtualMachine vm, String vnet, boolean executeInSequence) { super(vm); this.vnet = vnet; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm) { + public StopCommand(VirtualMachine vm, boolean executeInSequence) { super(vm); + this.executeInSequence = executeInSequence; } - public StopCommand(String vmName) { + public StopCommand(String vmName, boolean executeInSequence) { super(vmName); + this.executeInSequence = executeInSequence; } public String getVnet() { @@ -53,7 +58,7 @@ public class StopCommand extends RebootCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public boolean isProxy() { diff --git a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index fd8d84c8c3a..d51ea5e70b5 100644 --- a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -32,6 +32,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String ip6Gateway; String duid; private boolean isDefault; + boolean executeInSequence = false; protected DhcpEntryCommand() { @@ -39,19 +40,20 @@ public class DhcpEntryCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address) { + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, boolean executeInSequence) { this.vmMac = vmMac; this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; this.setDefault(true); + this.executeInSequence = executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { - this(vmMac, vmIpAddress, vmName, vmIp6Address); + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway, boolean executeInSequence) { + this(vmMac, vmIpAddress, vmName, vmIp6Address, executeInSequence); this.dns = dns; this.gateway = gateway; } diff --git a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java index 6dac1488e11..c77dbf60987 100644 --- a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java +++ b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java @@ -22,19 +22,21 @@ public class SavePasswordCommand extends NetworkElementCommand { String password; String vmIpAddress; String vmName; + boolean executeInSequence = false; protected SavePasswordCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public SavePasswordCommand(String password, String vmIpAddress, String vmName) { + public SavePasswordCommand(String password, String vmIpAddress, String vmName, boolean executeInSequence) { this.password = password; this.vmIpAddress = vmIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getPassword() { diff --git a/core/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java index f7b38c8c364..cf360023abc 100644 --- a/core/src/com/cloud/agent/api/routing/UserDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/UserDataCommand.java @@ -23,6 +23,7 @@ public class UserDataCommand extends NetworkElementCommand { String vmIpAddress; String routerPrivateIpAddress; String vmName; + boolean executeInSequence = false; protected UserDataCommand() { @@ -30,14 +31,15 @@ public class UserDataCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName) { + public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName, boolean executeInSequence) { this.userData = userData; this.vmIpAddress = vmIpAddress; this.routerPrivateIpAddress = routerPrivateIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getRouterPrivateIpAddress() { diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java index df882554479..861f7006432 100644 --- a/core/src/com/cloud/agent/api/routing/VmDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/VmDataCommand.java @@ -28,27 +28,29 @@ public class VmDataCommand extends NetworkElementCommand { String vmName; @LogLevel(Log4jLevel.Trace) List vmData; + boolean executeInSequence = false; protected VmDataCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public VmDataCommand(String vmIpAddress) { - this(vmIpAddress, null); + public VmDataCommand(String vmIpAddress, boolean executeInSequence) { + this(vmIpAddress, null, executeInSequence); } public String getVmName() { return vmName; } - public VmDataCommand(String vmIpAddress, String vmName) { + public VmDataCommand(String vmIpAddress, String vmName, boolean executeInSequence) { this.vmName = vmName; this.vmIpAddress = vmIpAddress; this.vmData = new ArrayList(); + this.executeInSequence = executeInSequence; } diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 3d05e9ba69c..1acf2cc13f1 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -28,22 +28,24 @@ public class CopyVolumeCommand extends Command { String secondaryStorageURL; boolean toSecondaryStorage; String vmName; + boolean executeInSequence = false; public CopyVolumeCommand() { } - public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait) { + public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait, boolean executeInSequence) { this.volumeId = volumeId; this.volumePath = volumePath; this.pool = new StorageFilerTO(pool); this.secondaryStorageURL = secondaryStorageURL; this.toSecondaryStorage = toSecondaryStorage; setWait(wait); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getVolumePath() { diff --git a/core/src/com/cloud/agent/api/storage/CreateCommand.java b/core/src/com/cloud/agent/api/storage/CreateCommand.java index fd0375aa6e7..900abfd744e 100644 --- a/core/src/com/cloud/agent/api/storage/CreateCommand.java +++ b/core/src/com/cloud/agent/api/storage/CreateCommand.java @@ -26,6 +26,7 @@ public class CreateCommand extends Command { private StorageFilerTO pool; private DiskProfile diskCharacteristics; private String templateUrl; + boolean executeInSequence = false; protected CreateCommand() { super(); @@ -33,44 +34,47 @@ public class CreateCommand extends Command { /** * Construction for template based volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param templateUrl * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool) { - this(diskCharacteristics, pool); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool, boolean executeInSequence) { + this(diskCharacteristics, pool, executeInSequence); this.templateUrl = templateUrl; + this.executeInSequence = executeInSequence; } /** * Construction for regular volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool) { + public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool, boolean executeInSequence) { this.volId = diskCharacteristics.getVolumeId(); this.diskCharacteristics = diskCharacteristics; this.pool = pool; this.templateUrl = null; + this.executeInSequence = executeInSequence; } - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool) { - this(diskCharacteristics, templateUrl, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, templateUrl, new StorageFilerTO(pool), executeInSequence); } - public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool) { - this(diskCharacteristics, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, new StorageFilerTO(pool), executeInSequence); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getTemplateUrl() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index a6880c3f548..cb7940e94e4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -50,11 +50,11 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.MigrateVolumeAnswer; -import com.cloud.agent.api.storage.MigrateVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.storage.MigrateVolumeAnswer; +import com.cloud.agent.api.storage.MigrateVolumeCommand; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; @@ -67,6 +67,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.server.ManagementServer; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; @@ -138,6 +139,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject + private ManagementServer _mgmtServer; + + protected boolean _executeInSequence; + @Override public boolean canHandle(DataObject srcData, DataObject destData) { @@ -165,7 +171,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { StoragePool destPool = (StoragePool) destData.getDataStore(); CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(), volumeUUID, destPool, secondaryStorageURL, false, - _copyvolumewait); + _copyvolumewait, _mgmtServer.getExecuteInSequence()); CopyVolumeAnswer cvAnswer = null; String errMsg = null; try { @@ -321,7 +327,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { null); CreateCommand cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO((StoragePool)template.getDataStore())); + new StorageFilerTO((StoragePool)template.getDataStore()), _mgmtServer.getExecuteInSequence()); Answer answer = null; StoragePool pool = (StoragePool)volume.getDataStore(); String errMsg = null; @@ -375,7 +381,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, - _copyvolumewait); + _copyvolumewait, _mgmtServer.getExecuteInSequence()); CopyVolumeAnswer cvAnswer; try { cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd); @@ -394,7 +400,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { cvCmd = new CopyVolumeCommand(volume.getId(), secondaryStorageVolumePath, destPool, - secondaryStorageURL, false, _copyvolumewait); + secondaryStorageURL, false, _copyvolumewait, _mgmtServer.getExecuteInSequence()); try { cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd); } catch (StorageUnavailableException e1) { diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index fb0c34fbd42..eaa82927803 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -69,7 +69,9 @@ HOSTS=/etc/hosts source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as DhcpEntryCommand is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/savepassword.sh b/patches/systemvm/debian/config/root/savepassword.sh index a096b862fce..fc736039c2e 100755 --- a/patches/systemvm/debian/config/root/savepassword.sh +++ b/patches/systemvm/debian/config/root/savepassword.sh @@ -25,7 +25,9 @@ source /root/func.sh lock="passwdlock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as password reset command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/userdata.sh b/patches/systemvm/debian/config/root/userdata.sh index e5d170b5b23..f9ea644c2fd 100644 --- a/patches/systemvm/debian/config/root/userdata.sh +++ b/patches/systemvm/debian/config/root/userdata.sh @@ -21,7 +21,9 @@ source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as userdata command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java index f87bf71ca13..c749211e375 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java @@ -53,6 +53,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; @@ -100,6 +101,8 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; @Inject BaremetalDhcpDao _extDhcpDao; + @Inject + NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -147,7 +150,7 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh dns = nic.getDns2(); } DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), null, dns, - nic.getGateway(), null); + nic.getGateway(), null, _ntwkModel.getExecuteInSeqNtwkElmtCmd()); String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()); // prepareBareMetalDhcpEntry(nic, dhcpCommand); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index 59a28117cb5..04f5fbc34a7 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -45,6 +45,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.network.NetworkModel; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.resource.ResourceManager; @@ -81,6 +82,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe @Inject NicDao _nicDao; @Inject ConfigurationDao _configDao; @Inject PhysicalNetworkDao _phynwDao; + @Inject NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -184,7 +186,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); NicVO nvo = _nicDao.findById(nic.getId()); - VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName()); + VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", vm.getUserData()); cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 04869020468..fa099d31b9f 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -49,11 +49,12 @@ import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.server.ManagementServer; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ResizeVolumePayload; +import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateHostVO; @@ -85,6 +86,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject SnapshotDao snapshotDao; @Inject PrimaryDataStoreDao primaryStoreDao; @Inject SnapshotManager snapshotMgr; + @Inject ManagementServer _mgmtSrvr; @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -152,7 +154,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath(); cmd = new CreateCommand(diskProfile, fullTmpltUrl, - new StorageFilerTO(pool)); + new StorageFilerTO(pool), _mgmtSrvr.getExecuteInSequence()); } else { tmpltStoredOn = templateMgr.prepareTemplateForCreate( template, pool); @@ -166,7 +168,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO(pool)); + new StorageFilerTO(pool), _mgmtSrvr.getExecuteInSequence()); } } else { if (template != null @@ -180,7 +182,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } } cmd = new CreateCommand(diskProfile, new StorageFilerTO( - pool)); + pool), _mgmtSrvr.getExecuteInSequence()); } Answer answer = storageMgr.sendToPool(pool, null, cmd); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index f6fa97418bd..3c73783792c 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -426,9 +426,11 @@ public enum Config { BlacklistedRoutes("Advanced", VpcManager.class, String.class, "blacklisted.routes", null, "Routes that are blacklisted, can not be used for Static Routes creation for the VPC Private Gateway", "routes", ConfigurationParameterScope.zone.toString()), - InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null); - - + InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null), + ExecuteInSequence("Advanced", ManagementServer.class, Boolean.class, "execute.in.sequence.hypervisor.commands", "false", "If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null), + ExecuteInSequenceNetworkElementCommands("Advanced", NetworkManager.class, Boolean.class, "execute.in.sequence.network.element.commands", "false", "If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null); private final String _category; private final Class _componentClass; diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index bc43daa9975..306169ebcf6 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -386,4 +386,5 @@ public interface NetworkManager { DhcpServiceProvider getDhcpServiceProvider(Network network); PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 274e79468e2..745fe2344d4 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1234,7 +1234,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _configs = _configDao.getConfiguration("AgentManager", params); _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600); _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); - + _configs = _configDao.getConfiguration("Network", params); _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600); @@ -4364,5 +4364,5 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L nic.setVmType(vmType); return _nicDao.persist(nic); } - + } diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index fa34d65ab1a..4a4da8e3f4f 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -208,11 +208,16 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { private boolean _allowSubdomainNetworkAccess; private Map _configs; + + protected boolean _executeInSequenceNtwkElmtCmd; HashMap _lastNetworkIdsToFree = new HashMap(); static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); static HashMap s_providerToNetworkElementMap = new HashMap(); + + + /** * */ @@ -1869,6 +1874,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { _configs = _configDao.getConfiguration("Network", params); _networkDomain = _configs.get(Config.GuestDomainSuffix.key()); _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key())); + _executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key())); NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, true); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); @@ -2112,4 +2118,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { public Networks.IsolationType[] listNetworkIsolationMethods() { return Networks.IsolationType.values(); } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + return _executeInSequenceNtwkElmtCmd; + } } diff --git a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java index 320258b8d37..bdd8e61bbc2 100644 --- a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java +++ b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java @@ -152,7 +152,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem private VmDataCommand generateVmDataCommand(String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", userData); cmd.addVmData("metadata", "service-offering", serviceOffering); @@ -217,7 +217,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem Commands cmds = new Commands(OnError.Continue); if (password != null && nic.isDefaultNic()) { final String encodedPassword = PasswordGenerator.rot13(password); - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName(), _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmds.addCommand("password", cmd); } String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(uservm.getServiceOfferingId()).getDisplayText(); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 8edd5bd7b8f..752a4f343ce 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -166,6 +166,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; @@ -797,7 +798,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey, long guestNetworkId) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); @@ -3360,7 +3361,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER) { encodedPassword = PasswordGenerator.rot13("saved_password"); } - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName(), _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -3400,7 +3401,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } private void createDhcpEntryCommand(VirtualRouter router, UserVm vm, NicVO nic, Commands cmds) { - DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address()); + DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address(), _networkModel.getExecuteInSeqNtwkElmtCmd()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); Nic defaultNic = findGatewayIp(vm.getId()); String gatewayIp = defaultNic.getGateway(); diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index f60ce488e10..aec1be705dc 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -72,4 +72,6 @@ public interface ManagementServer extends ManagementService, PluggableService { String getEncryptionIV(); void resetEncryptionKeyIV(); + boolean getExecuteInSequence(); + } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index dea761df5da..cfc8333e9c8 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -766,6 +766,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe ConfigurationServer _configServer; @Inject UserVmManager _userVmMgr; + @Inject ClusterManager _clusterMgr; + private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); @@ -788,10 +790,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe this._planners = _planners; } - @Inject ClusterManager _clusterMgr; private String _hashKey = null; private String _encryptionKey = null; private String _encryptionIV = null; + protected boolean _executeInSequence; @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @@ -861,6 +863,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _availableIdsMap.put(id, true); } + _executeInSequence = Boolean.parseBoolean(_configDao.getValue(Config.ExecuteInSequence.key())); + return true; } @@ -3469,7 +3473,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe String value = _configs.get(Config.CopyVolumeWait.toString()); int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); // Copy the volume from the source storage pool to secondary storage - CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, copyvolumewait); + CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, copyvolumewait, _executeInSequence); CopyVolumeAnswer cvAnswer = null; try { cvAnswer = (CopyVolumeAnswer) _storageMgr.sendToPool(srcPool, cvCmd); @@ -4080,5 +4084,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return plannersAvailable; } - + + @Override + public boolean getExecuteInSequence() { + return _executeInSequence; + } } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f946cd1ebf6..58140750d74 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -130,6 +130,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -259,6 +260,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @Inject protected ConfigurationServer _configServer; + @Inject + protected ManagementServer _mgmtServer; protected List _planners; public List getPlanners() { @@ -857,7 +860,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); - cmds.addCommand(new StartCommand(vmTO, dest.getHost())); + cmds.addCommand(new StartCommand(vmTO, dest.getHost(), _mgmtServer.getExecuteInSequence())); vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); @@ -897,7 +900,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("The guru did not like the answers so stopping " + vm); } - StopCommand cmd = new StopCommand(vm); + StopCommand cmd = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); if (answer == null || !answer.getResult()) { s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); @@ -984,7 +987,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { VMInstanceVO vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); try { Answer answer = _agentMgr.send(vm.getHostId(), stop); if (!answer.getResult()) { @@ -1170,7 +1173,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac vmGuru.prepareStop(profile); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); boolean stopped = false; StopAnswer answer = null; try { @@ -1923,11 +1926,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public Command cleanup(VirtualMachine vm) { - return new StopCommand(vm); + return new StopCommand(vm, _mgmtServer.getExecuteInSequence()); } public Command cleanup(String vmName) { - return new StopCommand(vmName); + return new StopCommand(vmName, _mgmtServer.getExecuteInSequence()); } public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 3a367480a30..bab9df8dd6d 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -879,4 +879,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) { return null; } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 3e67f5e76e2..a6ab1261c3c 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -892,4 +892,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { return null; } + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index bcdf2d986d5..3c5b1bcb146 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1884,3 +1884,7 @@ UPDATE `cloud`.`networks` set name='Shared SG enabled network', display_text='Sh INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.public.ips', 'true', 'If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.guest.vlans', 'true', 'If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool'); + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.hypervisor.commands', 'false', 'If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.network.element.commands', 'false', 'If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); + From d5d0142ed4c14e5d4d8fe255486c1437730425a5 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 19 Jun 2013 10:18:52 -0700 Subject: [PATCH 89/95] CLOUDSTACK-3016: listZones API - take in networktype instead of zonetype parameter to be consistent with networktype property in ZoneResponse. --- api/src/org/apache/cloudstack/api/ApiConstants.java | 3 +-- .../cloudstack/api/command/user/zone/ListZonesByCmd.java | 8 ++++---- server/src/com/cloud/api/query/QueryManagerImpl.java | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 1704ca3d132..12e50978475 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -245,8 +245,7 @@ public class ApiConstants { public static final String IS_VOLATILE = "isvolatile"; public static final String VOLUME_ID = "volumeid"; public static final String ZONE_ID = "zoneid"; - public static final String ZONE_NAME = "zonename"; - public static final String ZONE_TYPE = "zonetype"; + public static final String ZONE_NAME = "zonename"; public static final String NETWORK_TYPE = "networktype"; public static final String PAGE = "page"; public static final String PAGE_SIZE = "pagesize"; diff --git a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java index ed31037407f..4cf3b58a0a8 100644 --- a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java @@ -57,8 +57,8 @@ public class ListZonesByCmd extends BaseListCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the zone") private String name; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; + @Parameter(name=ApiConstants.NETWORK_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") + private String networkType; @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the zones") private Boolean showCapacities; @@ -83,8 +83,8 @@ public class ListZonesByCmd extends BaseListCmd { return name; } - public String getZoneType() { - return zoneType; + public String getNetworkType() { + return networkType; } public Boolean getShowCapacities() { diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 10ab8f1475a..ad29cda576b 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2208,7 +2208,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Long id = cmd.getId(); String keyword = cmd.getKeyword(); String name = cmd.getName(); - String networkType = cmd.getZoneType(); + String networkType = cmd.getNetworkType(); Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _dcJoinDao.createSearchCriteria(); From 928d94265b3cfc06a2a98fa1d5123e752606bd02 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 19 Jun 2013 10:53:15 -0700 Subject: [PATCH 90/95] Added more logging to the place where VR investigates whether the user vm is alive, by executing PingCommand --- server/src/com/cloud/ha/UserVmDomRInvestigator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/ha/UserVmDomRInvestigator.java b/server/src/com/cloud/ha/UserVmDomRInvestigator.java index f785d183938..8b48c09dfa1 100644 --- a/server/src/com/cloud/ha/UserVmDomRInvestigator.java +++ b/server/src/com/cloud/ha/UserVmDomRInvestigator.java @@ -182,7 +182,8 @@ public class UserVmDomRInvestigator extends AbstractInvestigatorImpl { Answer pingTestAnswer = _agentMgr.easySend(hostId, new PingTestCommand(routerPrivateIp, privateIp)); if (pingTestAnswer!=null && pingTestAnswer.getResult()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("user vm " + vm.getHostName() + " has been successfully pinged, returning that it is alive"); + s_logger.debug("user vm's " + vm.getHostName() + " ip address "+ privateIp + " has been successfully pinged from the Virtual Router " + + router.getHostName() + ", returning that vm is alive"); } return Boolean.TRUE; } From 2d10ae7580018611919be070bc51818f476bc1e4 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 19 Jun 2013 11:49:05 -0700 Subject: [PATCH 91/95] CLOUDSTACK-3016: UI - (1) remove obsolete code that pass zonetype to API calls. (2) network menu: use listZones&networktype=Advanced to determine which section to show. --- ui/scripts/network.js | 61 +++++++++++++++++++++-------------- ui/scripts/sharedFunctions.js | 6 +--- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index ddde9c967e5..d18e796b9a6 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -274,40 +274,46 @@ } }; - var networkOfferingObjs = []; - var checkVpc=0; + var networkOfferingObjs = []; + var advZoneObjs; + cloudStack.sections.network = { title: 'label.network', id: 'network', sectionSelect: { preFilter: function(args) { - var havingSecurityGroupNetwork = false; - + var sectionsToShow = ['networks']; + + $.ajax({ + url: createURL('listZones'), + data: { + networktype: 'Advanced' + }, + async: false, + success: function(json) { + advZoneObjs = json.listzonesresponse.zone; + if(advZoneObjs != null && advZoneObjs.length > 0) { + sectionsToShow.push('vpc'); + sectionsToShow.push('vpnCustomerGateway'); + } + } + }); + $.ajax({ url: createURL('listNetworks', { ignoreProject: true }), data: { supportedServices: 'SecurityGroup', listAll: true, - details: 'min' + details: 'min' }, async: false, - success: function(data) { - if (data.listnetworksresponse.network != null && data.listnetworksresponse.network.length > 0) { - havingSecurityGroupNetwork = true; + success: function(json) { + if(json.listnetworksresponse.network != null && json.listnetworksresponse.network.length > 0) { + sectionsToShow.push('securityGroups'); } } }); - - var sectionsToShow = ['networks']; - - if(args.context.zoneType != 'Basic') { //Advanced type or all types - sectionsToShow.push('vpc'); - sectionsToShow.push('vpnCustomerGateway'); - } - - if(havingSecurityGroupNetwork == true) - sectionsToShow.push('securityGroups'); - + return sectionsToShow; }, @@ -323,11 +329,18 @@ add: { label: 'Add Isolated Guest Network with SourceNat', - preFilter: function(args) { //Isolated networks is only supported in Advanced (SG-disabled) zone - if(args.context.zoneType != 'Basic') - return true; - else - return false; + preFilter: function(args) { + if(advZoneObjs != null && advZoneObjs.length > 0) { + for(var i = 0; i < advZoneObjs.length; i++) { + if(advZoneObjs[i].securitygroupsenabled != true) { //'Add Isolated Guest Network with SourceNat' is only supported in Advanced SG-disabled zone + return true; + } + } + return false; + } + else{ + return false; + } }, createForm: { diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index d87f0dcb0ae..86dc68eaf4b 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -114,11 +114,7 @@ function createURL(apiName, options) { if (cloudStack.context && cloudStack.context.projects && !options.ignoreProject) { urlString = urlString + '&projectid=' + cloudStack.context.projects[0].id; } - - if(cloudStack.context != null && cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type - urlString = urlString + '&zonetype=' + cloudStack.context.zoneType; - } - + return urlString; } From fde6637f90d2466d9d99579ffb0f782adf2a8162 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 19 Jun 2013 20:59:02 +0200 Subject: [PATCH 92/95] Use the blacklist in modprobe as the bridge module might be blacklisted by the openvswitch installation. --- python/lib/cloudutils/networkConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lib/cloudutils/networkConfig.py b/python/lib/cloudutils/networkConfig.py index 9e456e970be..405a3be519c 100644 --- a/python/lib/cloudutils/networkConfig.py +++ b/python/lib/cloudutils/networkConfig.py @@ -82,7 +82,7 @@ class networkConfig: if os.path.exists("/proc/sys/net/bridge"): return True - return bash("modprobe bridge").isSucess() + return bash("modprobe -b bridge").isSucess() @staticmethod def isNetworkDev(devName): From 11b9d5ff6442aafede62502a59b035f52b28c633 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 19 Jun 2013 14:08:12 -0700 Subject: [PATCH 93/95] CLOUDSTACK-1405: add scope type in liststoragepoolcmd --- .../command/admin/storage/ListStoragePoolsCmd.java | 8 ++++++++ server/src/com/cloud/api/query/QueryManagerImpl.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index 85a3c22a3e2..f33b9877662 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -64,6 +64,10 @@ public class ListStoragePoolsCmd extends BaseListCmd { description="the ID of the storage pool") private Long id; + @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, entityType = StoragePoolResponse.class, + description="the ID of the storage pool") + private String scope; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -115,4 +119,8 @@ public class ListStoragePoolsCmd extends BaseListCmd { response.setResponseName(getCommandName()); this.setResponseObject(response); } + + public String getScope() { + return scope; + } } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index ad29cda576b..c851e3bcf8c 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -55,6 +55,7 @@ import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.response.*; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.query.QueryService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -1862,6 +1863,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } private Pair, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) { + ScopeType scopeType = null; + if (cmd.getScope() != null) { + try { + scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase()); + } catch (Exception e) { + throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope()); + } + } Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Object id = cmd.getId(); @@ -1922,6 +1931,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (cluster != null) { sc.setParameters("clusterId", cluster); } + if (scopeType != null) { + sc.setParameters("scope", scopeType.toString()); + } // search Pool details by ids Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter); From 5cd6d6944a5b80aa401587c90fb0f69863ec4a96 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 19 Jun 2013 14:12:19 -0700 Subject: [PATCH 94/95] CLOUDSTACK-3015: VPC virtual router lists deleted nics --- setup/db/db/schema-410to420.sql | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 3c5b1bcb146..c782234ff2e 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -974,15 +974,11 @@ CREATE VIEW `cloud`.`domain_router_view` AS left join `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id left join - `cloud`.`volumes` ON vm_instance.id = volumes.instance_id - left join - `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id - left join - `cloud`.`nics` ON vm_instance.id = nics.instance_id + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null left join `cloud`.`networks` ON nics.network_id = networks.id left join - `cloud`.`vpc` ON domain_router.vpc_id = vpc.id + `cloud`.`vpc` ON domain_router.vpc_id = vpc.id and vpc.removed is null left join `cloud`.`async_job` ON async_job.instance_id = vm_instance.id and async_job.instance_type = 'DomainRouter' @@ -1452,7 +1448,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS data_center.uuid data_center_uuid, data_center.name data_center_name, data_center.is_security_group_enabled security_group_enabled, - data_center.networktype data_center_type, + data_center.networktype data_center_type, host.id host_id, host.uuid host_uuid, host.name host_name, @@ -1564,11 +1560,11 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id left join - `cloud`.`nics` ON vm_instance.id = nics.instance_id + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null left join `cloud`.`networks` ON nics.network_id = networks.id left join - `cloud`.`vpc` ON networks.vpc_id = vpc.id + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null left join `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id left join From 0a4e65126fd297a7e04ee746b51ebd0cd8137998 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 19 Jun 2013 14:38:25 -0700 Subject: [PATCH 95/95] CLOUDSTACK-3079: Use global var "ping.timeout" as a multiplier to ping.interval before announcing an agent has timed out. The multiplier used to be hardcoded to 3 --- .../com/cloud/agent/manager/ClusteredAgentManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 3ce60b79107..19f0102d173 100755 --- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -173,8 +173,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust s_logger.trace("Begin scanning directly connected hosts"); } - // for agents that are self-managed, threshold to be considered as disconnected is 3 ping intervals - long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingInterval * 3); + // for agents that are self-managed, threshold to be considered as disconnected after pingtimeout + long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingTimeout); List hosts = _hostDao.findAndUpdateDirectAgentToLoad(cutSeconds, _loadSize, _nodeId); List appliances = _hostDao.findAndUpdateApplianceToLoad(cutSeconds, _nodeId); hosts.addAll(appliances);