mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
* FR-248: Instance lease, WIP commit * insert lease expiry into db and use that to filter exiring vms, add asyncjobmanager * Add leaseDuration and leaseExpiryAction in Service offering create flow * Update listVM cmd to allow listing only leased instances * Add methods to fetch instances for which lease is expiring in next days * Changes included: config key setup and configured for alert email lease options in create and update vm screen handle delete protection, edit vm, create vm validated stop and detroy, delete protection * Update UI screens for leased properties coming from config and service offering * use global lock before running scheduler * Unit tests * Flow changes done in UI based on discussion * Include view changes in schema upgrade files and use feature in various UI elements * Added integration test for vm deployment, UI enhancements for user persona, bug fixes * validate integration tests, minor ui changes and log messages * fix build: moving configkey from setup to test itself * Disable testAlert to unblock build and trim whitespaces in integration tests * Address review comments * Minor changes in EditVM screen * Use ExecutorService instead of Timer and TimerTask * Additional review comments * Incorporate following changes: 1. Execute lease action once on the instance 2. Cancel lease on instance when feature is disabled 3. Relevant events when lease gets disabled, cancelled, executed 4. Disable associating lease after deployment 5. UI elements and flow changes 6. Changes based on feedback from demo * Handle pr review comments * address review comments * move instance.lease.enabled config to VMLeaseManager interface * bug fix in edit instance flow and reject api request for invalid values * max allowed lease is for 100 years * log instance ids for expired instance * Fix config validation for value range and code coverage improvement * fix lease expiry request failures in async * dont use forced: true for StopVmCmd * Update server/src/main/java/org/apache/cloudstack/vm/lease/VMLeaseManager.java Co-authored-by: Vishesh <vishesh92@gmail.com> * handle review comments --------- Co-authored-by: Rohit Yadav <rohityadav89@gmail.com> Co-authored-by: Vishesh <vishesh92@gmail.com>
359 lines
12 KiB
Python
359 lines
12 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.
|
|
|
|
# Import Local Modules
|
|
from nose.plugins.attrib import attr
|
|
from marvin.codes import FAILED
|
|
from marvin.cloudstackTestCase import cloudstackTestCase
|
|
from marvin.lib.utils import cleanup_resources
|
|
from marvin.lib.base import (Account,
|
|
VirtualMachine,
|
|
ServiceOffering,
|
|
DiskOffering,
|
|
Configurations)
|
|
from marvin.lib.common import (get_zone,
|
|
get_domain,
|
|
get_test_template,
|
|
is_config_suitable)
|
|
|
|
|
|
class TestDeployVMLease(cloudstackTestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
|
|
cls.testClient = super(TestDeployVMLease, cls).getClsTestClient()
|
|
cls.api_client = cls.testClient.getApiClient()
|
|
|
|
cls.testdata = cls.testClient.getParsedTestDataConfig()
|
|
# Get Zone, Domain and templates
|
|
cls.domain = get_domain(cls.api_client)
|
|
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
|
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
|
|
|
cls.template = get_test_template(
|
|
cls.api_client,
|
|
cls.zone.id,
|
|
cls.hypervisor
|
|
)
|
|
|
|
if cls.template == FAILED:
|
|
assert False, "get_test_template() failed to return template"
|
|
|
|
|
|
# enable instance lease feature
|
|
Configurations.update(cls.api_client,
|
|
name="instance.lease.enabled",
|
|
value="true"
|
|
)
|
|
|
|
# Create service, disk offerings etc
|
|
cls.non_lease_svc_offering = ServiceOffering.create(
|
|
cls.api_client,
|
|
cls.testdata["service_offering"],
|
|
name="non-lease-svc-offering"
|
|
)
|
|
|
|
# Create service, disk offerings etc
|
|
cls.lease_svc_offering = ServiceOffering.create(
|
|
cls.api_client,
|
|
cls.testdata["service_offering"],
|
|
name="lease-svc-offering",
|
|
leaseduration=20,
|
|
leaseexpiryaction="DESTROY"
|
|
)
|
|
|
|
cls.disk_offering = DiskOffering.create(
|
|
cls.api_client,
|
|
cls.testdata["disk_offering"]
|
|
)
|
|
|
|
cls._cleanup = [
|
|
cls.lease_svc_offering,
|
|
cls.non_lease_svc_offering,
|
|
cls.disk_offering
|
|
]
|
|
return
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
try:
|
|
# disable instance lease feature
|
|
Configurations.update(cls.api_client,
|
|
name="instance.lease.enabled",
|
|
value="false"
|
|
)
|
|
cleanup_resources(cls.api_client, cls._cleanup)
|
|
except Exception as e:
|
|
raise Exception("Warning: Exception during cleanup : %s" % e)
|
|
|
|
def setUp(self):
|
|
self.apiclient = self.testClient.getApiClient()
|
|
self.hypervisor = self.testClient.getHypervisorInfo()
|
|
self.testdata["virtual_machine"]["zoneid"] = self.zone.id
|
|
self.testdata["virtual_machine"]["template"] = self.template.id
|
|
self.testdata["iso"]["zoneid"] = self.zone.id
|
|
self.account = Account.create(
|
|
self.apiclient,
|
|
self.testdata["account"],
|
|
domainid=self.domain.id
|
|
)
|
|
self.cleanup = [self.account]
|
|
return
|
|
|
|
def tearDown(self):
|
|
try:
|
|
self.debug("Cleaning up the resources")
|
|
cleanup_resources(self.apiclient, self.cleanup)
|
|
self.debug("Cleanup complete!")
|
|
except Exception as e:
|
|
self.debug("Warning! Exception in tearDown: %s" % e)
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_01_deploy_vm_no_lease_svc_offering(self):
|
|
"""Test Deploy Virtual Machine from non-lease-svc-offering
|
|
|
|
Validate the following:
|
|
1. deploy VM using non-lease-svc-offering
|
|
2. confirm vm has no lease configured
|
|
"""
|
|
|
|
non_lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.non_lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor
|
|
)
|
|
self.verify_no_lease_configured_for_vm(non_lease_vm.id)
|
|
return
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_02_deploy_vm_no_lease_svc_offering_with_lease_params(self):
|
|
"""Test Deploy Virtual Machine from non-lease-svc-offering and lease parameters are used to enabled lease for vm
|
|
|
|
Validate the following:
|
|
1. deploy VM using non-lease-svc-offering and passing leaseduration and leaseexpiryaction
|
|
2. confirm vm has lease configured
|
|
"""
|
|
lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.non_lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor,
|
|
leaseduration=10,
|
|
leaseexpiryaction="STOP"
|
|
)
|
|
self.verify_lease_configured_for_vm(lease_vm.id, lease_duration=10, lease_expiry_action="STOP")
|
|
return
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_03_deploy_vm_lease_svc_offering_with_no_param(self):
|
|
"""Test Deploy Virtual Machine from lease-svc-offering without lease params
|
|
expect vm to inherit svc_offering lease properties
|
|
|
|
Validate the following:
|
|
1. deploy VM using lease-svc-offering without passing leaseduration and leaseexpiryaction
|
|
2. confirm vm has lease configured
|
|
"""
|
|
lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor
|
|
)
|
|
self.verify_lease_configured_for_vm(lease_vm.id, lease_duration=20, lease_expiry_action="DESTROY")
|
|
return
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_04_deploy_vm_lease_svc_offering_with_param(self):
|
|
"""Test Deploy Virtual Machine from lease-svc-offering with overridden lease properties
|
|
|
|
Validate the following:
|
|
1. confirm svc_offering has lease properties
|
|
2. deploy VM using lease-svc-offering and leaseduration and leaseexpiryaction passed
|
|
3. confirm vm has lease configured
|
|
"""
|
|
self.verify_svc_offering()
|
|
|
|
lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor,
|
|
leaseduration=30,
|
|
leaseexpiryaction="STOP"
|
|
)
|
|
self.verify_lease_configured_for_vm(lease_vm.id, lease_duration=30, lease_expiry_action="STOP")
|
|
return
|
|
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_05_deploy_vm_lease_svc_offering_with_lease_param_disabled(self):
|
|
"""Test Deploy Virtual Machine from lease-svc-offering and passing -1 leaseduration to set no-expiry
|
|
|
|
Validate the following:
|
|
1. deploy VM using lease-svc-offering
|
|
2. leaseduration is set as -1 in the deploy vm request to disable lease
|
|
3. confirm vm has no lease configured
|
|
"""
|
|
|
|
lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.non_lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor,
|
|
leaseduration=-1
|
|
)
|
|
|
|
vms = VirtualMachine.list(
|
|
self.apiclient,
|
|
id=lease_vm.id
|
|
)
|
|
vm = vms[0]
|
|
self.verify_no_lease_configured_for_vm(vm.id)
|
|
return
|
|
|
|
@attr(
|
|
tags=[
|
|
"advanced",
|
|
"basic"],
|
|
required_hardware="true")
|
|
def test_06_deploy_vm_lease_svc_offering_with_disabled_lease(self):
|
|
"""Test Deploy Virtual Machine from lease-svc-offering with lease feature disabled
|
|
|
|
Validate the following:
|
|
1. Disable lease feature
|
|
2. deploy VM using lease-svc-offering
|
|
3. confirm vm has no lease configured
|
|
"""
|
|
|
|
Configurations.update(self.api_client,
|
|
name="instance.lease.enabled",
|
|
value="false"
|
|
)
|
|
|
|
lease_vm = VirtualMachine.create(
|
|
self.apiclient,
|
|
self.testdata["virtual_machine"],
|
|
accountid=self.account.name,
|
|
domainid=self.account.domainid,
|
|
templateid=self.template.id,
|
|
serviceofferingid=self.lease_svc_offering.id,
|
|
diskofferingid=self.disk_offering.id,
|
|
hypervisor=self.hypervisor
|
|
)
|
|
|
|
vms = VirtualMachine.list(
|
|
self.apiclient,
|
|
id=lease_vm.id
|
|
)
|
|
vm = vms[0]
|
|
self.verify_no_lease_configured_for_vm(vm.id)
|
|
return
|
|
|
|
|
|
def verify_svc_offering(self):
|
|
svc_offering_list = ServiceOffering.list(
|
|
self.api_client,
|
|
id=self.lease_svc_offering.id
|
|
)
|
|
|
|
svc_offering = svc_offering_list[0]
|
|
|
|
self.assertIsNotNone(
|
|
svc_offering.leaseduration,
|
|
"svc_offering has lease configured"
|
|
)
|
|
|
|
self.assertEqual(
|
|
20,
|
|
svc_offering.leaseduration,
|
|
"svc_offering has 20 days for lease"
|
|
)
|
|
|
|
def verify_lease_configured_for_vm(self, vm_id=None, lease_duration=None, lease_expiry_action=None):
|
|
vms = VirtualMachine.list(
|
|
self.apiclient,
|
|
id=vm_id
|
|
)
|
|
vm = vms[0]
|
|
self.assertEqual(
|
|
lease_duration,
|
|
vm.leaseduration,
|
|
"check to confirm leaseduration is configured"
|
|
)
|
|
|
|
self.assertEqual(
|
|
lease_expiry_action,
|
|
vm.leaseexpiryaction,
|
|
"check to confirm leaseexpiryaction is configured"
|
|
)
|
|
|
|
self.assertIsNotNone(vm.leaseexpirydate, "confirm leaseexpirydate is available")
|
|
|
|
|
|
def verify_no_lease_configured_for_vm(self, vm_id=None):
|
|
if vm_id == None:
|
|
return
|
|
vms = VirtualMachine.list(
|
|
self.apiclient,
|
|
id=vm_id
|
|
)
|
|
vm = vms[0]
|
|
self.assertIsNone(vm.leaseduration)
|
|
self.assertIsNone(vm.leaseexpiryaction)
|