class PolicyProfileAssignable(object): """This class can be inherited by anything that provider load_details method. It provides functionality to assign and unassign Policy Profiles """ manage_policies_tree = deferred_verpick({ version.LOWEST: CheckboxTree("//div[@id='protect_treebox']/ul"), "5.7": BootstrapTreeview("protectbox") }) @property def assigned_policy_profiles(self): try: return self._assigned_policy_profiles except AttributeError: self._assigned_policy_profiles = set([]) return self._assigned_policy_profiles def assign_policy_profiles(self, *policy_profile_names): """ Assign Policy Profiles to this object. Args: policy_profile_names: :py:class:`str` with Policy Profile names. After Control/Explorer coverage goes in, PolicyProfile objects will be also passable. """ map(self.assigned_policy_profiles.add, policy_profile_names) self._assign_unassign_policy_profiles(True, *policy_profile_names) def unassign_policy_profiles(self, *policy_profile_names): """ Unssign Policy Profiles to this object. Args: policy_profile_names: :py:class:`str` with Policy Profile names. After Control/Explorer coverage goes in, PolicyProfile objects will be also passable. """ for pp_name in policy_profile_names: try: self.assigned_policy_profiles.remove(pp_name) except KeyError: pass self._assign_unassign_policy_profiles(False, *policy_profile_names) def _assign_unassign_policy_profiles(self, assign, *policy_profile_names): """DRY function for managing policy profiles. See :py:func:`assign_policy_profiles` and :py:func:`assign_policy_profiles` Args: assign: Wheter to assign or unassign. policy_profile_names: :py:class:`str` with Policy Profile names. """ self.load_details(refresh=True) pol_btn("Manage Policies") for policy_profile in policy_profile_names: if assign: self.manage_policies_tree.check_node(policy_profile) else: self.manage_policies_tree.uncheck_node(policy_profile) form_buttons.save() flash.assert_no_errors()
class Role(Updateable, Pretty, Navigatable): form = Form(fields=[ ('name_txt', Input('name')), ('vm_restriction_select', AngularSelect('vm_restriction')), ('product_features_tree', { version.LOWEST: CheckboxTree("//div[@id='features_treebox']/ul"), '5.7': BootstrapTreeview("features_treebox") }), ]) pretty_attrs = ['name', 'product_features'] def __init__(self, name=None, vm_restriction=None, product_features=None, appliance=None): Navigatable.__init__(self, appliance=appliance) self.name = name self.vm_restriction = vm_restriction self.product_features = product_features or [] def create(self): navigate_to(self, 'Add') fill(self.form, { 'name_txt': self.name, 'vm_restriction_select': self.vm_restriction, 'product_features_tree': self.product_features }, action=form_buttons.add) flash.assert_success_message('Role "{}" was saved'.format(self.name)) def update(self, updates): navigate_to(self, 'Edit') fill(self.form, { 'name_txt': updates.get('name'), 'vm_restriction_select': updates.get('vm_restriction'), 'product_features_tree': updates.get('product_features') }, action=form_buttons.save) flash.assert_success_message('Role "{}" was saved'.format( updates.get('name', self.name))) def delete(self): navigate_to(self, 'Details') tb_select('Delete this Role', invokes_alert=True) sel.handle_alert() flash.assert_success_message('Role "{}": Delete successful'.format( self.name)) def copy(self, name=None): if not name: name = self.name + "copy" navigate_to(self, 'Details') tb.select('Configuration', 'Copy this Role to a new Role') new_role = Role(name=name) fill(self.form, {'name_txt': new_role.name}, action=form_buttons.add) flash.assert_success_message('Role "{}" was saved'.format( new_role.name)) return new_role
def tree(name, *path): """Get underlying Tree() object. And eventually click path. If the accordion is not active, will be clicked. Attention! The object is 'live' so when it's obscured, it won't work! Usage: accordion.tree("Something").click_path("level 1", "level 2") accordion.tree("Something", "level 1", "level 2") # is the same Args: *path: If specified, it will directly pass these parameters into click_path of Tree. Otherwise it returns the Tree object. """ try: if not is_active(name): logger.debug( 'Clicking accordion item %s because it is not active.', name) click(name) except AccordionItemNotFound: logger.debug( 'Clicking accordion item %s because AccordionItemNotFound raised.', name) click(name) locator = locate(name) # Wait a bit for any of the trees to appear wait_for(lambda: sel.is_displayed(ANY_TREE, root=locator), quiet=True, silent_failure=True, delay=0.2, timeout=5) if sel.is_displayed(DYNATREE, root=locator): # Dynatree detected tree = Tree(sel.element(DYNATREE, root=locator)) elif sel.is_displayed(TREEVIEW, root=locator): # treeview detected el = sel.element(TREEVIEW, root=locator) tree_id = sel.get_attribute(el, 'id') tree = BootstrapTreeview(tree_id) else: raise TypeError('None of the supported trees was detected.') if path: return tree.click_path(*path) else: return tree
class DefaultFilter(Updateable, Pretty, Navigatable): filter_form = Form(fields=[ ("filter_tree", { version.LOWEST: CheckboxTree("//div[@id='all_views_treebox']/ul"), '5.7': BootstrapTreeview('df_treebox') }), ]) pretty_attrs = ['name', 'filters'] def __init__(self, name=None, filters=None, appliance=None): Navigatable.__init__(self, appliance=appliance) self.name = name self.filters = filters or [] def update(self, updates, expect_success=True): navigate_to(self, 'All') fill(self.filter_form, {'filter_tree': updates.get('filters')}, action=form_buttons.save) if expect_success: flash.assert_success_message('Default Filters saved successfully')
retire_remove_button = "//span[@id='remove_button']/a/img|//a/img[contains(@src, '/clear')]" set_ownership_form = Form(fields=[( 'user_name', AngularSelect('user_name')), ( 'group_name', AngularSelect('group_name')), ( 'create_button', form_buttons.save), ( 'reset_button', form_buttons.reset), ('cancel_button', form_buttons.cancel)]) drift_table = CheckboxTable( "//th[normalize-space(.)='Timestamp']/ancestor::table[1]") drift_section = BootstrapTreeview('all_sectionsbox') def base_types(template=False): from pkg_resources import iter_entry_points search = "template" if template else "vm" return { ep.name: ep.resolve() for ep in iter_entry_points('manageiq.{}_categories'.format(search)) } def instance_types(category, template=False): from pkg_resources import iter_entry_points search = "template" if template else "vm" return {
class Genealogy(object): """Class, representing genealogy of an infra object with possibility of data retrieval and comparison. Args: o: The :py:class:`Vm` or :py:class:`Template` object. """ genealogy_tree = deferred_verpick({ version.LOWEST: CheckboxTree("//div[@id='genealogy_treebox']/ul"), 5.7: BootstrapTreeview('genealogy_treebox') }) section_comparison_tree = CheckboxTree( "//div[@id='all_sections_treebox']/div/table") apply_button = form_buttons.FormButton("Apply sections") mode_mapping = { "exists": "Exists Mode", "details": "Details Mode", } attr_mapping = { "all": "All Attributes", "different": "Attributes with different values", "same": "Attributes with same values", } def __init__(self, o): self.o = o def navigate(self): self.o.load_details() sel.click(InfoBlock.element("Relationships", "Genealogy")) def compare(self, *objects, **kwargs): """Compares two or more objects in the genealogy. Args: *objects: :py:class:`Vm` or :py:class:`Template` or :py:class:`str` with name. Keywords: sections: Which sections to compare. attributes: `all`, `different` or `same`. Default: `all`. mode: `exists` or `details`. Default: `exists`.""" sections = kwargs.get("sections") attributes = kwargs.get("attributes", "all").lower() mode = kwargs.get("mode", "exists").lower() assert len(objects) >= 2, "You must specify at least two objects" objects = map(lambda o: o.name if isinstance(o, (Vm, Template)) else o, objects) self.navigate() for obj in objects: if not isinstance(obj, list): path = self.genealogy_tree.find_path_to(obj) self.genealogy_tree.check_node(*path) toolbar.select("Compare selected VMs") # COMPARE PAGE flash.assert_no_errors() if sections is not None: map(lambda path: self.section_comparison_tree.check_node(*path), sections) sel.click(self.apply_button) flash.assert_no_errors() # Set requested attributes sets toolbar.select(self.attr_mapping[attributes]) # Set the requested mode toolbar.select(self.mode_mapping[mode]) @property def tree(self): """Returns contents of the tree with genealogy""" self.navigate() return self.genealogy_tree.read_contents() @property def ancestors(self): """Returns list of ancestors of the represented object.""" self.navigate() path = self.genealogy_tree.find_path_to( re.compile(r"^.*?\(Selected\)$")) if not path: raise ValueError("Something wrong happened, path not found!") processed_path = [] for step in path[:-1]: # We will remove the (parent) and (Selected) suffixes processed_path.append( re.sub(r"\s*(?:\(Current\)|\(Parent\))$", "", step)) return processed_path
class Snapshot(object): snapshot_tree = deferred_verpick({ version.LOWEST: Tree("//div[@id='snapshots_treebox']/ul"), '5.7.0.1': BootstrapTreeview('snapshot_treebox') }) def __init__(self, name=None, description=None, memory=None, parent_vm=None): super(Vm.Snapshot, self).__init__() self.name = name self.description = description self.memory = memory self.vm = parent_vm def _nav_to_snapshot_mgmt(self): snapshot_title = '"Snapshots" for Virtual Machine "{}"'.format( self.vm.name) if summary_title() != snapshot_title: self.vm.load_details() sel.click(InfoBlock.element("Properties", "Snapshots")) def does_snapshot_exist(self): self._nav_to_snapshot_mgmt() try: if self.name is not None: self.snapshot_tree.find_path_to( re.compile(self.name + r".*?")) else: self.snapshot_tree.find_path_to( re.compile(self.description + r".*?")) return True except CandidateNotFound: return False except NoSuchElementException: return False def wait_for_snapshot_active(self): self._nav_to_snapshot_mgmt() try: self.snapshot_tree.click_path( *self.snapshot_tree.find_path_to(re.compile(self.name))) if sel.is_displayed_text(self.name + " (Active)"): return True except CandidateNotFound: return False def create(self): self._nav_to_snapshot_mgmt() toolbar.select('Create a new snapshot for this VM') if self.name is not None: fill(snapshot_form, { 'name': self.name, 'description': self.description, 'snapshot_memory': self.memory }, action=snapshot_form.create_button) else: fill(snapshot_form, { 'description': self.description, 'snapshot_memory': self.memory }, action=snapshot_form.create_button) wait_for(self.does_snapshot_exist, num_sec=300, delay=20, fail_func=sel.refresh, handle_exception=True) def delete(self, cancel=False): self._nav_to_snapshot_mgmt() toolbar.select('Delete Snapshots', 'Delete Selected Snapshot', invokes_alert=True) sel.handle_alert(cancel=cancel) if not cancel: flash.assert_message_match( 'Remove Snapshot initiated for 1 ' 'VM and Instance from the CFME Database') def delete_all(self, cancel=False): self._nav_to_snapshot_mgmt() toolbar.select('Delete Snapshots', 'Delete All Existing Snapshots', invokes_alert=True) sel.handle_alert(cancel=cancel) if not cancel: flash.assert_message_match( 'Remove All Snapshots initiated for 1 VM and ' 'Instance from the CFME Database') def revert_to(self, cancel=False): self._nav_to_snapshot_mgmt() self.snapshot_tree.click_path( *self.snapshot_tree.find_path_to(re.compile(self.name))) toolbar.select('Revert to selected snapshot', invokes_alert=True) sel.handle_alert(cancel=cancel) flash.assert_message_match( 'Revert To Snapshot initiated for 1 VM and Instance from ' 'the CFME Database')
from utils.update import Updateable from widgetastic.utils import Fillable accordion_tree = functools.partial(accordion.tree, "Service Dialogs") cfg_btn = functools.partial(tb.select, "Configuration") plus_btn = functools.partial(tb.select, "Add") entry_table = Table({'5.6': "//div[@id='field_values_div']/form/table", '5.5': "//div[@id='field_values_div']/form/fieldset/table"}) text_area_table = Table("//div[@id='dialog_field_div']/fieldset/table[@class='style1']") text_area_table = Table({version.LOWEST: "//div[@id='dialog_field_div']/fieldset/table" "[@class='style1']", '5.5': "//div[@id='dialog_field_div']/div[@class='form-horizontal']"}) dynamic_tree = Tree("//div[@class='modal-content']/div/div/ul[@class='dynatree-container']") bt_tree = BootstrapTreeview('automate_treebox') label_form = Form(fields=[ ('label', Input("label")), ('description_text', Input("description")), ('submit_button', Input("chkbx_submit")), ('cancel_button', Input("chkbx_cancel")) ]) tab_form = Form(fields=[ ('tab_label', Input("tab_label")), ('tab_desc', Input("tab_description")) ]) box_form = Form(fields=[ ('box_label', Input("group_label")),
class Snapshot(object): snapshot_tree = deferred_verpick({ version.LOWEST: Tree("//div[@id='snapshots_treebox']/ul"), '5.7.0.1': BootstrapTreeview('snapshot_treebox') }) def __init__(self, name=None, description=None, memory=None, parent_vm=None): super(Vm.Snapshot, self).__init__() self.name = name self.description = description self.memory = memory self.vm = parent_vm def _nav_to_snapshot_mgmt(self): snapshot_title = '"Snapshots" for Virtual Machine "{}"'.format( self.vm.name) if summary_title() != snapshot_title: self.vm.load_details() sel.click(InfoBlock.element("Properties", "Snapshots")) @property def exists(self): self._nav_to_snapshot_mgmt() try: self.snapshot_tree.find_path_to( re.compile(r"{}.*?".format(self.name or self.description))) return True except CandidateNotFound: return False except NoSuchElementException: return False def _click_tree_path(self, prop): """Find and click the given property in a snapshot tree path. Args: prop (str): Property to check (name or description). Returns: None """ self.snapshot_tree.click_path( *self.snapshot_tree.find_path_to(re.compile(prop))) @property def active(self): """Check if the snapshot is active. Returns: bool: True if snapshot is active, False otherwise. """ self._nav_to_snapshot_mgmt() try: self._click_tree_path(self.name or self.description) if sel.is_displayed_text("{} (Active)".format( self.name or self.description)): return True except CandidateNotFound: return False def create(self): snapshot_dict = {'description': self.description} self._nav_to_snapshot_mgmt() toolbar.select('Create a new snapshot for this VM') if self.name is not None: snapshot_dict['name'] = self.name if self.vm.provider.mgmt.is_vm_running(self.vm.name): snapshot_dict["snapshot_memory"] = self.memory fill(snapshot_form, snapshot_dict, action=snapshot_form.create_button) wait_for(lambda: self.exists, num_sec=300, delay=20, fail_func=sel.refresh, handle_exception=True) def delete(self, cancel=False): self._nav_to_snapshot_mgmt() toolbar.select('Delete Snapshots', 'Delete Selected Snapshot', invokes_alert=True) sel.handle_alert(cancel=cancel) if not cancel: flash.assert_message_match( 'Remove Snapshot initiated for 1 ' 'VM and Instance from the CFME Database') def delete_all(self, cancel=False): self._nav_to_snapshot_mgmt() toolbar.select('Delete Snapshots', 'Delete All Existing Snapshots', invokes_alert=True) sel.handle_alert(cancel=cancel) if not cancel: flash.assert_message_match( 'Remove All Snapshots initiated for 1 VM and ' 'Instance from the CFME Database') def revert_to(self, cancel=False): self._nav_to_snapshot_mgmt() self._click_tree_path(self.name or self.description) toolbar.select('Revert to selected snapshot', invokes_alert=True) sel.handle_alert(cancel=cancel) flash.assert_message_match( 'Revert To Snapshot initiated for 1 VM and Instance from ' 'the CFME Database')
def reports_tree(): if version.current_version() >= '5.7': return BootstrapTreeview("menu_roles_treebox") else: return Tree("//div[@id='menu_roles_treebox']/ul")