Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

Commit

Permalink
[1LP][RFR] All Provider collections (#6859)
Browse files Browse the repository at this point in the history
* initial changes to InfraProvider to turn it into collections
updated all infra providers
got rid of appliance in get_crud calls and etc

* initial changes to InfraProvider to turn it into collections
updated all infra providers
got rid of appliance in get_crud calls and etc
updated cloud provider
updated azure provider
turned EC2 provider to collections
updated GCE provider
updated OpenStack provider
updated vCloud provider
added collection to list of collections; moved discovery to collections; added some hacks until all provider collections are created
fixes to get the ball rolling
updated cloud and network providers fixes and updated setup.py
turned containers providers into collection
fixed physical providers
fixed some found collection issues
  • Loading branch information
izapolsk authored and mshriver committed Apr 27, 2018
1 parent 6c1919b commit 1fe4600
Show file tree
Hide file tree
Showing 30 changed files with 665 additions and 578 deletions.
134 changes: 86 additions & 48 deletions cfme/cloud/provider/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
""" A model of a Cloud Provider in CFME
"""
import attr
from navmazing import NavigateToSibling, NavigateToAttribute
from widgetastic.exceptions import MoveTargetOutOfBoundsException
from widgetastic.widget import View
from widgetastic_patternfly import Dropdown

from cfme.base.login import BaseLoggedInPage
from cfme.common import TagPageView
from cfme.common.provider import CloudInfraProvider
from cfme.common.provider import CloudInfraProvider, provider_types
from cfme.common.provider_views import (
CloudProviderAddView, CloudProviderEditView, CloudProviderDetailsView, CloudProvidersView,
CloudProvidersDiscoverView)
from cfme.common.vm_views import VMToolbar, VMEntities
from cfme.utils.appliance import Navigatable
from cfme.modeling.base import BaseCollection
from cfme.utils.appliance.implementations.ui import navigator, navigate_to, CFMENavigateStep
from cfme.utils.log import logger
from cfme.utils.pretty import Pretty
Expand Down Expand Up @@ -73,23 +74,22 @@ def is_displayed(self):
including_entities = View.include(VMEntities, use_parent=True)


@attr.s(hash=False)
class CloudProvider(Pretty, CloudInfraProvider):
"""
Abstract model of a cloud provider in cfme. See EC2Provider or OpenStackProvider.
Args:
name: Name of the provider.
endpoints: one or several provider endpoints like DefaultEndpoint. it should be either dict
in format dict{endpoint.name, endpoint, endpoint_n.name, endpoint_n}, list of endpoints or
mere one endpoint
key: The CFME key of the provider in the yaml.
# TODO: update all provider doc strings when provider conversion is done
Usage:
credentials = Credential(principal='bad', secret='reallybad')
endpoint = DefaultEndpoint(hostname='some_host', region='us-west', credentials=credentials)
myprov = VMwareProvider(name='foo',
endpoints=endpoint)
myprov = collections.instantiate(prov_class=OpenStackProvider, name='foo',
endpoints=endpoint)
myprov.create()
"""
provider_types = {}
Expand All @@ -102,12 +102,13 @@ class CloudProvider(Pretty, CloudInfraProvider):
template_name = "Images"
db_types = ["CloudManager"]

def __init__(self, name=None, endpoints=None, zone=None, key=None, appliance=None):
Navigatable.__init__(self, appliance=appliance)
self.name = name
self.zone = zone
self.key = key
self.endpoints = self._prepare_endpoints(endpoints)
name = attr.ib(default=None)
key = attr.ib(default=None)
zone = attr.ib(default=None)

def __attrs_post_init__(self):
super(CloudProvider, self).__attrs_post_init__()
self.parent = self.appliance.collections.cloud_providers

def as_fill_value(self):
return self.name
Expand All @@ -123,7 +124,77 @@ def discover_dict(credential):
raise NotImplementedError("This provider doesn't support discovery")


@attr.s
class CloudProviderCollection(BaseCollection):
"""Collection object for CloudProvider object
"""

ENTITY = CloudProvider

def all(self):
view = navigate_to(self, 'All')
provs = view.entities.get_all(surf_pages=True)

# trying to figure out provider type and class
# todo: move to all providers collection later
def _get_class(pid):
prov_type = self.appliance.rest_api.collections.providers.get(id=pid)['type']
for prov_class in provider_types('cloud').values():
if prov_class.db_types[0] in prov_type:
return prov_class

return [self.instantiate(prov_class=_get_class(p.data['id']), name=p.name) for p in provs]

def instantiate(self, prov_class, *args, **kwargs):
return prov_class.from_collection(self, *args, **kwargs)

def create(self, prov_class, *args, **kwargs):
# ugly workaround until I move everything to main class
class_attrs = [at.name for at in attr.fields(prov_class)]
init_kwargs = {}
create_kwargs = {}
for name, value in kwargs.items():
if name not in class_attrs:
create_kwargs[name] = value
else:
init_kwargs[name] = value

obj = self.instantiate(prov_class, *args, **init_kwargs)
obj.create(**create_kwargs)
return obj

def discover(self, credential, discover_cls, cancel=False):
"""
Discover cloud providers. Note: only starts discovery, doesn't
wait for it to finish.
Args:
credential (cfme.base.credential.Credential): Discovery credentials.
cancel (boolean): Whether to cancel out of the discover UI.
discover_cls: class of the discovery item
"""
view = navigate_to(self, 'Discover')
if discover_cls:
view.fill({'discover_type': discover_cls.discover_name})
view.fields.fill(discover_cls.discover_dict(credential))

if cancel:
view.cancel.click()
else:
view.start.click()

# todo: combine with discover ?
def wait_for_new_provider(self):
view = navigate_to(self, 'All')
logger.info('Waiting for a provider to appear...')
wait_for(lambda: int(view.entities.paginator.items_amount), fail_condition=0,
message="Wait for any provider to appear", num_sec=1000,
fail_func=view.browser.refresh)


# todo: to remove those register statements when all providers are turned into collections
@navigator.register(CloudProvider, 'All')
@navigator.register(CloudProviderCollection, 'All')
class All(CFMENavigateStep):
VIEW = CloudProvidersView
prerequisite = NavigateToAttribute('appliance.server', 'LoggedIn')
Expand All @@ -140,6 +211,7 @@ def resetter(self):


@navigator.register(CloudProvider, 'Add')
@navigator.register(CloudProviderCollection, 'Add')
class New(CFMENavigateStep):
VIEW = CloudProviderAddView
prerequisite = NavigateToSibling('All')
Expand All @@ -149,6 +221,7 @@ def step(self):


@navigator.register(CloudProvider, 'Discover')
@navigator.register(CloudProviderCollection, 'Discover')
class Discover(CFMENavigateStep):
VIEW = CloudProvidersDiscoverView
prerequisite = NavigateToSibling('All')
Expand Down Expand Up @@ -233,38 +306,3 @@ class Images(CFMENavigateStep):

def step(self, *args, **kwargs):
self.prerequisite_view.entities.summary("Relationships").click_at('Images')


def get_all_providers():
"""Returns list of all providers"""
view = navigate_to(CloudProvider, 'All')
return [item.name for item in view.entities.get_all(surf_pages=True)]


def discover(credential, discover_cls, cancel=False):
"""
Discover cloud providers. Note: only starts discovery, doesn't
wait for it to finish.
Args:
credential (cfme.base.credential.Credential): Discovery credentials.
cancel (boolean): Whether to cancel out of the discover UI.
discover_cls: class of the discovery item
"""
view = navigate_to(CloudProvider, 'Discover')
if discover_cls:
view.fill({'discover_type': discover_cls.discover_name})
view.fields.fill(discover_cls.discover_dict(credential))

if cancel:
view.cancel.click()
else:
view.start.click()


def wait_for_a_provider():
view = navigate_to(CloudProvider, 'All')
logger.info('Waiting for a provider to appear...')
wait_for(lambda: int(view.entities.paginator.items_amount), fail_condition=0,
message="Wait for any provider to appear", num_sec=1000,
fail_func=view.browser.refresh)
21 changes: 10 additions & 11 deletions cfme/cloud/provider/azure.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import attr

from wrapanapi.msazure import AzureSystem

from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm
Expand All @@ -22,6 +24,7 @@ class AzureEndpointForm(DefaultEndpointForm):
pass


@attr.s(hash=False)
class AzureProvider(CloudProvider):
"""
BaseProvider->CloudProvider->AzureProvider class.
Expand All @@ -35,13 +38,9 @@ class AzureProvider(CloudProvider):
discover_name = "Azure"
settings_key = 'ems_azure'

def __init__(self, name=None, endpoints=None, zone=None, key=None, region=None,
tenant_id=None, subscription_id=None, appliance=None):
super(AzureProvider, self).__init__(name=name, endpoints=endpoints,
zone=zone, key=key, appliance=appliance)
self.region = region # Region can be a string or a dict for version pick
self.tenant_id = tenant_id
self.subscription_id = subscription_id
region = attr.ib(default=None)
tenant_id = attr.ib(default=None)
subscription_id = attr.ib(default=None)

@property
def view_value_mapping(self):
Expand All @@ -60,18 +59,18 @@ def deployment_helper(self, deploy_args):
return self.data['provisioning']

@classmethod
def from_config(cls, prov_config, prov_key, appliance=None):
def from_config(cls, prov_config, prov_key):
endpoint = AzureEndpoint(**prov_config['endpoints']['default'])
# HACK: stray domain entry in credentials, so ensure it is not there
endpoint.credentials.domain = None
return cls(
return cls.appliance.collections.cloud_providers.instantiate(
prov_class=cls,
name=prov_config['name'],
region=prov_config.get('region'),
tenant_id=prov_config['tenant_id'],
subscription_id=prov_config['subscription_id'],
endpoints={endpoint.name: endpoint},
key=prov_key,
appliance=appliance)
key=prov_key)

@staticmethod
def discover_dict(credential):
Expand Down
27 changes: 13 additions & 14 deletions cfme/cloud/provider/ec2.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import attr

from widgetastic.widget import View
from widgetastic_patternfly import Tab, Input, Button
from wrapanapi.ec2 import EC2System
Expand Down Expand Up @@ -35,6 +37,7 @@ class smart_state_docker(Tab, BeforeFillMixin): # NOQA
validate = Button('Validate')


@attr.s(hash=False)
class EC2Provider(CloudProvider):
"""
BaseProvider->CloudProvider->EC2Provider class.
Expand All @@ -48,13 +51,8 @@ class EC2Provider(CloudProvider):
discover_name = "Amazon EC2"
settings_key = 'ems_amazon'

def __init__(
self, name=None, endpoints=None, zone=None, key=None, region=None, region_name=None,
appliance=None):
super(EC2Provider, self).__init__(name=name, endpoints=endpoints,
zone=zone, key=key, appliance=appliance)
self.region = region
self.region_name = region_name
region = attr.ib(default=None)
region_name = attr.ib(default=None)

@property
def view_value_mapping(self):
Expand All @@ -69,13 +67,14 @@ def view_value_mapping(self):
def from_config(cls, prov_config, prov_key, appliance=None):
"""Returns the EC" object from configuration"""
endpoint = EC2Endpoint(**prov_config['endpoints']['default'])
return cls(name=prov_config['name'],
region=prov_config['region'],
region_name=prov_config['region_name'],
endpoints={endpoint.name: endpoint},
zone=prov_config['server_zone'],
key=prov_key,
appliance=appliance)
return cls.appliance.collections.cloud_providers.instantiate(
prov_class=cls,
name=prov_config['name'],
region=prov_config['region'],
region_name=prov_config['region_name'],
endpoints={endpoint.name: endpoint},
zone=prov_config['server_zone'],
key=prov_key)

@staticmethod
def discover_dict(credential):
Expand Down
32 changes: 16 additions & 16 deletions cfme/cloud/provider/gce.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import attr

from widgetastic.widget import View
from widgetastic_patternfly import Button, Input
from wrapanapi.google import GoogleCloudSystem
Expand Down Expand Up @@ -27,6 +29,7 @@ class GCEEndpointForm(View):
validate = Button('Validate')


@attr.s(hash=False)
class GCEProvider(CloudProvider):
"""
BaseProvider->CloudProvider->GCEProvider class.
Expand All @@ -39,13 +42,9 @@ class GCEProvider(CloudProvider):
endpoints_form = GCEEndpointForm
settings_key = 'ems_google'

def __init__(self, name=None, project=None, zone=None, region=None, region_name=None,
endpoints=None, key=None, appliance=None):
super(GCEProvider, self).__init__(name=name, zone=zone, key=key, endpoints=endpoints,
appliance=appliance)
self.region = region
self.region_name = region_name
self.project = project
project = attr.ib(default=None)
region = attr.ib(default=None)
region_name = attr.ib(default=None)

@property
def view_value_mapping(self):
Expand All @@ -62,16 +61,17 @@ def view_value_mapping(self):
return endpoints

@classmethod
def from_config(cls, prov_config, prov_key, appliance=None):
def from_config(cls, prov_config, prov_key):
endpoint = GCEEndpoint(**prov_config['endpoints']['default'])
return cls(name=prov_config['name'],
project=prov_config['project'],
zone=prov_config['zone'],
region=prov_config['region'],
region_name=prov_config['region_name'],
endpoints={endpoint.name: endpoint},
key=prov_key,
appliance=appliance)
return cls.appliance.collections.cloud_providers.instantiate(
prov_class=cls,
name=prov_config['name'],
project=prov_config['project'],
zone=prov_config['zone'],
region=prov_config['region'],
region_name=prov_config['region_name'],
endpoints={endpoint.name: endpoint},
key=prov_key)

@classmethod
def get_credentials(cls, credential_dict, cred_type=None):
Expand Down
Loading

0 comments on commit 1fe4600

Please sign in to comment.