| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- """
- Specification for a provider interface
- """
- from __future__ import annotations
- from abc import ABCMeta
- from abc import abstractmethod
- from abc import abstractproperty
- from typing import Any
- from typing import TYPE_CHECKING
- if TYPE_CHECKING:
- from pyeventsystem.middleware import MiddlewareManager
- from cloudbridge.interfaces.resources import Configuration
- from cloudbridge.interfaces.resources import Instance
- from cloudbridge.interfaces.resources import PlacementZone
- from cloudbridge.interfaces.services import ComputeService
- from cloudbridge.interfaces.services import DnsService
- from cloudbridge.interfaces.services import NetworkingService
- from cloudbridge.interfaces.services import SecurityService
- from cloudbridge.interfaces.services import StorageService
- class CloudProvider(object):
- """
- Base interface for a cloud provider
- """
- __metaclass__ = ABCMeta
- @abstractmethod
- def __init__(self, config: dict[str, Any]) -> None:
- """
- Create a new provider instance given a dictionary of
- configuration attributes.
- :type config: :class:`dict`
- :param config: A dictionary object containing provider initialization
- values. Alternatively, this can be an iterable of
- key/value pairs (as tuples or other iterables of length
- two). See specific provider implementation for the
- required fields.
- :rtype: :class:`.CloudProvider`
- :return: a concrete provider instance
- """
- pass
- @abstractproperty
- def config(self) -> Configuration:
- """
- Returns the config object associated with this provider. This object
- is a subclass of :class:`dict` and will contain the properties
- provided at initialization time, grouped under `cloud_properties` and
- `credentials` keys. In addition, it also contains extra provider-wide
- properties such as the default result limit for `list()` queries.
- Example:
- .. code-block:: python
- config = { 'aws_access_key' : '<my_key>' }
- provider = factory.create_provider(ProviderList.AWS, config)
- print(provider.config['credentials'].get('aws_access_key'))
- print(provider.config.default_result_limit))
- # change provider result limit
- provider.config.default_result_limit = 100
- :rtype: :class:`.Configuration`
- :return: An object of class Configuration, which contains the values
- used to initialize the provider, as well as other global
- configuration properties.
- """
- pass
- @abstractproperty
- def middleware(self) -> MiddlewareManager:
- """
- Returns the middleware manager associated with this provider. The
- middleware manager can be used to add or remove middleware from
- cloudbridge. Refer to pyeventsystem documentation for more information
- on how the middleware manager works.
- :rtype: :class:`.MiddlewareManager`
- :return: An object of class MiddlewareManager, which can be used to
- add or remove middleware from cloudbridge.
- """
- pass
- @abstractmethod
- def clone(self, zone: PlacementZone | None = None) -> CloudProvider:
- """
- Create a clone of this provider. An optional `zone` parameter can be
- used to clone the provider to use a different zone.
- As each cloudbridge provider is restricted to a particular zone,
- this is useful when performing cross-zonal operations.
- Example:
- .. code-block:: python
- # list instances in all availability zones
- all_instances = []
- for zone in provider.compute.regions.current.zones:
- new_provider = provider.clone(zone=zone)
- all_instances.append(list(new_provider.compute.instances))
- print(all_instances)
- :param zone: Changes the provider's zone to the requested
- AvailabilityZone
- :type zone: :class:`.PlacementZone` object
- :rtype: :class:`.CloudProvider`
- :return: A clone of the CloudProvider, with zone changed to the
- requested zone.
- """
- pass
- @abstractmethod
- def authenticate(self) -> bool:
- """
- Checks whether a provider can be successfully authenticated with the
- configured settings. Clients are *not* required to call this method
- prior to accessing provider services, as most cloud connections are
- initialized lazily. The authenticate() method will return True if
- cloudbridge can establish a successful connection to the provider.
- It will raise an exception with the appropriate error details
- otherwise.
- Example:
- .. code-block:: python
- try:
- if provider.authenticate():
- print("Provider connection successful")
- except ProviderConnectionException as e:
- print("Could not authenticate with provider: %s" % (e, ))
- :rtype: :class:`bool`
- :return: ``True`` if authentication is successful.
- """
- pass
- @abstractmethod
- def has_service(self, service_type: str) -> bool:
- """
- Checks whether this provider supports a given service.
- Example:
- .. code-block:: python
- if provider.has_service(CloudServiceType.BUCKET):
- print("Provider supports object store services")
- provider.storage.buckets.list()
- :type service_type: :class:`.CloudServiceType`
- :param service_type: Type of service to check support for.
- :rtype: :class:`bool`
- :return: ``True`` if the service type is supported.
- """
- pass
- @abstractproperty
- def region_name(self) -> str | None:
- """
- Returns the region that this provider is connected to.
- All provider operations will take place within this region.
- :rtype: ``str``
- :return: a zone id
- """
- pass
- @abstractproperty
- def zone_name(self) -> str | None:
- """
- Returns the placement zone that this provider is connected to.
- All provider operations will take place within this zone. Placement
- zone must be within the provider default region.
- :rtype: ``str``
- :return: a zone id
- """
- pass
- # @abstractproperty
- # def account(self):
- # """
- # Provides access to all user account related services in this
- # provider. This includes listing available tenancies.
- #
- # :rtype: ``object`` of :class:`.ComputeService`
- # :return: a ComputeService object
- # """
- # pass
- @abstractproperty
- def compute(self) -> ComputeService:
- """
- Provides access to all compute related services in this provider.
- Example:
- .. code-block:: python
- regions = provider.compute.regions.list()
- vm_types = provider.compute.vm_types.list()
- instances = provider.compute.instances.list()
- images = provider.compute.images.list()
- # Alternatively
- for instance in provider.compute.instances:
- print(instance.name)
- :rtype: :class:`.ComputeService`
- :return: a ComputeService object
- """
- pass
- @abstractproperty
- def networking(self) -> NetworkingService:
- """
- Provide access to all network related services in this provider.
- Example:
- .. code-block:: python
- networks = provider.networking.networks.list()
- subnets = provider.networking.subnets.list()
- routers = provider.networking.routers.list()
- :rtype: :class:`.NetworkingService`
- :return: a NetworkingService object
- """
- @abstractproperty
- def security(self) -> SecurityService:
- """
- Provides access to key pair management and firewall control
- Example:
- .. code-block:: python
- keypairs = provider.security.keypairs.list()
- vm_firewalls = provider.security.vm_firewalls.list()
- :rtype: ``object`` of :class:`.SecurityService`
- :return: a SecurityService object
- """
- pass
- @abstractproperty
- def storage(self) -> StorageService:
- """
- Provides access to storage related services in this provider.
- This includes the volume, snapshot and bucket services,
- Example:
- .. code-block:: python
- volumes = provider.storage.volumes.list()
- snapshots = provider.storage.snapshots.list()
- if provider.has_service(CloudServiceType.BUCKET):
- print("Provider supports object store services")
- print(provider.storage.buckets.list())
- :rtype: :class:`.StorageService`
- :return: a StorageService object
- """
- pass
- @abstractproperty
- def dns(self) -> DnsService:
- """
- Provides access to all DNS related services.
- Example:
- .. code-block:: python
- if provider.has_service(CloudServiceType.DNS):
- print("Provider supports DNS services")
- dns_zones = provider.dns.host_zones.list()
- print(dns_zones)
- :rtype: :class:`.DnsService`
- :return: a DNS service object
- """
- pass
- class TestMockHelperMixin(object):
- """
- A helper class that providers mock drivers can use to be notified when a
- test setup/teardown occurs. This is useful when activating libraries
- like HTTPretty which take over socket communications.
- """
- def setUpMock(self) -> None:
- """
- Called before a test is started.
- """
- raise NotImplementedError(
- 'TestMockHelperMixin.setUpMock not implemented')
- def tearDownMock(self) -> None:
- """
- Called before test teardown.
- """
- raise NotImplementedError(
- 'TestMockHelperMixin.tearDownMock not implemented by this'
- ' provider')
- class ContainerProvider(object):
- """
- Represents a container instance, such as Docker or LXC
- """
- __metaclass__ = ABCMeta
- @abstractmethod
- def create_container(self) -> None:
- pass
- @abstractmethod
- def delete_container(self) -> None:
- pass
- class DeploymentProvider(object):
- """
- Represents a deployment provider, such as Ansible or Shell script provider
- """
- __metaclass__ = ABCMeta
- @abstractmethod
- def deploy(self, target: Instance) -> None:
- """
- Deploys on given target, where target is an Instance or Container
- """
- pass
|