mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1128 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1128 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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.
 | |
| """ P1 tests for Resource limits
 | |
| """
 | |
| #Import Local Modules
 | |
| from nose.plugins.attrib import attr
 | |
| from marvin.cloudstackTestCase import cloudstackTestCase
 | |
| import unittest
 | |
| #from marvin.cloudstackAPI import *
 | |
| from marvin.lib.utils import (cleanup_resources,
 | |
|                               validateList)
 | |
| from marvin.lib.base import (Account,
 | |
|                              Domain,
 | |
|                              Project,
 | |
|                              Template,
 | |
|                              Snapshot,
 | |
|                              Volume,
 | |
|                              NetworkOffering,
 | |
|                              ServiceOffering,
 | |
|                              VirtualMachine,
 | |
|                              DiskOffering,
 | |
|                              Configurations,
 | |
|                              Network,
 | |
|                              PublicIPAddress)
 | |
| from marvin.lib.common import (get_domain,
 | |
|                                get_zone,
 | |
|                                get_template,
 | |
|                                list_snapshots,
 | |
|                                list_volumes,
 | |
|                                list_configurations,
 | |
|                                list_resource_limits,
 | |
|                                update_resource_limit,
 | |
|                                get_builtin_template_info,
 | |
|                                find_storage_pool_type)
 | |
| from marvin.codes import PASS
 | |
| import time
 | |
| 
 | |
| class Services:
 | |
|     """Test Resource Limits Services
 | |
|     """
 | |
| 
 | |
|     def __init__(self):
 | |
|         self.services = {
 | |
|                         "domain": {
 | |
|                                    "name": "Domain",
 | |
|                         },
 | |
|                         "project": {
 | |
|                                     "name": "Project",
 | |
|                                     "displaytext": "Test project",
 | |
|                         },
 | |
|                         "account": {
 | |
|                                     "email": "administrator@clogeny.com",
 | |
|                                     "firstname": "Test",
 | |
|                                     "lastname": "User",
 | |
|                                     "username": "test",
 | |
|                                     # Random characters are appended for unique
 | |
|                                     # username
 | |
|                                     "password": "password",
 | |
|                          },
 | |
|                          "user": {
 | |
|                                     "email": "administrator@clogeny.com",
 | |
|                                     "firstname": "User",
 | |
|                                     "lastname": "User",
 | |
|                                     "username": "User",
 | |
|                                     # Random characters are appended for unique
 | |
|                                     # username
 | |
|                                     "password": "password",
 | |
|                          },
 | |
|                          "service_offering": {
 | |
|                                     "name": "Tiny Instance",
 | |
|                                     "displaytext": "Tiny Instance",
 | |
|                                     "cpunumber": 1,
 | |
|                                     "cpuspeed": 100, # in MHz
 | |
|                                     "memory": 128, # In MBs
 | |
|                         },
 | |
|                         "disk_offering": {
 | |
|                                     "displaytext": "Tiny Disk Offering",
 | |
|                                     "name": "Tiny Disk Offering",
 | |
|                                     "disksize": 1
 | |
|                         },
 | |
|                         "volume": {
 | |
|                                    "diskname": "Test Volume",
 | |
|                         },
 | |
|                         "server": {
 | |
|                                     "displayname": "TestVM",
 | |
|                                     "username": "root",
 | |
|                                     "password": "password",
 | |
|                                     "ssh_port": 22,
 | |
|                                     "hypervisor": 'XenServer',
 | |
|                                     "privateport": 22,
 | |
|                                     "publicport": 22,
 | |
|                                     "protocol": 'TCP',
 | |
|                         },
 | |
|                         "template": {
 | |
|                                     "displaytext": "Cent OS Template",
 | |
|                                     "name": "Cent OS Template",
 | |
|                                     "ostype": 'CentOS 5.3 (64-bit)',
 | |
|                                     "templatefilter": 'self',
 | |
|                         },
 | |
|                          "network_offering": {
 | |
|                                     "name": 'Network offering-VR services',
 | |
|                                     "displaytext": 'Network offering-VR services',
 | |
|                                     "guestiptype": 'Isolated',
 | |
|                                     "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
 | |
|                                     "traffictype": 'GUEST',
 | |
|                                     "availability": 'Optional',
 | |
|                                     "serviceProviderList": {
 | |
|                                             "Dhcp": 'VirtualRouter',
 | |
|                                             "Dns": 'VirtualRouter',
 | |
|                                             "SourceNat": 'VirtualRouter',
 | |
|                                             "PortForwarding": 'VirtualRouter',
 | |
|                                             "Vpn": 'VirtualRouter',
 | |
|                                             "Firewall": 'VirtualRouter',
 | |
|                                             "Lb": 'VirtualRouter',
 | |
|                                             "UserData": 'VirtualRouter',
 | |
|                                             "StaticNat": 'VirtualRouter',
 | |
|                                         },
 | |
|                                     },
 | |
|                          "network": {
 | |
|                                   "name": "Test Network",
 | |
|                                   "displaytext": "Test Network",
 | |
|                                 },
 | |
|                          "ostype": 'CentOS 5.3 (64-bit)',
 | |
|                         # Cent OS 5.3 (64 bit)
 | |
|                         "sleep": 60,
 | |
|                         "timeout": 10,
 | |
|                     }
 | |
| 
 | |
| 
 | |
| class TestProjectLimits(cloudstackTestCase):
 | |
| 
 | |
|     @classmethod
 | |
|     def setUpClass(cls):
 | |
|         cls.testClient = super(TestProjectLimits, cls).getClsTestClient()
 | |
|         cls.api_client = cls.testClient.getApiClient()
 | |
| 
 | |
|         cls.services = Services().services
 | |
|         cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
 | |
|         cls.services['mode'] = cls.zone.networktype
 | |
| 
 | |
|         # Create domains, account etc.
 | |
|         cls.domain = Domain.create(
 | |
|                                    cls.api_client,
 | |
|                                    cls.services["domain"]
 | |
|                                    )
 | |
| 
 | |
|         cls.admin = Account.create(
 | |
|                             cls.api_client,
 | |
|                             cls.services["account"],
 | |
|                             admin=True,
 | |
|                             domainid=cls.domain.id
 | |
|                             )
 | |
|         cls.user = Account.create(
 | |
|                             cls.api_client,
 | |
|                             cls.services["user"],
 | |
|                             domainid=cls.domain.id
 | |
|                             )
 | |
|         cls.disk_offering = DiskOffering.create(
 | |
|                                     cls.api_client,
 | |
|                                     cls.services["disk_offering"]
 | |
|                                     )
 | |
|         cls._cleanup = [
 | |
|             cls.disk_offering,
 | |
|             cls.domain,
 | |
|             cls.user,
 | |
|             cls.admin
 | |
|         ]
 | |
|         return
 | |
| 
 | |
|     @classmethod
 | |
|     def tearDownClass(cls):
 | |
|         try:
 | |
|             #Cleanup resources used
 | |
|             super(TestProjectLimits,cls).tearDownClass()
 | |
|         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 accounts, domains etc
 | |
|             super(TestProjectLimits,self).tearDown()
 | |
|         except Exception as e:
 | |
|             raise Exception("Warning: Exception during cleanup : %s" % e)
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_01_project_limits(self):
 | |
|         """ Test project limits for domain admin
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. Create a Project. Verify once projects are created, they inherit
 | |
|         #    a default set of resource limits as configured by the Cloud Stack
 | |
|         #    ROOT admin.
 | |
|         # 2. Reduce Project resources limits. Verify limits can be reduced by
 | |
|         #    the Project Owner of each project and project limit applies to
 | |
|         #    number of virtual instances, disk volumes, snapshots, IP address.
 | |
|         #    Also, verify resource limits for the project are independent of
 | |
|         #    account resource limits
 | |
|         # 3. Increase Projects Resources limits above domains limit. Verify
 | |
|         #    project can't have more resources than domain level limit allows.
 | |
|         # 4. Create Resource more than its set limit for the parent domain.
 | |
|         #    Verify resource allocation should fail giving proper message
 | |
| 
 | |
|         # Create project as a domain admin
 | |
|         project = Project.create(
 | |
|                                  self.apiclient,
 | |
|                                  self.services["project"],
 | |
|                                  account=self.admin.name,
 | |
|                                  domainid=self.admin.domainid
 | |
|                                  )
 | |
|         # Cleanup created project at end of test
 | |
|         self.cleanup.append(project)
 | |
|         self.debug("Created project with domain admin with ID: %s" %
 | |
|                                                                 project.id)
 | |
| 
 | |
|         list_projects_response = Project.list(
 | |
|                                              self.apiclient,
 | |
|                                              id=project.id,
 | |
|                                              listall=True
 | |
|                                              )
 | |
| 
 | |
|         self.assertEqual(
 | |
|                             isinstance(list_projects_response, list),
 | |
|                             True,
 | |
|                             "Check for a valid list projects response"
 | |
|                             )
 | |
|         list_project = list_projects_response[0]
 | |
| 
 | |
|         self.assertNotEqual(
 | |
|                     len(list_projects_response),
 | |
|                     0,
 | |
|                     "Check list project response returns a valid project"
 | |
|                     )
 | |
| 
 | |
|         self.assertEqual(
 | |
|                             project.name,
 | |
|                             list_project.name,
 | |
|                             "Check project name from list response"
 | |
|                             )
 | |
|         # Get the resource limits for ROOT domain
 | |
|         resource_limits = list_resource_limits(self.apiclient)
 | |
| 
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
| 
 | |
|         # Reduce resource limits for project
 | |
|         # Resource: 0 - Instance. Number of instances a user can create.
 | |
|         # Resource: 1 - IP. Number of public IP addresses a user can own.
 | |
|         # Resource: 2 - Volume. Number of disk volumes a user can create.
 | |
|         # Resource: 3 - Snapshot. Number of snapshots a user can create.
 | |
|         # Resource: 4 - Template. Number of templates that a user can
 | |
|         #               register/create
 | |
|         for resource in resource_limits:
 | |
|             update_resource_limit(
 | |
|                                     self.apiclient,
 | |
|                                     resource.resourcetype,
 | |
|                                     max=1,
 | |
|                                     projectid=project.id
 | |
|                                     )
 | |
|             self.debug(
 | |
|             "Updating resource (ID: %s) limit for project: %s" % (
 | |
|                                                                   resource,
 | |
|                                                                   project.id
 | |
|                                                                   ))
 | |
|         resource_limits = list_resource_limits(
 | |
|                                                 self.apiclient,
 | |
|                                                 projectid=project.id
 | |
|                                                 )
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
|         for resource in resource_limits:
 | |
|             self.assertEqual(
 | |
|                          resource.max,
 | |
|                          1,
 | |
|                          "Resource limit should be updated to 1"
 | |
|                          )
 | |
| 
 | |
|         # Get the resource limits for domain
 | |
|         resource_limits = list_resource_limits(
 | |
|                                                 self.apiclient,
 | |
|                                                 domainid=self.domain.id
 | |
|                                                 )
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
| 
 | |
|         for resource in resource_limits:
 | |
|             # Update domain resource limits to 2
 | |
|             update_resource_limit(
 | |
|                                         self.apiclient,
 | |
|                                         resource.resourcetype,
 | |
|                                         domainid=self.domain.id,
 | |
|                                         max=1
 | |
|                                       )
 | |
|             max_value = 2
 | |
|             self.debug(
 | |
|                 "Attempting to update project: %s resource limit to: %s" % (
 | |
|                                                             project.id,
 | |
|                                                             max_value
 | |
|                                                             ))
 | |
|             # Update project resource limits to 3
 | |
|             update_resource_limit(
 | |
|                                     self.apiclient,
 | |
|                                     resource.resourcetype,
 | |
|                                     max=max_value,
 | |
|                                     projectid=project.id
 | |
|                                   )
 | |
| 
 | |
|         # Verify project can't have more resources then limit set for domain by adding volumes.
 | |
|         volume = Volume.create(
 | |
|                           self.apiclient,
 | |
|                           self.services["volume"],
 | |
|                           zoneid=self.zone.id,
 | |
|                           diskofferingid=self.disk_offering.id,
 | |
|                           projectid=project.id
 | |
|                         )
 | |
|         # Exception should be raised for second volume
 | |
|         with self.assertRaises(Exception):
 | |
|             Volume.create(
 | |
|                           self.apiclient,
 | |
|                           self.services["volume"],
 | |
|                           zoneid=self.zone.id,
 | |
|                           diskofferingid=self.disk_offering.id,
 | |
|                           projectid=project.id
 | |
|                         )
 | |
|         volume.delete(self.apiclient);
 | |
| 
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_02_project_limits_normal_user(self):
 | |
|         """ Test project limits for normal user
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. Create a Project
 | |
|         # 2. Reduce the projects limits as a domain admin. Verify resource
 | |
|         #    count is updated
 | |
|         # 3. Reduce the projects limits as a project user owner who is not a
 | |
|         #    domain admin. Resource count should fail
 | |
| 
 | |
|         # Create project as a domain admin
 | |
|         project = Project.create(
 | |
|                                  self.apiclient,
 | |
|                                  self.services["project"],
 | |
|                                  account=self.admin.name,
 | |
|                                  domainid=self.admin.domainid
 | |
|                                  )
 | |
|         # Cleanup created project at end of test
 | |
|         self.cleanup.append(project)
 | |
|         self.debug("Created project with domain admin with ID: %s" %
 | |
|                                                                 project.id)
 | |
| 
 | |
|         list_projects_response = Project.list(
 | |
|                                              self.apiclient,
 | |
|                                              id=project.id,
 | |
|                                              listall=True
 | |
|                                              )
 | |
| 
 | |
|         self.assertEqual(
 | |
|                             isinstance(list_projects_response, list),
 | |
|                             True,
 | |
|                             "Check for a valid list projects response"
 | |
|                             )
 | |
|         list_project = list_projects_response[0]
 | |
| 
 | |
|         self.assertNotEqual(
 | |
|                     len(list_projects_response),
 | |
|                     0,
 | |
|                     "Check list project response returns a valid project"
 | |
|                     )
 | |
| 
 | |
|         self.assertEqual(
 | |
|                             project.name,
 | |
|                             list_project.name,
 | |
|                             "Check project name from list response"
 | |
|                             )
 | |
|         # Get the resource limits for ROOT domain
 | |
|         resource_limits = list_resource_limits(self.apiclient)
 | |
| 
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
| 
 | |
|         # Reduce resource limits for project
 | |
|         # Resource: 0 - Instance. Number of instances a user can create.
 | |
|         # Resource: 1 - IP. Number of public IP addresses a user can own.
 | |
|         # Resource: 2 - Volume. Number of disk volumes a user can create.
 | |
|         # Resource: 3 - Snapshot. Number of snapshots a user can create.
 | |
|         # Resource: 4 - Template. Number of templates that a user can
 | |
|         #               register/create
 | |
|         for resource in resource_limits:
 | |
|             update_resource_limit(
 | |
|                                     self.apiclient,
 | |
|                                     resource.resourcetype,
 | |
|                                     max=1,
 | |
|                                     projectid=project.id
 | |
|                                     )
 | |
|             self.debug(
 | |
|             "Updating resource (ID: %s) limit for project: %s" % (
 | |
|                                                                   resource,
 | |
|                                                                   project.id
 | |
|                                                                   ))
 | |
|         resource_limits = list_resource_limits(
 | |
|                                                 self.apiclient,
 | |
|                                                 projectid=project.id
 | |
|                                                 )
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
|         for resource in resource_limits:
 | |
|             self.assertEqual(
 | |
|                          resource.max,
 | |
|                          1,
 | |
|                          "Resource limit should be updated to 1"
 | |
|                          )
 | |
| 
 | |
|         self.debug("Adding %s user to project: %s" % (
 | |
|                                                 self.user.name,
 | |
|                                                 project.name
 | |
|                                                 ))
 | |
| 
 | |
|         # Add user to the project
 | |
|         project.addAccount(
 | |
|                            self.apiclient,
 | |
|                            self.user.name,
 | |
|                            )
 | |
| 
 | |
|         # Get the resource limits for domain
 | |
|         resource_limits = list_resource_limits(
 | |
|                                                 self.apiclient,
 | |
|                                                 domainid=self.domain.id
 | |
|                                                 )
 | |
|         self.assertEqual(
 | |
|                          isinstance(resource_limits, list),
 | |
|                          True,
 | |
|                          "List resource API should return a valid list"
 | |
|                          )
 | |
|         self.assertNotEqual(
 | |
|                          len(resource_limits),
 | |
|                          0,
 | |
|                          "List resource API response should not be empty"
 | |
|                          )
 | |
| 
 | |
|         for resource in resource_limits:
 | |
|             #with self.assertRaises(Exception):
 | |
|             self.debug(
 | |
|                     "Attempting to update resource limit by user: %s" % (
 | |
|                                                         self.user.name
 | |
|                                                         ))
 | |
|             # Update project resource limits to 3
 | |
|             update_resource_limit(
 | |
|                                     self.apiclient,
 | |
|                                     resource.resourcetype,
 | |
|                                     account=self.user.name,
 | |
|                                     domainid=self.user.domainid,
 | |
|                                     max=3,
 | |
|                                     projectid=project.id
 | |
|                                 )
 | |
|         return
 | |
| 
 | |
| 
 | |
| class TestResourceLimitsProject(cloudstackTestCase):
 | |
| 
 | |
|     @classmethod
 | |
|     def setUpClass(cls):
 | |
|         cls.testClient = super(TestResourceLimitsProject, cls).getClsTestClient()
 | |
|         cls.api_client = cls.testClient.getApiClient()
 | |
|         cls.hypervisor = cls.testClient.getHypervisorInfo()
 | |
|         cls.services = Services().services
 | |
|         cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
 | |
|         cls.services['mode'] = cls.zone.networktype
 | |
| 
 | |
|         cls.template = get_template(
 | |
|                             cls.api_client,
 | |
|                             cls.zone.id,
 | |
|                             cls.services["ostype"]
 | |
|                             )
 | |
|         cls.services["server"]["zoneid"] = cls.zone.id
 | |
| 
 | |
|         # Create Domains, Account etc
 | |
|         cls.domain = Domain.create(
 | |
|                                    cls.api_client,
 | |
|                                    cls.services["domain"]
 | |
|                                    )
 | |
| 
 | |
|         cls.account = Account.create(
 | |
|                             cls.api_client,
 | |
|                             cls.services["account"],
 | |
|                             domainid=cls.domain.id
 | |
|                             )
 | |
| 
 | |
|         cls.userapiclient = cls.testClient.getUserApiClient(
 | |
|                                     UserName=cls.account.name,
 | |
|                                     DomainName=cls.account.domain)
 | |
| 
 | |
|         # Create project as a domain admin
 | |
|         cls.project = Project.create(
 | |
|                                  cls.api_client,
 | |
|                                  cls.services["project"],
 | |
|                                  account=cls.account.name,
 | |
|                                  domainid=cls.account.domainid
 | |
|                                  )
 | |
|         cls.services["account"] = cls.account.name
 | |
| 
 | |
|         # Create Service offering and disk offerings etc
 | |
|         cls.service_offering = ServiceOffering.create(
 | |
|                                             cls.api_client,
 | |
|                                             cls.services["service_offering"]
 | |
|                                             )
 | |
|         cls.disk_offering = DiskOffering.create(
 | |
|                                     cls.api_client,
 | |
|                                     cls.services["disk_offering"]
 | |
|                                     )
 | |
|         cls._cleanup = [
 | |
|             cls.domain,
 | |
|             cls.account,
 | |
|             cls.disk_offering,
 | |
|             cls.service_offering,
 | |
|             cls.project
 | |
|         ]
 | |
|         return
 | |
| 
 | |
|     @classmethod
 | |
|     def tearDownClass(cls):
 | |
|         try:
 | |
|             #Cleanup resources used
 | |
|             super(TestResourceLimitsProject,cls).tearDownClass()
 | |
|         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
 | |
|             super(TestResourceLimitsProject,self).tearDown()
 | |
|         except Exception as e:
 | |
|             raise Exception("Warning: Exception during cleanup : %s" % e)
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_03_vm_per_project(self):
 | |
|         """Test VM limit per project
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. Set max VM per project to 2
 | |
|         # 2. Create account and start 2 VMs. Verify VM state is Up and Running
 | |
|         # 3. Try to create 3rd VM instance. The appropriate error or alert
 | |
|         #    should be raised
 | |
| 
 | |
|         self.debug(
 | |
|             "Updating instance resource limits for project: %s" %
 | |
|                                                         self.project.id)
 | |
|         # Set usage_vm=1 for Account 1
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               0, # Instance
 | |
|                               max=2,
 | |
|                               projectid=self.project.id
 | |
|                               )
 | |
| 
 | |
|         self.debug("Deploying VM for project: %s" % self.project.id)
 | |
|         virtual_machine_1 = VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project.id
 | |
|                                 )
 | |
|         self.cleanup.append(virtual_machine_1)
 | |
|         # Verify VM state
 | |
|         self.assertEqual(
 | |
|                             virtual_machine_1.state,
 | |
|                             'Running',
 | |
|                             "Check VM state is Running or not"
 | |
|                         )
 | |
|         self.debug("Deploying VM for project: %s" % self.project.id)
 | |
|         virtual_machine_2 = VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project.id
 | |
|                                 )
 | |
|         self.cleanup.append(virtual_machine_2)
 | |
|         # Verify VM state
 | |
|         self.assertEqual(
 | |
|                             virtual_machine_2.state,
 | |
|                             'Running',
 | |
|                             "Check VM state is Running or not"
 | |
|                         )
 | |
|         # Exception should be raised for second instance
 | |
|         with self.assertRaises(Exception):
 | |
|             VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project.id
 | |
|                                 )
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_04_publicip_per_project(self):
 | |
|         """Test Public IP limit per project
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. set max no of IPs per project to 2.
 | |
|         # 2. Create an account in this domain
 | |
|         # 3. Create 1 VM in this domain
 | |
|         # 4. Acquire 1 IP in the domain. IP should be successfully acquired
 | |
|         # 5. Try to acquire 3rd IP in this domain. It should give the user an
 | |
|         #    appropriate error and an alert should be generated.
 | |
| 
 | |
|         self.debug(
 | |
|             "Updating public IP resource limits for project: %s" %
 | |
|                                                             self.project.id)
 | |
|         # Set usage_vm=1 for Account 1
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               1, # Public Ip
 | |
|                               max=2,
 | |
|                               projectid=self.project.id
 | |
|                               )
 | |
| 
 | |
|         self.debug("Deploying VM for Project: %s" % self.project.id)
 | |
|         virtual_machine_1 = VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project.id
 | |
|                                 )
 | |
|         self.cleanup.append(virtual_machine_1)
 | |
|         # Verify VM state
 | |
|         self.assertEqual(
 | |
|                             virtual_machine_1.state,
 | |
|                             'Running',
 | |
|                             "Check VM state is Running or not"
 | |
|                         )
 | |
|         networks = Network.list(
 | |
|                                 self.apiclient,
 | |
|                                 projectid=self.project.id,
 | |
|                                 listall=True
 | |
|                                 )
 | |
|         self.assertEqual(
 | |
|                     isinstance(networks, list),
 | |
|                     True,
 | |
|                     "Check list networks response returns a valid response"
 | |
|                     )
 | |
|         self.assertNotEqual(
 | |
|                     len(networks),
 | |
|                     0,
 | |
|                     "Check list networks response returns a valid network"
 | |
|                     )
 | |
|         network = networks[0]
 | |
|         self.debug("Associating public IP for project: %s" %
 | |
|                                                             self.project.id)
 | |
|         public_ip_1 = PublicIPAddress.create(
 | |
|                                            self.apiclient,
 | |
|                                            zoneid=virtual_machine_1.zoneid,
 | |
|                                            services=self.services["server"],
 | |
|                                            networkid=network.id,
 | |
|                                            projectid=self.project.id
 | |
|                                            )
 | |
|         self.cleanup.append(public_ip_1)
 | |
|         # Verify Public IP state
 | |
|         self.assertEqual(
 | |
|                             public_ip_1.ipaddress.state in [
 | |
|                                                  'Allocated',
 | |
|                                                  'Allocating'
 | |
|                                                  ],
 | |
|                             True,
 | |
|                             "Check Public IP state is allocated or not"
 | |
|                         )
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_05_snapshots_per_project(self):
 | |
|         """Test Snapshot limit per project
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. set max no of snapshots per project to 1.
 | |
|         # 2. Create one snapshot in the project. Snapshot should be
 | |
|         #    successfully created
 | |
|         # 5. Try to create another snapshot in this project. It should give
 | |
|         #    user an appropriate error and an alert should be generated.
 | |
| 
 | |
|         if self.hypervisor.lower() in ['hyperv', 'lxc']:
 | |
|             raise self.skipTest("Snapshots feature is not supported on %s" % self.hypervisor.lower())
 | |
|         self.debug(
 | |
|             "Updating snapshot resource limits for project: %s" %
 | |
|                                         self.project.id)
 | |
|         # Set usage_vm=1 for Account 1
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               3, # Snapshot
 | |
|                               max=1,
 | |
|                               projectid=self.project.id
 | |
|                               )
 | |
| 
 | |
|         self.debug("Deploying VM for account: %s" % self.account.name)
 | |
|         virtual_machine_1 = VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project.id
 | |
|                                 )
 | |
|         self.cleanup.append(virtual_machine_1)
 | |
|         # Verify VM state
 | |
|         self.assertEqual(
 | |
|                             virtual_machine_1.state,
 | |
|                             'Running',
 | |
|                             "Check VM state is Running or not"
 | |
|                         )
 | |
| 
 | |
|         # Get the Root disk of VM
 | |
|         volumes = list_volumes(
 | |
|                             self.apiclient,
 | |
|                             virtualmachineid=virtual_machine_1.id,
 | |
|                             projectid=self.project.id,
 | |
|                             type='ROOT'
 | |
|                             )
 | |
|         self.assertEqual(
 | |
|                         isinstance(volumes, list),
 | |
|                         True,
 | |
|                         "Check for list volume response return valid data"
 | |
|                         )
 | |
| 
 | |
|         self.debug("Creating snapshot from volume: %s" % volumes[0].id)
 | |
|         # Create a snapshot from the ROOTDISK
 | |
|         snapshot_1 = Snapshot.create(self.apiclient,
 | |
|                             volumes[0].id,
 | |
|                             projectid=self.project.id
 | |
|                             )
 | |
|         self.cleanup.append(snapshot_1)
 | |
| 
 | |
|         #list snapshots
 | |
|         snapshots = list_snapshots(self.apiclient, projectid=self.project.id)
 | |
| 
 | |
|         self.debug("snapshots list: %s" % snapshots)
 | |
| 
 | |
|         self.assertEqual(validateList(snapshots)[0], PASS, "Snapshots list validation failed")
 | |
|         self.assertEqual(len(snapshots), 1, "Snapshots list should have exactly one entity")
 | |
| 
 | |
|         # Exception should be raised for second snapshot
 | |
|         with self.assertRaises(Exception):
 | |
|             Snapshot.create(self.apiclient,
 | |
|                             volumes[0].id,
 | |
|                             projectid=self.project.id
 | |
|                             )
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false")
 | |
|     def test_06_volumes_per_project(self):
 | |
|         """Test Volumes limit per project
 | |
|         """
 | |
|         # Validate the following
 | |
|         # 1. set max no of volume per project to 1.
 | |
|         # 2. Create 1 VM in this project
 | |
|         # 4. Try to Create another VM in the project. It should give the user
 | |
|         #    an appropriate error that Volume limit is exhausted and an alert
 | |
|         #    should be generated.
 | |
| 
 | |
|         if self.hypervisor.lower() == 'lxc':
 | |
|             if not find_storage_pool_type(self.apiclient, storagetype='rbd'):
 | |
|                 self.skipTest("RBD storage type is required for data volumes for LXC")
 | |
|         self.project_1 = Project.create(
 | |
|                          self.api_client,
 | |
|                          self.services["project"],
 | |
|                          account=self.account.name,
 | |
|                          domainid=self.account.domainid
 | |
|                          )
 | |
|         self.cleanup.append(self.project_1)
 | |
| 
 | |
|         self.debug(
 | |
|             "Updating volume resource limits for project: %s" %
 | |
|                                                     self.project_1.id)
 | |
|         # Set usage_vm=1 for Account 1
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               2, # Volume
 | |
|                               max=1,
 | |
|                               projectid=self.project_1.id
 | |
|                               )
 | |
| 
 | |
|         self.debug("Deploying VM for project: %s" % self.project_1.id)
 | |
|         virtual_machine_1 = VirtualMachine.create(
 | |
|                                 self.apiclient,
 | |
|                                 self.services["server"],
 | |
|                                 templateid=self.template.id,
 | |
|                                 serviceofferingid=self.service_offering.id,
 | |
|                                 projectid=self.project_1.id
 | |
|                                 )
 | |
|         # Verify VM state
 | |
|         self.assertEqual(
 | |
|                             virtual_machine_1.state,
 | |
|                             'Running',
 | |
|                             "Check VM state is Running or not"
 | |
|                         )
 | |
|         self.cleanup.append(virtual_machine_1)
 | |
|         networks = Network.list(
 | |
|             self.apiclient,
 | |
|             projectid=self.project_1.id,
 | |
|             listall=True
 | |
|         )
 | |
|         for network in networks:
 | |
|             self.cleanup.insert(1,Network(network.__dict__))
 | |
| 
 | |
|         # Exception should be raised for second volume
 | |
|         with self.assertRaises(Exception):
 | |
|             Volume.create(
 | |
|                           self.apiclient,
 | |
|                           self.services["volume"],
 | |
|                           zoneid=self.zone.id,
 | |
|                           diskofferingid=self.disk_offering.id,
 | |
|                           projectid=self.project_1.id
 | |
|                         )
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "basic", "sg", "eip", "advancedns"], required_hardware="true")
 | |
|     def test_07_templates_per_project(self):
 | |
|         """Test Templates limit per project
 | |
|         """
 | |
|         # 1. set max no of templates per project to 1.
 | |
|         # 2. Create a template in this project. Both template should be in
 | |
|         #    ready state
 | |
|         # 3. Try create 2nd template in the project. It should give the user
 | |
|         #    appropriate error and an alert should be generated.
 | |
| 
 | |
|         # Reset the volume limits
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               2, # Volume
 | |
|                               max=5,
 | |
|                               projectid=self.project.id
 | |
|                               )
 | |
|         self.debug(
 | |
|             "Updating template resource limits for domain: %s" %
 | |
|                                         self.account.domainid)
 | |
|         # Set usage_vm=1 for Account 1
 | |
|         update_resource_limit(
 | |
|                               self.apiclient,
 | |
|                               4, # Template
 | |
|                               max=1,
 | |
|                               projectid=self.project.id
 | |
|                               )
 | |
| 
 | |
|         # Register the First Template in the project
 | |
|         self.debug("Register the First Template in the project")
 | |
|         builtin_info = get_builtin_template_info(self.apiclient, self.zone.id)
 | |
|         self.services["template"]["url"] = builtin_info[0]
 | |
|         self.services["template"]["hypervisor"] = builtin_info[1]
 | |
|         self.services["template"]["format"] = builtin_info[2]
 | |
| 
 | |
|         # Register new template
 | |
|         template = Template.register(
 | |
|                                         self.userapiclient,
 | |
|                                         self.services["template"],
 | |
|                                         zoneid=self.zone.id,
 | |
|                                         projectid=self.project.id
 | |
|                                         )
 | |
|         self.debug(
 | |
|                 "Registered a template of format: %s with ID: %s" % (
 | |
|                                                                 self.services["template"]["format"],
 | |
|                                                                 template.id
 | |
|                                                                 ))
 | |
|         self.cleanup.append(template)
 | |
| 
 | |
|         # Wait for template status to be changed across
 | |
|         time.sleep(self.services["sleep"])
 | |
|         timeout = self.services["timeout"]
 | |
|         while True:
 | |
|             list_template_response = Template.list(
 | |
|                                             self.apiclient,
 | |
|                                             templatefilter='all',
 | |
|                                             id=template.id,
 | |
|                                             zoneid=self.zone.id,
 | |
|                                             projectid=self.project.id,
 | |
|                                             )
 | |
|             if list_template_response[0].isready is True:
 | |
|                 break
 | |
|             elif timeout == 0:
 | |
|                 raise Exception("Template state is not ready, it is %s" % list_template_response[0].isready)
 | |
| 
 | |
|             time.sleep(self.services["sleep"])
 | |
|             timeout = timeout - 1
 | |
| 
 | |
|         #Verify template response to check whether template added successfully
 | |
|         self.assertEqual(
 | |
|                         isinstance(list_template_response, list),
 | |
|                         True,
 | |
|                         "Check for list template response return valid data"
 | |
|                         )
 | |
| 
 | |
|         self.assertNotEqual(
 | |
|                             len(list_template_response),
 | |
|                             0,
 | |
|                             "Check template available in List Templates"
 | |
|                         )
 | |
| 
 | |
|         template_response = list_template_response[0]
 | |
|         self.assertEqual(
 | |
|                             template_response.isready,
 | |
|                             True,
 | |
|                             "Template state is not ready, it is %s" % template_response.isready
 | |
|                         )
 | |
| 
 | |
|         # Exception should be raised for second template
 | |
|         with self.assertRaises(Exception):
 | |
|             Template.register(
 | |
|                                 self.userapiclient,
 | |
|                                 self.services["template"],
 | |
|                                 zoneid=self.zone.id,
 | |
|                                 projectid=self.project.id
 | |
|                             )
 | |
|         networks = Network.list(
 | |
|             self.apiclient,
 | |
|             projectid=self.project.id,
 | |
|             listall=True
 | |
|         )
 | |
|         for network in networks:
 | |
|             self.cleanup.append(Network(network.__dict__))
 | |
| 
 | |
|         return
 | |
| 
 | |
| class TestMaxProjectNetworks(cloudstackTestCase):
 | |
| 
 | |
|     @classmethod
 | |
|     def setUpClass(cls):
 | |
|         cls.testClient = super(TestMaxProjectNetworks, cls).getClsTestClient()
 | |
|         cls.api_client = cls.testClient.getApiClient()
 | |
| 
 | |
|         cls.services = Services().services
 | |
|         cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
 | |
|         cls.domain = get_domain(cls.api_client)
 | |
|         cls.services['mode'] = cls.zone.networktype
 | |
|         cls.template = get_template(
 | |
|                             cls.api_client,
 | |
|                             cls.zone.id,
 | |
|                             cls.services["ostype"]
 | |
|                             )
 | |
|         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
 | |
|             super(TestMaxProjectNetworks,cls).tearDownClass()
 | |
|         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 = []
 | |
|         return
 | |
| 
 | |
|     def tearDown(self):
 | |
|         try:
 | |
|             #Clean up, terminate the created network offerings
 | |
|             super(TestMaxProjectNetworks,self).tearDown()
 | |
|             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)
 | |
|         except Exception as e:
 | |
|             raise Exception("Warning: Exception during cleanup : %s" % e)
 | |
|         return
 | |
| 
 | |
|     @attr(tags=["advanced", "advancedns", "simulator",
 | |
|                 "api"])
 | |
|     def test_maxAccountNetworks(self):
 | |
|         """Test Limit number of guest account specific networks
 | |
|         """
 | |
| 
 | |
|         # Steps for validation
 | |
|         # 1. Fetch max.account.networks from configurations
 | |
|         # 2. Create an account. Create account more that max.account.network
 | |
|         # 3. Create network should fail
 | |
| 
 | |
|         self.debug("Creating project with '%s' as admin" %
 | |
|                                             self.account.name)
 | |
|         # Create project as a domain admin
 | |
|         project = Project.create(
 | |
|                                  self.apiclient,
 | |
|                                  self.services["project"],
 | |
|                                  account=self.account.name,
 | |
|                                  domainid=self.account.domainid
 | |
|                                  )
 | |
|         # Cleanup created project at end of test
 | |
|         self.cleanup.append(project)
 | |
|         self.debug("Created project with domain admin with ID: %s" %
 | |
|                                                                 project.id)
 | |
| 
 | |
|         config = Configurations.list(
 | |
|                                     self.apiclient,
 | |
|                                     name='max.project.networks',
 | |
|                                     listall=True
 | |
|                                     )
 | |
|         self.assertEqual(
 | |
|                 isinstance(config, list),
 | |
|                 True,
 | |
|                 "List configurations hsould have max.project.networks"
 | |
|                 )
 | |
| 
 | |
|         config_value = int(config[0].value)
 | |
|         self.debug("max.project.networks: %s" % config_value)
 | |
| 
 | |
|         for ctr in range(config_value):
 | |
|             # 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"],
 | |
|                                     projectid=project.id,
 | |
|                                     networkofferingid=self.network_offering.id,
 | |
|                                     zoneid=self.zone.id
 | |
|                                     )
 | |
|             self.cleanup.append(network)
 | |
|             self.debug("Created network with ID: %s" % network.id)
 | |
|         self.debug(
 | |
|             "Creating network in account already having networks : %s" %
 | |
|                                                             config_value)
 | |
| 
 | |
|         with self.assertRaises(Exception):
 | |
|             network = Network.create(
 | |
|                                     self.apiclient,
 | |
|                                     self.services["network"],
 | |
|                                     projectid=project.id,
 | |
|                                     networkofferingid=self.network_offering.id,
 | |
|                                     zoneid=self.zone.id
 | |
|                                     )
 | |
|             self.cleanup.append(network)
 | |
|         self.debug('Create network failed (as expected)')
 | |
|         return
 |