Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

Commit

Permalink
[1LP][RFR] Cover provisioning issues (#9985)
Browse files Browse the repository at this point in the history
* Cover 1670327

* Autoselect provision source by provider.

* Correct the automates marker to BZ 1797706.

* Add template cloning.

* Add skip for BZ 1797706

* Review fixes

* Use OOP instead of instanceof.
  • Loading branch information
Jaroslav Henner authored May 6, 2020
1 parent c0c3b75 commit 067b006
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 49 deletions.
2 changes: 2 additions & 0 deletions cfme/cloud/provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ class CloudProvider(BaseProvider, CloudInfraProviderMixin, Pretty, PolicyProfile
db_types = ["CloudManager"]
template_class = Image
collection_name = 'cloud_providers'
provisioning_dialog_widget_names = BaseProvider.provisioning_dialog_widget_names.union({
'properties', 'volumes', 'customize'})

name = attr.ib(default=None)
key = attr.ib(default=None)
Expand Down
3 changes: 3 additions & 0 deletions cfme/cloud/provider/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class EC2Provider(CloudProvider):
region = attr.ib(default=None)
region_name = attr.ib(default=None)

provisioning_dialog_widget_names = CloudProvider.provisioning_dialog_widget_names.difference(
{'volumes'})

@property
def view_value_mapping(self):
"""Maps values to view attrs"""
Expand Down
1 change: 1 addition & 0 deletions cfme/common/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class BaseProvider(Taggable, Updateable, Navigatable, BaseEntity, CustomButtonEv
_param_name = ParamClassName('name')
STATS_TO_MATCH = []
db_types = ["Providers"]
provisioning_dialog_widget_names = {'request', 'purpose', 'catalog', 'environment', 'schedule'}
ems_events = []
settings_key = None
vm_class = None # Set on type specific provider classes for VM/instance class
Expand Down
31 changes: 31 additions & 0 deletions cfme/common/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
from datetime import datetime

import attr
import fauxfactory
from cached_property import cached_property
from manageiq_client.filters import Q
from navmazing import NavigateToSibling
from riggerlib import recursive_update
from widgetastic.exceptions import NoSuchElementException
from widgetastic.utils import partial_match

from cfme.common import BaseLoggedInPage
from cfme.common import CustomButtonEventsMixin
Expand All @@ -33,6 +35,7 @@
from cfme.utils.appliance.implementations.ui import navigate_to
from cfme.utils.appliance.implementations.ui import navigator
from cfme.utils.blockers import BZ
from cfme.utils.conf import cfme_data
from cfme.utils.log import logger
from cfme.utils.net import find_pingable
from cfme.utils.pretty import Pretty
Expand Down Expand Up @@ -274,6 +277,29 @@ def delete(self, cancel=False, from_details=False):
self.find_quadicon().ensure_checked()
view.toolbar.configuration.item_select(self.REMOVE_SELECTED, handle_alert=not cancel)

def _fill_clone_form(self, view, email=None, first_name=None, last_name=None,
new_name=None, provision_type=None):
first_name = first_name or fauxfactory.gen_alphanumeric()
last_name = last_name or fauxfactory.gen_alphanumeric()
email = email or f"{first_name}@{last_name}.test"
try:
prov_data = cfme_data["management_systems"][self.provider.key]["provisioning"]
except (KeyError, IndexError):
raise ValueError("You have to specify the correct options in cfme_data.yaml")

provisioning_data = {
'catalog': {'vm_name': new_name,
'provision_type': provision_type},
'request': {
'email': email,
'first_name': first_name,
'last_name': last_name},
'environment': {"host_name": {'name': prov_data.get("host")},
"datastore_name": {"name": prov_data.get("datastore")}},
'network': {'vlan': partial_match(prov_data.get("vlan"))},
}
view.form.fill_with(provisioning_data, on_change=view.form.submit_button)

@property
def ip_address(self):
"""Fetches IP Address of VM
Expand Down Expand Up @@ -1074,6 +1100,11 @@ def mgmt(self):
def exists_on_provider(self):
return self.provider.mgmt.does_template_exist(self.name)

def clone_template(self, email=None, first_name=None, last_name=None,
new_name=None, provision_type=None):
view = navigate_to(self, 'CloneTemplate')
self._fill_clone_form(view, email, first_name, last_name, new_name, provision_type)


@attr.s
class TemplateCollection(BaseVMCollection):
Expand Down
2 changes: 2 additions & 0 deletions cfme/infrastructure/provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class InfraProvider(BaseProvider, CloudInfraProviderMixin, Pretty, Fillable,
hosts_menu_item = "Hosts"
vm_name = "Virtual Machines"
collection_name = 'infra_providers'
provisioning_dialog_widget_names = BaseProvider.provisioning_dialog_widget_names.union(
{'hardware', 'network', 'customize'})

name = attr.ib(default=None)
key = attr.ib(default=None)
Expand Down
2 changes: 2 additions & 0 deletions cfme/infrastructure/provider/scvmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class SCVMMProvider(InfraProvider):
settings_key = 'ems_scvmm'
ui_prov_type = 'Microsoft System Center VMM'
log_name = 'scvmm'
provisioning_dialog_widget_names = (InfraProvider.provisioning_dialog_widget_names
- {'environment'} | {'customize'})

@property
def view_value_mapping(self):
Expand Down
30 changes: 10 additions & 20 deletions cfme/infrastructure/virtual_machines.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,26 +948,7 @@ def migrate_vm(self, email=None, first_name=None, last_name=None,
def clone_vm(self, email=None, first_name=None, last_name=None,
vm_name=None, provision_type=None):
view = navigate_to(self, 'Clone')
first_name = first_name or fauxfactory.gen_alphanumeric()
last_name = last_name or fauxfactory.gen_alphanumeric()
email = email or f"{first_name}@{last_name}.test"
try:
prov_data = cfme_data["management_systems"][self.provider.key]["provisioning"]
except (KeyError, IndexError):
raise ValueError("You have to specify the correct options in cfme_data.yaml")

provisioning_data = {
'catalog': {'vm_name': vm_name,
'provision_type': provision_type},
'request': {
'email': email,
'first_name': first_name,
'last_name': last_name},
'environment': {"host_name": {'name': prov_data.get("host")},
"datastore_name": {"name": prov_data.get("datastore")}},
'network': {'vlan': partial_match(prov_data.get("vlan"))},
}
view.form.fill_with(provisioning_data, on_change=view.form.submit_button)
self._fill_clone_form(view, email, first_name, last_name, vm_name, provision_type)

def publish_to_template(self, template_name, email=None, first_name=None, last_name=None):
view = navigate_to(self, 'Publish')
Expand Down Expand Up @@ -1741,6 +1722,15 @@ def step(self, *args, **kwargs):
self.prerequisite_view.toolbar.configuration.item_select('Set Ownership')


@navigator.register(InfraTemplate, 'CloneTemplate')
class TemplateClone(CFMENavigateStep):
VIEW = CloneVmView
prerequisite = NavigateToSibling('Details')

def step(self, *args, **kwargs):
self.prerequisite_view.toolbar.lifecycle.item_select("Clone this Template")


@navigator.register(InfraVm, 'Rename')
class Rename(CFMENavigateStep):
VIEW = RenameVmView
Expand Down
6 changes: 6 additions & 0 deletions cfme/services/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,12 @@ class schedule(WaitTab): # noqa
retirement = SummaryFormItem('Lifespan', 'Time until Retirement')
retirement_warning = SummaryFormItem('Lifespan', 'Retirement Warning')

@View.nested
class volumes(WaitTab): # noqa
volume_name = SummaryFormItem('Volumes', 'Volume Name')
volume_size = SummaryFormItem('Volumes', 'Size (gigabytes)')
delete_on_terminate = Checkbox(name='volumes__delete_on_terminate_1')

@property
def is_displayed(self):
expected_description = self.context['object'].rest.description
Expand Down
10 changes: 10 additions & 0 deletions cfme/tests/cloud_infra_common/test_cloud_init_provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
from cfme.infrastructure.provider.scvmm import SCVMMProvider
from cfme.infrastructure.pxe import get_template_from_config
from cfme.markers.env_markers.provider import providers
from cfme.tests.infrastructure.test_provisioning_dialog import check_all_tabs
from cfme.utils import ssh
from cfme.utils.blockers import BZ
from cfme.utils.generators import random_vm_name
from cfme.utils.log import logger
from cfme.utils.providers import ProviderFilter
Expand Down Expand Up @@ -59,6 +61,7 @@ def vm_name():

@pytest.mark.tier(3)
@test_requirements.provision
@pytest.mark.meta(automates=[BZ(1797706)])
def test_provision_cloud_init(appliance, request, setup_provider, provider, provisioning,
setup_ci_template, vm_name):
""" Tests provisioning from a template with cloud_init
Expand All @@ -68,6 +71,7 @@ def test_provision_cloud_init(appliance, request, setup_provider, provider, prov
Bugzilla:
1619744
1797706
Polarion:
assignee: jhenner
Expand All @@ -88,6 +92,7 @@ def test_provision_cloud_init(appliance, request, setup_provider, provider, prov
# for image selection in before_fill
inst_args['template_name'] = image

# TODO Perhaps merge this with stuff in test_provisioning_dialog.prov_data
if provider.one_of(AzureProvider):
inst_args['environment'] = {'public_ip_address': "New"}
if provider.one_of(OpenStackProvider):
Expand All @@ -97,16 +102,19 @@ def test_provision_cloud_init(appliance, request, setup_provider, provider, prov
inst_args['environment'] = {'public_ip_address': floating_ip}
inst_arg_props = inst_args.setdefault('properties', {})
inst_arg_props['instance_type'] = partial_match(provisioning['ci-flavor-name'])

if provider.one_of(InfraProvider) and appliance.version > '5.9':
inst_args['customize']['customize_type'] = 'Specification'

logger.info(f'Instance args: {inst_args}')

collection = appliance.provider_based_collection(provider)
instance = collection.create(vm_name, provider, form_values=inst_args)

request.addfinalizer(instance.cleanup_on_provider)
provision_request = provider.appliance.collections.requests.instantiate(vm_name,
partial_check=True)
check_all_tabs(provision_request, provider)
provision_request.wait_for_request()
wait_for(lambda: instance.ip_address is not None, num_sec=600)
connect_ip = instance.ip_address
Expand All @@ -122,6 +130,7 @@ def test_provision_cloud_init(appliance, request, setup_provider, provider, prov

@test_requirements.provision
@pytest.mark.provider([RHEVMProvider])
@pytest.mark.meta(automates=[1797706])
def test_provision_cloud_init_payload(appliance, request, setup_provider, provider, provisioning,
vm_name):
"""
Expand Down Expand Up @@ -170,6 +179,7 @@ def test_provision_cloud_init_payload(appliance, request, setup_provider, provid
request.addfinalizer(instance.cleanup_on_provider)
provision_request = provider.appliance.collections.requests.instantiate(vm_name,
partial_check=True)
check_all_tabs(provision_request, provider)
provision_request.wait_for_request()

connect_ip = wait_for(find_global_ipv6, func_args=[instance], num_sec=600, delay=20).out
Expand Down
Loading

0 comments on commit 067b006

Please sign in to comment.