# -*- coding: utf-8 -*-
import attr
from navmazing import NavigateToSibling, NavigateToAttribute
from widgetastic.widget import View, Text, NoSuchElementException
from widgetastic_patternfly import BreadCrumb, Button, Dropdown
from cfme.base.ui import BaseLoggedInPage
from cfme.common import TagPageView, Taggable
from cfme.exceptions import SnapshotNotFoundError, ItemNotFound
from cfme.modeling.base import BaseCollection, BaseEntity
from cfme.utils.appliance.implementations.ui import CFMENavigateStep, navigator, navigate_to
from cfme.utils.log import logger
from cfme.utils.providers import get_crud_by_name
from cfme.utils.wait import wait_for
from widgetastic_manageiq import (
Accordion, BaseEntitiesView, ItemsToolBarViewSelector, ManageIQTree, SummaryTable)
[docs]class VolumeSnapshotDetailsEntities(View):
"""The entities on the Volume Snapshot detail page"""
breadcrumb = BreadCrumb()
title = Text('.//div[@id="center_div" or @id="main-content"]//h1')
properties = SummaryTable('Properties')
relationships = SummaryTable('Relationships')
smart_management = SummaryTable('Smart Management')
[docs]class VolumeSnapshotView(BaseLoggedInPage):
"""A base view for all the Volume Snapshot pages"""
@property
def in_volume_snapshots(self):
return (
self.logged_in_as_current_user and
self.navigation.currently_selected == ['Storage', 'Block Storage', 'Volume Snapshots']
)
@property
def is_displayed(self):
return self.in_volume_snapshots
[docs]class VolumeSnapshotAllView(VolumeSnapshotView):
"""The all Volume Snapshot page"""
toolbar = View.nested(VolumeSnapshotToolbar)
including_entities = View.include(BaseEntitiesView, use_parent=True)
@property
def is_displayed(self):
return (
self.in_volume_snapshots and
self.entities.title.text == 'Cloud Volume Snapshots')
[docs]class VolumeSnapshotDetailsView(VolumeSnapshotView):
"""The detail Volume Snapshot page"""
@property
def is_displayed(self):
expected_title = '{} (Summary)'.format(self.context['object'].name)
return (
self.in_volume_snapshots and
self.entities.title.text == expected_title and
self.entities.breadcrumb.active_location == expected_title)
toolbar = View.nested(VolumeSnapshotDetailsToolbar)
sidebar = View.nested(VolumeSnapshotDetailSidebar)
entities = View.nested(VolumeSnapshotDetailsEntities)
@attr.s
[docs]class VolumeSnapshot(BaseEntity, Taggable):
""" Model of an Storage Volume Snapshots in cfme
Args:
name: name of the snapshot
provider: provider
"""
name = attr.ib()
provider = attr.ib()
[docs] def refresh(self):
self.provider.refresh_provider_relationships()
self.browser.refresh()
@property
def exists(self):
""" check for snapshot exist on UI.
Returns:
:py:class:`bool`
"""
view = navigate_to(self.parent, 'All')
return self.name in view.entities.all_entity_names
@property
def status(self):
""" status of cloud volume snapshot.
Returns:
:py:class:`str` Status of volume snapshot.
"""
view = navigate_to(self.parent, 'All')
view.toolbar.view_selector.select("List View")
for item in view.entities.elements.read():
if self.name in item['Name']:
return str(item['Status'])
@property
def size(self):
""" size of cloud volume snapshot.
Returns:
:py:class:`int` size of volume snapshot in GB.
"""
view = navigate_to(self, 'Details')
return int(view.entities.properties.get_text_of('Size').split()[0])
@property
def volume_name(self):
""" volume name of snapshot.
Returns:
:py:class:`str` respective volume name.
"""
view = navigate_to(self, 'Details')
return view.entities.relationships.get_text_of('Cloud Volume')
@property
def tenant_name(self):
""" Tenant name of snapshot.
Returns:
:py:class:`str` respective tenant name for snapshot.
"""
view = navigate_to(self, 'Details')
return view.entities.relationships.get_text_of('Cloud Tenants')
[docs] def delete(self, wait=True):
"""Delete snapshot """
view = navigate_to(self, 'Details')
view.toolbar.configuration.item_select('Delete Cloud Volume Snapshot')
view.flash.assert_success_message('Delete initiated for 1 Cloud Volume Snapshot.')
if wait:
wait_for(
lambda: not self.exists,
message="Wait snapshot to disappear",
delay=20,
timeout=800,
fail_func=self.refresh
)
@attr.s
[docs]class VolumeSnapshotCollection(BaseCollection):
"""Collection object for :py:class:`cfme.storage.volume_snapshots.VolumeSnapshot`"""
ENTITY = VolumeSnapshot
[docs] def all(self):
"""returning all Snapshot objects for respective storage manager type"""
view = navigate_to(self, 'All')
view.toolbar.view_selector.select("List View")
snapshots = []
try:
if 'provider' in self.filters:
for item in view.entities.elements.read():
if self.filters.get('provider').name in item['Storage Manager']:
snapshots.append(self.instantiate(name=item['Name'],
provider=self.filters.get('provider')))
else:
for item in view.entities.elements.read():
provider_name = item['Storage Manager'].split()[0]
provider = get_crud_by_name(provider_name)
snapshots.append(self.instantiate(name=item['Name'], provider=provider))
except NoSuchElementException:
if snapshots:
logger.error('VolumeSnapshotCollection: '
'NoSuchElementException in the middle of entities read')
else:
logger.warning('The snapshot table is probably not present or empty')
return snapshots
@navigator.register(VolumeSnapshotCollection, 'All')
[docs]class All(CFMENavigateStep):
VIEW = VolumeSnapshotAllView
prerequisite = NavigateToAttribute('appliance.server', 'LoggedIn')
[docs] def step(self):
self.prerequisite_view.navigation.select('Storage', 'Block Storage', 'Volume Snapshots')
@navigator.register(VolumeSnapshot, 'Details')
[docs]class Details(CFMENavigateStep):
VIEW = VolumeSnapshotDetailsView
prerequisite = NavigateToAttribute('parent', 'All')
[docs] def step(self, *args, **kwargs):
try:
self.prerequisite_view.entities.get_entity(name=self.obj.name,
surf_pages=True).click()
except ItemNotFound:
raise SnapshotNotFoundError('Could not locate volume snapshot {}'.format(self.obj.name))
@navigator.register(VolumeSnapshot, 'EditTagsFromDetails')
[docs]class SnapshotDetailEditTag(CFMENavigateStep):
""" This navigation destination help to Taggable"""
VIEW = TagPageView
prerequisite = NavigateToSibling('Details')
[docs] def step(self, *args, **kwargs):
self.prerequisite_view.toolbar.policy.item_select('Edit Tags')