# -*- coding: utf-8 -*-
from widgetastic.utils import (
Parameter,
ParametrizedLocator,
Version,
VersionPick
)
from widgetastic.widget import ParametrizedView, Text, View
from widgetastic_manageiq import (
BaseEntitiesView,
NonJSBaseEntity,
JSBaseEntity,
BaseListEntity,
BaseQuadIconEntity,
BaseTileIconEntity,
BootstrapTreeview,
BreadCrumb,
Button,
Checkbox,
Input,
ItemsToolBarViewSelector,
PaginationPane,
SummaryTable,
Table,
TimelinesView,
BaseNonInteractiveEntitiesView
)
from widgetastic_patternfly import (
BootstrapSelect,
CheckableBootstrapTreeview,
Dropdown,
FlashMessages,
Tab
)
from cfme.base.login import BaseLoggedInPage
[docs]class ComputeInfrastructureHostsView(BaseLoggedInPage):
"""Common parts for host views."""
title = Text('.//div[@id="center_div" or @id="main-content"]//h1')
flash = FlashMessages(
'.//div[@id="flash_msg_div"]/div[@id="flash_text_div" or '
'contains(@class, "flash_text_div")]'
)
@property
def in_compute_infrastructure_hosts(self):
def _host_page(title):
return self.navigation.currently_selected == ["Compute", "Infrastructure", title]
return (
self.logged_in_as_current_user and (_host_page("Hosts") or _host_page("Nodes") or
_host_page("Hosts / Nodes"))
)
[docs]class HostQuadIconEntity(BaseQuadIconEntity):
@property
def data(self):
return {
'no_vm': int(self.browser.text(self.QUADRANT.format(pos="a"))),
'state': self.browser.get_attribute("style", self.QUADRANT.format(pos="b")),
'vendor': self.browser.get_attribute("alt", self.QUADRANT.format(pos="c")),
'creds': self.browser.get_attribute("alt", self.QUADRANT.format(pos="d"))
}
[docs]class HostTileIconEntity(BaseTileIconEntity):
quad_icon = ParametrizedView.nested(HostQuadIconEntity)
[docs]class HostListEntity(BaseListEntity):
pass
[docs]class NonJSHostEntity(NonJSBaseEntity):
quad_entity = HostQuadIconEntity
list_entity = HostListEntity
tile_entity = HostTileIconEntity
[docs]def HostEntity(): # noqa
""" Temporary wrapper for Host Entity during transition to JS based Entity
"""
return VersionPick({
Version.lowest(): NonJSHostEntity,
'5.9': JSBaseEntity,
})
[docs]class HostDetailsEntities(View):
"""Represents Details page."""
properties = SummaryTable(title="Properties")
relationships = SummaryTable(title="Relationships")
compliance = SummaryTable(title="Compliance")
configuration = SummaryTable(title="Configuration")
smart_management = SummaryTable(title="Smart Management")
security = SummaryTable(title="Security")
authentication_status = SummaryTable(title="Authentication Status")
openstack_hardware = SummaryTable(title="Openstack Hardware")
[docs]class HostDetailsView(ComputeInfrastructureHostsView):
"""Main Host details page."""
breadcrumb = BreadCrumb(locator='.//ol[@class="breadcrumb"]')
toolbar = View.nested(HostDetailsToolbar)
entities = View.nested(HostDetailsEntities)
@property
def is_displayed(self):
title = "{name} (Summary)".format(name=self.context["object"].name)
return self.in_compute_infrastructure_hosts and self.breadcrumb.active_location == title
[docs]class HostDriftHistory(ComputeInfrastructureHostsView):
breadcrumb = BreadCrumb(locator='.//ol[@class="breadcrumb"]')
history_table = Table(locator='.//div[@id="main_div"]/table')
analyze_button = Button(title="Select up to 10 timestamps for Drift Analysis")
@property
def is_displayed(self):
return (
self.in_compute_infrastructure_hosts and
self.title.text == "Drift History" and
self.history_table.is_displayed
)
[docs]class HostDriftAnalysis(ComputeInfrastructureHostsView):
apply_button = Button("Apply")
drift_sections = CheckableBootstrapTreeview(tree_id="all_sectionsbox")
@ParametrizedView.nested
class drift_analysis(ParametrizedView): # noqa
PARAMETERS = ("drift_section", )
CELLS = "../td//i"
row = Text(ParametrizedLocator(".//div[@id='compare-grid']/"
"/th[normalize-space(.)={drift_section|quote}]"))
@property
def is_changed(self):
cells = self.browser.elements(self.CELLS, parent=self.row)
attrs = [self.browser.get_attribute("class", cell) for cell in cells]
return "drift-delta" in attrs
@View.nested
class toolbar(View): # noqa
all_attributes = Button(title="All attributes")
different_values_attributes = Button(title="Attributes with different")
same_values_attributes = Button(title="Attributes with same values")
details_mode = Button(title="Details Mode")
exists_mode = Button(title="Exists Mode")
@property
def is_displayed(self):
return (
self.in_compute_infrastructure_hosts and
self.title.text == "'{}' Drift Analysis".format(self.context["object"].name)
)
[docs]class HostTimelinesView(TimelinesView, ComputeInfrastructureHostsView):
"""Represents a Host Timelines page."""
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and super(TimelinesView, self).is_displayed
[docs]class HostDiscoverView(ComputeInfrastructureHostsView):
"""Discover View from Compute/Infrastructure/Hosts page."""
esx = Checkbox(name="discover_type_esx")
ipmi = Checkbox(name="discover_type_ipmi")
from_ip1 = Input(name="from_first")
from_ip2 = Input(name="from_second")
from_ip3 = Input(name="from_third")
from_ip4 = Input(name="from_fourth")
to_ip4 = Input(name="to_fourth")
start_button = Button("Start")
cancel_button = Button("Cancel")
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and self.title.text == "Hosts / Nodes Discovery"
[docs]class HostManagePoliciesView(BaseLoggedInPage):
"""Host's Manage Policies view."""
policies = BootstrapTreeview("protectbox")
entities = View.nested(BaseNonInteractiveEntitiesView)
save_button = Button("Save")
reset_button = Button("Reset")
cancel_button = Button("Cancel")
@property
def is_displayed(self):
return False
[docs]class HostEntitiesView(BaseEntitiesView):
"""Represents the view with different items like hosts."""
@property
def entity_class(self):
return HostEntity().pick(self.browser.product_version)
[docs]class HostsView(ComputeInfrastructureHostsView):
toolbar = View.nested(HostsToolbar)
sidebar = View.nested(HostSideBar)
paginator = PaginationPane()
including_entities = View.include(HostEntitiesView, use_parent=True)
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and self.title.text in "Hosts / Nodes"
[docs]class HostAddView(HostFormView):
host_platform = BootstrapSelect("user_assigned_os")
add_button = Button("Add")
cancel_button = Button("Cancel")
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and self.title.text == "Add New Host"
[docs]class HostEditView(HostFormView):
"""View for editing a single host"""
save_button = Button("Save")
reset_button = Button("Reset")
change_stored_password = Text(".//a[contains(@ng-hide, 'bChangeStoredPassword')]")
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and self.title.text == "Info/Settings"
[docs]class HostsEditView(HostEditView):
"""View when editing multiple hosts
Restricted to endpoints section of the form
Title changes
Must select host before validation
"""
validation_host = BootstrapSelect('validate_id') # only shown when editing multiple hosts
@property
def is_displayed(self):
return self.in_compute_infrastructure_hosts and self.title.text == 'Credentials/Settings'