blob: 38c53d33c629fe832b6845635d4562bf8522c493 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import with_statement
from typing import Optional
from typing import List
from libcloud.common.base import ConnectionUserAndKey, BaseDriver
from libcloud.container.types import ContainerState
__all__ = [
"Container",
"ContainerImage",
"ContainerCluster",
"ClusterLocation",
"ContainerDriver",
]
class Container(object):
"""
Container.
"""
def __init__(
self,
id, # type: str
name, # type: str
image, # type: ContainerImage
state, # type: ContainerState
ip_addresses, # type: List[str]
driver, # type: ContainerDriver
extra=None, # type: dict
):
"""
:param id: Container id.
:type id: ``str``
:param name: The name of the container.
:type name: ``str``
:param image: The image this container was deployed using.
:type image: :class:`.ContainerImage`
:param state: The state of the container, e.g. running
:type state: :class:`libcloud.container.types.ContainerState`
:param ip_addresses: A list of IP addresses for this container
:type ip_addresses: ``list`` of ``str``
:param driver: ContainerDriver instance.
:type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
"""
self.id = str(id) if id else None
self.name = name
self.image = image
self.state = state
self.ip_addresses = ip_addresses
self.driver = driver
self.extra = extra or {}
def start(self):
# type: () -> Container
return self.driver.start_container(container=self)
def stop(self):
# type: () -> Container
return self.driver.stop_container(container=self)
def restart(self):
# type: () -> Container
return self.driver.restart_container(container=self)
def destroy(self):
# type: () -> bool
return self.driver.destroy_container(container=self)
def __repr__(self):
return "<Container: id=%s, name=%s," "state=%s, provider=%s ...>" % (
self.id,
self.name,
self.state,
self.driver.name,
)
class ContainerImage(object):
"""
Container Image.
"""
def __init__(
self,
id, # type: str
name, # type: str
path, # type: str
version, # type: str
driver, # type: ContainerDriver
extra=None, # type: dict
):
"""
:param id: Container Image id.
:type id: ``str``
:param name: The name of the image.
:type name: ``str``
:param path: The path to the image
:type path: ``str``
:param version: The version of the image
:type version: ``str``
:param driver: ContainerDriver instance.
:type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
"""
self.id = str(id) if id else None
self.name = name
self.path = path
self.version = version
self.driver = driver
self.extra = extra or {}
def deploy(self, name, parameters, cluster=None, start=True):
# type: (str, str, Optional[ContainerCluster], bool) -> Container
return self.driver.deploy_container(
name=name, image=self, parameters=parameters, cluster=cluster, start=start
)
def __repr__(self):
return "<ContainerImage: id=%s, name=%s, path=%s ...>" % (
self.id,
self.name,
self.path,
)
class ContainerCluster(object):
"""
A cluster group for containers
"""
def __init__(
self,
id, # type: str
name, # type: str
driver, # type: ContainerDriver
extra=None, # type: dict
):
"""
:param id: Container Image id.
:type id: ``str``
:param name: The name of the image.
:type name: ``str``
:param driver: ContainerDriver instance.
:type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
"""
self.id = str(id) if id else None
self.name = name
self.driver = driver
self.extra = extra or {}
def list_containers(self):
# type: () -> List[Container]
return self.driver.list_containers(cluster=self)
def destroy(self):
# type: () -> bool
return self.driver.destroy_cluster(cluster=self)
def __repr__(self):
return "<ContainerCluster: id=%s, name=%s, provider=%s ...>" % (
self.id,
self.name,
self.driver.name,
)
class ClusterLocation(object):
"""
A physical location where clusters can be.
>>> from libcloud.container.drivers.dummy import DummyContainerDriver
>>> driver = DummyContainerDriver(0)
>>> location = driver.list_locations()[0]
>>> location.country
'US'
"""
def __init__(
self,
id, # type: str
name, # type: str
country, # type: str
driver, # type: ContainerDriver
):
"""
:param id: Location ID.
:type id: ``str``
:param name: Location name.
:type name: ``str``
:param country: Location country.
:type country: ``str``
:param driver: Driver this location belongs to.
:type driver: :class:`.ContainerDriver`
"""
self.id = str(id)
self.name = name
self.country = country
self.driver = driver
def __repr__(self):
return ("<ClusterLocation: id=%s, name=%s, country=%s, driver=%s>") % (
self.id,
self.name,
self.country,
self.driver.name,
)
class ContainerDriver(BaseDriver):
"""
A base ContainerDriver class to derive from
This class is always subclassed by a specific driver.
"""
connectionCls = ConnectionUserAndKey
name = None
website = None
supports_clusters = False
"""
Whether the driver supports containers being deployed into clusters
"""
def __init__(self, key, secret=None, secure=True, host=None, port=None, **kwargs):
"""
:param key: API key or username to used (required)
:type key: ``str``
:param secret: Secret password to be used (required)
:type secret: ``str``
:param secure: Whether to use HTTPS or HTTP. Note: Some providers
only support HTTPS, and it is on by default.
:type secure: ``bool``
:param host: Override hostname used for connections.
:type host: ``str``
:param port: Override port used for connections.
:type port: ``int``
:return: ``None``
"""
super(ContainerDriver, self).__init__(
key=key, secret=secret, secure=secure, host=host, port=port, **kwargs
)
def install_image(self, path):
# type: (str) -> ContainerImage
"""
Install a container image from a remote path.
:param path: Path to the container image
:type path: ``str``
:rtype: :class:`.ContainerImage`
"""
raise NotImplementedError("install_image not implemented for this driver")
def list_images(self):
# type: () -> List[ContainerImage]
"""
List the installed container images
:rtype: ``list`` of :class:`.ContainerImage`
"""
raise NotImplementedError("list_images not implemented for this driver")
def list_containers(
self,
image=None, # type: Optional[ContainerImage]
cluster=None, # type: Optional[ContainerCluster]
):
# type: (...) -> List[Container]
"""
List the deployed container images
:param image: Filter to containers with a certain image
:type image: :class:`.ContainerImage`
:param cluster: Filter to containers in a cluster
:type cluster: :class:`.ContainerCluster`
:rtype: ``list`` of :class:`.Container`
"""
raise NotImplementedError("list_containers not implemented for this driver")
def deploy_container(
self,
name, # type: str
image, # type: ContainerImage
cluster=None, # type: Optional[ContainerCluster]
parameters=None, # type: Optional[str]
start=True, # type: bool
):
# type: (...) -> Container
"""
Deploy an installed container image
:param name: The name of the new container
:type name: ``str``
:param image: The container image to deploy
:type image: :class:`.ContainerImage`
:param cluster: The cluster to deploy to, None is default
:type cluster: :class:`.ContainerCluster`
:param parameters: Container Image parameters
:type parameters: ``str``
:param start: Start the container on deployment
:type start: ``bool``
:rtype: :class:`.Container`
"""
raise NotImplementedError("deploy_container not implemented for this driver")
def get_container(self, id):
# type: (str) -> Container
"""
Get a container by ID
:param id: The ID of the container to get
:type id: ``str``
:rtype: :class:`.Container`
"""
raise NotImplementedError("get_container not implemented for this driver")
def start_container(self, container):
# type: (Container) -> Container
"""
Start a deployed container
:param container: The container to start
:type container: :class:`.Container`
:rtype: :class:`.Container`
"""
raise NotImplementedError("start_container not implemented for this driver")
def stop_container(self, container):
# type: (Container) -> Container
"""
Stop a deployed container
:param container: The container to stop
:type container: :class:`.Container`
:rtype: :class:`.Container`
"""
raise NotImplementedError("stop_container not implemented for this driver")
def restart_container(self, container):
# type: (Container) -> Container
"""
Restart a deployed container
:param container: The container to restart
:type container: :class:`.Container`
:rtype: :class:`.Container`
"""
raise NotImplementedError("restart_container not implemented for this driver")
def destroy_container(self, container):
# type: (Container) -> bool
"""
Destroy a deployed container
:param container: The container to destroy
:type container: :class:`.Container`
:rtype: ``bool``
"""
raise NotImplementedError("destroy_container not implemented for this driver")
def list_locations(self):
# type: () -> List[ClusterLocation]
"""
Get a list of potential locations to deploy clusters into
:rtype: ``list`` of :class:`.ClusterLocation`
"""
raise NotImplementedError("list_locations not implemented for this driver")
def create_cluster(self, name, location=None):
# type: (str, Optional[ClusterLocation]) -> ContainerCluster
"""
Create a container cluster
:param name: The name of the cluster
:type name: ``str``
:param location: The location to create the cluster in
:type location: :class:`.ClusterLocation`
:rtype: :class:`.ContainerCluster`
"""
raise NotImplementedError("create_cluster not implemented for this driver")
def destroy_cluster(self, cluster):
# type: (ContainerCluster) -> bool
"""
Delete a cluster
:return: ``True`` if the destroy was successful, otherwise ``False``.
:rtype: ``bool``
"""
raise NotImplementedError("destroy_cluster not implemented for this driver")
def list_clusters(self, location=None):
# type: (Optional[ClusterLocation]) -> List[ContainerCluster]
"""
Get a list of potential locations to deploy clusters into
:param location: The location to search in
:type location: :class:`.ClusterLocation`
:rtype: ``list`` of :class:`.ContainerCluster`
"""
raise NotImplementedError("list_clusters not implemented for this driver")
def get_cluster(self, id):
# type: (str) -> ContainerCluster
"""
Get a cluster by ID
:param id: The ID of the cluster to get
:type id: ``str``
:rtype: :class:`.ContainerCluster`
"""
raise NotImplementedError("list_clusters not implemented for this driver")