Source code for cfme.automate.explorer.namespace

# -*- coding: utf-8 -*-
import attr

from cached_property import cached_property

from navmazing import NavigateToAttribute, NavigateToSibling
from widgetastic.widget import Text
from widgetastic_manageiq import Table
from widgetastic_patternfly import CandidateNotFound, Input, Button

from cfme.exceptions import ItemNotFound
from cfme.modeling.base import BaseCollection, BaseEntity
from cfme.utils.appliance.implementations.ui import navigator, CFMENavigateStep, navigate_to

from . import AutomateExplorerView, check_tree_path
from .domain import DomainDetailsView, Domain


[docs]class NamespaceDetailsView(AutomateExplorerView): title = Text('#explorer_title_text') namespaces = Table('#ns_details_grid') @property def is_displayed(self): return ( self.in_explorer and self.title.text == 'Automate Namespace "{}"'.format(self.context['object'].name) and self.datastore.is_opened and check_tree_path( self.datastore.tree.currently_selected, self.context['object'].tree_path))
[docs]class NamespaceForm(AutomateExplorerView): title = Text('#explorer_title_text') name = Input(name='ns_name') description = Input(name='ns_description') cancel_button = Button('Cancel')
[docs]class NamespaceAddView(NamespaceForm): add_button = Button('Add') @property def is_displayed(self): return ( self.in_explorer and self.datastore.is_opened and check_tree_path( self.datastore.tree.currently_selected, self.context['object'].tree_path) and self.title.text == 'Adding a new Automate Namespace')
[docs]class NamespaceEditView(NamespaceForm): save_button = Button('Save') @property def is_displayed(self): return ( self.in_explorer and self.datastore.is_opened and check_tree_path( self.datastore.tree.currently_selected, self.context['object'].tree_path) and self.title.text == 'Editing Automate Namespace "{}"'.format(self.obj.name))
[docs]class Namespace(BaseEntity): def __init__(self, collection, name, description=None): from .klass import ClassCollection self._collections = { 'namespaces': NamespaceCollection, 'classes': ClassCollection } super(Namespace, self).__init__(collection) self.name = name if description is not None: self.description = description __repr__ = object.__repr__ def __hash__(self): return hash((self.name, id(self.parent))) @cached_property def description(self): return self.db_object.description @cached_property def db_id(self): table = self.appliance.db.client['miq_ae_namespaces'] try: return self.appliance.db.client.session.query(table.id).filter( table.name == self.name, table.parent_id == self.parent_obj.db_id)[0] # noqa except IndexError: raise ItemNotFound('Namespace named {} not found in the database'.format(self.name)) @property def db_object(self): table = self.appliance.db.client['miq_ae_namespaces'] return self.appliance.db.client.session.query(table).filter(table.id == self.db_id).first() @property def parent_obj(self): return self.parent.parent @property def domain(self): return self.parent_obj.domain @property def tree_path(self): return self.parent_obj.tree_path + [self.name] @cached_property def namespaces(self): return self.collections.namespaces @cached_property def classes(self): return self.collections.classes
[docs] def delete(self, cancel=False): # Ensure this has correct data self.description # Do it! details_page = navigate_to(self, 'Details') details_page.configuration.item_select('Remove this Namespace', handle_alert=not cancel) if cancel: assert details_page.is_displayed details_page.flash.assert_no_error() else: if isinstance(self.parent_obj, Domain): result_view = self.create_view(DomainDetailsView, self.parent_obj) else: result_view = self.create_view(NamespaceDetailsView, self.parent_obj) assert result_view.is_displayed result_view.flash.assert_no_error() result_view.flash.assert_message( 'Automate Namespace "{}": Delete successful'.format(self.description or self.name))
[docs] def update(self, updates): view = navigate_to(self, 'Edit') changed = view.fill(updates) if changed: view.save_button.click() else: view.cancel_button.click() view = self.create_view(NamespaceDetailsView, override=updates) assert view.is_displayed view.flash.assert_no_error() if changed: if self.appliance.version >= '5.8.2': text = ( updates.get('description', self.description) or updates.get('name', self.name)) view.flash.assert_message( 'Automate Namespace "{}" was saved'.format(text)) else: view.flash.assert_message( 'Automate Namespace "{}" was saved'.format(updates.get('name', self.name))) else: view.flash.assert_message( 'Edit of Automate Namespace "{}" was cancelled by the user'.format(self.name))
@property def exists(self): try: navigate_to(self, 'Details') return True except CandidateNotFound: return False
[docs] def delete_if_exists(self): if self.exists: self.delete()
@attr.s
[docs]class NamespaceCollection(BaseCollection): ENTITY = Namespace def __eq__(self, other): return self.parent == other.parent @property def tree_path(self): return self.parent.tree_path
[docs] def create(self, name=None, description=None, cancel=False): add_page = navigate_to(self, 'Add') fill_dict = { k: v for k, v in {'name': name, 'description': description}.items() if v is not None} add_page.fill(fill_dict) if cancel: add_page.cancel_button.click() add_page.flash.assert_no_error() add_page.flash.assert_message('Add of new Automate Namespace was cancelled by the user') return None else: add_page.add_button.click() add_page.flash.assert_no_error() if self.appliance.version >= '5.8.2': add_page.flash.assert_message( 'Automate Namespace "{}" was added'.format(description or name)) else: add_page.flash.assert_message('Automate Namespace "{}" was added'.format(name)) return self.instantiate(name=name, description=description)
[docs] def delete(self, *namespaces): all_page = navigate_to(self.parent, 'Details') namespaces = list(namespaces) parents = set() # Check if the parent is the same for namespace in namespaces: parents.add(namespace.parent.parent) if len(parents) > 1: raise ValueError('You passed namespaces that are not under one parent.') checked_namespaces = [] if not all_page.namespaces.is_displayed: raise ValueError('No namespace found!') all_page.namespaces.uncheck_all() for row in all_page.namespaces.rows(_row__attr_startswith=('data-click-id', 'aen-')): name = row[2].text for namespace in namespaces: if namespace.name == name: checked_namespaces.append(namespace) row[0].check() break if set(namespaces) == set(checked_namespaces): break if set(namespaces) != set(checked_namespaces): raise ValueError('Some of the namespaces were not found in the UI.') if isinstance(self.parent, Domain): all_page.configuration.item_select('Remove Namespaces', handle_alert=True) else: all_page.configuration.item_select('Remove selected Items', handle_alert=True) all_page.flash.assert_no_error() for namespace in checked_namespaces: all_page.flash.assert_message( 'Automate Namespace "{}": Delete successful'.format( namespace.description or namespace.name))
@navigator.register(NamespaceCollection)
[docs]class Add(CFMENavigateStep): VIEW = NamespaceAddView prerequisite = NavigateToAttribute('parent', 'Details')
[docs] def step(self): self.prerequisite_view.configuration.item_select('Add a New Namespace')
@navigator.register(Namespace)
[docs]class Details(CFMENavigateStep): VIEW = NamespaceDetailsView prerequisite = NavigateToAttribute('appliance.server', 'AutomateExplorer')
[docs] def step(self): self.prerequisite_view.datastore.tree.click_path(*self.obj.tree_path)
@navigator.register(Namespace)
[docs]class Edit(CFMENavigateStep): VIEW = NamespaceEditView prerequisite = NavigateToSibling('Details')
[docs] def step(self): self.prerequisite_view.configuration.item_select('Edit this Namespace')