import attr
from navmazing import NavigateToAttribute, NavigateToSibling
from widgetastic.exceptions import NoSuchElementException
from cfme.common import Taggable
from cfme.exceptions import ItemNotFound
from cfme.modeling.base import BaseCollection, BaseEntity, parent_of_type
from cfme.networks.views import (NetworkRouterDetailsView, NetworkRouterView, NetworkRouterAddView,
NetworkRouterEditView, NetworkRouterAddInterfaceView)
from cfme.utils import version
from cfme.utils.appliance.implementations.ui import navigator, CFMENavigateStep, navigate_to
from cfme.utils.wait import wait_for
@attr.s
[docs]class NetworkRouter(Taggable, BaseEntity):
""" Class representing network ports in sdn"""
in_version = ('5.8', version.LATEST)
category = 'networks'
string_name = 'NetworkRouter'
quad_name = None
db_types = ['NetworkRouter']
name = attr.ib()
provider_obj = attr.ib(default=None)
ext_network = attr.ib(default=None)
[docs] def add_interface(self, subnet_name):
"""Adds subnet as an interface to current router
Args:
subnet_name: (str) name of the subnet to be added
"""
view = navigate_to(self, 'AddInterface')
view.subnet_name.fill(subnet_name)
view.add.click()
success_msg = 'Subnet "{subnet}" added to Router "{router}"'.format(subnet=subnet_name,
router=self.name)
view.flash.assert_success_message(success_msg)
[docs] def delete(self):
"""Deletes current cloud router"""
view = navigate_to(self, 'Details')
view.toolbar.configuration.item_select('Delete this Router', handle_alert=True)
view.flash.assert_success_message('Delete initiated for 1 Network Router.')
[docs] def edit(self, name=None, change_external_gw=None, ext_network=None, ext_network_subnet=None):
"""Edit this router
Args:
name: (str) new name of router
change_external_gw: (bool) external gateway, True stands for 'Yes', False - 'No'
ext_network: (str) name of external network to be connected as gateway to router.
applicable if 'external gateway' is enabled
ext_network_subnet: (str) name of subnet of ext_network.
applicable if 'external gateway' is enabled
"""
view = navigate_to(self, 'Edit')
view.fill({'router_name': name,
'ext_gateway': change_external_gw,
'network_name': ext_network,
'subnet_name': ext_network_subnet})
view.save.click()
success_msg = 'Network Router "{}" updated'.format(name if name else self.name)
view.flash.assert_success_message(success_msg)
if name:
self.name = name
if change_external_gw is False:
self.ext_network = None
if ext_network:
self.ext_network = ext_network
@property
def exists(self):
try:
navigate_to(self, 'Details')
except (ItemNotFound, NoSuchElementException):
return False
else:
return True
@property
def cloud_network(self):
""" Return name of network that router connected to"""
view = navigate_to(self, 'Details')
return view.entities.relationships.get_text_of('Cloud Network')
@property
def cloud_tenant(self):
""" Return name of tenant that router belongs to"""
view = navigate_to(self, 'Details')
return view.entities.relationships.get_text_of('Cloud Tenant')
@property
def provider(self):
from cfme.networks.provider import NetworkProvider
return parent_of_type(self, NetworkProvider)
@property
def network_provider(self):
""" Returns network provider """
if self.provider:
return self.provider
# otherwise get provider name from ui
view = navigate_to(self, 'Details')
try:
prov_name = view.entities.relationships.get_text_of("Network Manager")
collection = self.appliance.collections.network_provider
return collection.instantiate(name=prov_name)
except ItemNotFound: # BZ 1480577
return None
@attr.s
[docs]class NetworkRouterCollection(BaseCollection):
""" Collection object for NetworkRouter object
Note: Network providers object are not implemented in mgmt
"""
ENTITY = NetworkRouter
[docs] def create(self, name, provider, tenant, network_manager, has_external_gw=False,
ext_network=None, ext_network_subnet=None):
"""Create network router
Args:
name: (str) name of router
provider: crud object of OpenStack cloud provider
tenant: (str) name of tenant to place router to
network_manager: (str) name of network manager
has_external_gw: (bool) represents if router has external gateway
ext_network: (str) name of the external cloud network
to be connected as a gateway to the router.
Is used if has_external_gw == 'Yes'
ext_network_subnet: (str) name of the subnet of ext_network.
Is used if has_external_gw == 'Yes'
Returns: instance of cfme.networks.network_router.NetworkRouter
"""
view = navigate_to(self, 'Add')
form_params = {'network_manager': network_manager,
'router_name': name,
'cloud_tenant': tenant}
if has_external_gw:
form_params.update({'ext_gateway': has_external_gw,
'network_name': ext_network,
'subnet_name': ext_network_subnet})
view.fill(form_params)
view.add.click()
view.flash.assert_success_message('Network Router "{}" created'.format(name))
router = self.instantiate(name, provider, ext_network)
# Refresh provider's relationships to have new router displayed
wait_for(provider.is_refreshed, func_kwargs=dict(refresh_delta=10), timeout=600)
wait_for(lambda: router.exists, timeout=100, fail_func=router.browser.refresh)
return router
[docs] def all(self):
if self.filters.get('parent'):
view = navigate_to(self.filters.get('parent'), 'NetworkRouters')
else:
view = navigate_to(self, 'All')
list_networks_obj = view.entities.get_all(surf_pages=True)
return [self.instantiate(name=r.name) for r in list_networks_obj]
@navigator.register(NetworkRouterCollection, 'All')
[docs]class All(CFMENavigateStep):
VIEW = NetworkRouterView
prerequisite = NavigateToAttribute('appliance.server', 'LoggedIn')
[docs] def step(self):
self.prerequisite_view.navigation.select('Networks', 'Network Routers')
[docs] def resetter(self):
"""Reset the view"""
self.view.browser.refresh()
@navigator.register(NetworkRouter, 'Details')
[docs]class Details(CFMENavigateStep):
prerequisite = NavigateToAttribute('parent', 'All')
VIEW = NetworkRouterDetailsView
[docs] def step(self):
self.prerequisite_view.entities.get_entity(name=self.obj.name).click()
@navigator.register(NetworkRouterCollection, 'Add')
[docs]class AddRouter(CFMENavigateStep):
prerequisite = NavigateToSibling('All')
VIEW = NetworkRouterAddView
[docs] def step(self):
self.prerequisite_view.toolbar.configuration.item_select('Add a new Router')
@navigator.register(NetworkRouter, 'Edit')
[docs]class EditRouter(CFMENavigateStep):
prerequisite = NavigateToSibling('Details')
VIEW = NetworkRouterEditView
[docs] def step(self):
self.prerequisite_view.toolbar.configuration.item_select('Edit this Router')
@navigator.register(NetworkRouter, 'AddInterface')
[docs]class AddInterface(CFMENavigateStep):
prerequisite = NavigateToSibling('Details')
VIEW = NetworkRouterAddInterfaceView
[docs] def step(self):
self.prerequisite_view.toolbar.configuration.item_select('Add Interface to this Router')