# 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.

"""
Provides base classes for working with drivers
"""

from __future__ import with_statement

from typing import Dict
from typing import List
from typing import Tuple
from typing import Type
from typing import Optional
from typing import Any
from typing import Union
from typing import Callable
from typing import TYPE_CHECKING

import time
import hashlib
import os
import re
import socket
import random
import binascii
import datetime
import traceback
import atexit

from libcloud.utils.py3 import b

import libcloud.compute.ssh
from libcloud.pricing import get_size_price
from libcloud.compute.types import NodeState, StorageVolumeState, DeploymentError

if TYPE_CHECKING:
    from libcloud.compute.deployment import Deployment
from libcloud.compute.types import Provider
from libcloud.compute.types import NodeImageMemberState
from libcloud.compute.ssh import SSHClient
from libcloud.compute.ssh import BaseSSHClient
from libcloud.common.base import Connection
from libcloud.common.base import ConnectionKey
from libcloud.common.base import BaseDriver
from libcloud.common.types import LibcloudError
from libcloud.compute.ssh import have_paramiko
from libcloud.compute.ssh import SSHCommandTimeoutError

from libcloud.utils.networking import is_private_subnet
from libcloud.utils.networking import is_valid_ip_address

if have_paramiko:
    from paramiko.ssh_exception import SSHException
    from paramiko.ssh_exception import AuthenticationException

    SSH_TIMEOUT_EXCEPTION_CLASSES = (
        AuthenticationException,
        SSHException,
        IOError,
        socket.gaierror,
        socket.error,
    )
else:
    SSH_TIMEOUT_EXCEPTION_CLASSES = (
        IOError,  # type: ignore
        socket.gaierror,  # type: ignore
        socket.error,
    )  # type: ignore

T_Auth = Union["NodeAuthSSHKey", "NodeAuthPassword"]

T_Ssh_key = Union[List[str], str]

# How long to wait for the node to come online after creating it
NODE_ONLINE_WAIT_TIMEOUT = 10 * 60

# How long to try connecting to a remote SSH server when running a deployment
# script.
SSH_CONNECT_TIMEOUT = 5 * 60

# Error message which should be considered fatal for deploy_node() method and
# on which we should abort retrying and immediately propagate the error
SSH_FATAL_ERROR_MSGS = [
    # Propagate (key) file doesn't exist errors
    # NOTE: Paramiko only supports PEM private key format
    # See https://github.com/paramiko/paramiko/issues/1313
    # for details
    "no such file or directory",
    "invalid key",
    "not a valid ",
    "invalid or unsupported key type",
    "private file is encrypted",
    "private key file is encrypted",
    "private key file checkints do not match",
    "invalid password provided",
]

__all__ = [
    "Node",
    "NodeState",
    "NodeSize",
    "NodeImage",
    "NodeImageMember",
    "NodeLocation",
    "NodeAuthSSHKey",
    "NodeAuthPassword",
    "NodeDriver",
    "StorageVolume",
    "StorageVolumeState",
    "VolumeSnapshot",
    # Deprecated, moved to libcloud.utils.networking
    "is_private_subnet",
    "is_valid_ip_address",
]


class UuidMixin(object):
    """
    Mixin class for get_uuid function.
    """

    def __init__(self):
        self._uuid = None  # type: str

    def get_uuid(self):
        """
        Unique hash for a node, node image, or node size

        The hash is a function of an SHA1 hash of the node, node image,
        or node size's ID and its driver which means that it should be
        unique between all objects of its type.
        In some subclasses (e.g. GoGridNode) there is no ID
        available so the public IP address is used.  This means that,
        unlike a properly done system UUID, the same UUID may mean a
        different system install at a different time

        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
        >>> driver = DummyNodeDriver(0)
        >>> node = driver.create_node()
        >>> node.get_uuid()
        'd3748461511d8b9b0e0bfa0d4d3383a619a2bb9f'

        Note, for example, that this example will always produce the
        same UUID!

        :rtype: ``str``
        """
        if not self._uuid:
            self._uuid = hashlib.sha1(
                b("%s:%s" % (self.id, self.driver.type))
            ).hexdigest()

        return self._uuid

    @property
    def uuid(self):
        # type: () -> str
        return self.get_uuid()


class Node(UuidMixin):
    """
    Provide a common interface for handling nodes of all types.

    The Node object provides the interface in libcloud through which
    we can manipulate nodes in different cloud providers in the same
    way.  Node objects don't actually do much directly themselves,
    instead the node driver handles the connection to the node.

    You don't normally create a node object yourself; instead you use
    a driver and then have that create the node for you.

    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
    >>> driver = DummyNodeDriver(0)
    >>> node = driver.create_node()
    >>> node.public_ips[0]
    '127.0.0.3'
    >>> node.name
    'dummy-3'

    You can also get nodes from the driver's list_node function.

    >>> node = driver.list_nodes()[0]
    >>> node.name
    'dummy-1'

    The node keeps a reference to its own driver which means that we
    can work on nodes from different providers without having to know
    which is which.

    >>> driver = DummyNodeDriver(72)
    >>> node2 = driver.create_node()
    >>> node.driver.creds
    0
    >>> node2.driver.creds
    72

    Although Node objects can be subclassed, this isn't normally
    done.  Instead, any driver specific information is stored in the
    "extra" attribute of the node.

    >>> node.extra
    {'foo': 'bar'}
    """

    def __init__(
        self,
        id,  # type: str
        name,  # type: str
        state,  # type: NodeState
        public_ips,  # type: List[str]
        private_ips,  # type: List[str]
        driver,
        size=None,  # type: NodeSize
        image=None,  # type: NodeImage
        extra=None,  # type: dict
        created_at=None,  # type: datetime.datetime
    ):
        """
        :param id: Node ID.
        :type id: ``str``

        :param name: Node name.
        :type name: ``str``

        :param state: Node state.
        :type state: :class:`libcloud.compute.types.NodeState`


        :param public_ips: Public IP addresses associated with this node.
        :type public_ips: ``list``

        :param private_ips: Private IP addresses associated with this node.
        :type private_ips: ``list``

        :param driver: Driver this node belongs to.
        :type driver: :class:`.NodeDriver`

        :param size: Size of this node. (optional)
        :type size: :class:`.NodeSize`

        :param image: Image of this node. (optional)
        :type image: :class:`.NodeImage`

        :param created_at: The datetime this node was created (optional)
        :type created_at: :class: `datetime.datetime`

        :param extra: Optional provider specific attributes associated with
                      this node.
        :type extra: ``dict``

        """
        self.id = str(id) if id else None
        self.name = name
        self.state = state
        self.public_ips = public_ips if public_ips else []
        self.private_ips = private_ips if private_ips else []
        self.driver = driver
        self.size = size
        self.created_at = created_at
        self.image = image
        self.extra = extra or {}
        UuidMixin.__init__(self)

    def reboot(self):
        # type: () -> bool
        """
        Reboot this node

        :return: ``bool``

        This calls the node's driver and reboots the node

        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
        >>> driver = DummyNodeDriver(0)
        >>> node = driver.create_node()
        >>> node.state == NodeState.RUNNING
        True
        >>> node.state == NodeState.REBOOTING
        False
        >>> node.reboot()
        True
        >>> node.state == NodeState.REBOOTING
        True
        """
        return self.driver.reboot_node(self)

    def start(self):
        # type: () -> bool
        """
        Start this node.

        :return: ``bool``
        """
        return self.driver.start_node(self)

    def stop_node(self):
        # type: () -> bool
        """
        Stop (shutdown) this node.

        :return: ``bool``
        """
        return self.driver.stop_node(self)

    def destroy(self):
        # type: () -> bool
        """
        Destroy this node

        :return: ``bool``

        This calls the node's driver and destroys the node

        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
        >>> driver = DummyNodeDriver(0)
        >>> from libcloud.compute.types import NodeState
        >>> node = driver.create_node()
        >>> node.state == NodeState.RUNNING
        True
        >>> node.destroy()
        True
        >>> node.state == NodeState.RUNNING
        False

        """
        return self.driver.destroy_node(self)

    def __repr__(self):
        state = NodeState.tostring(self.state)

        return (
            "<Node: uuid=%s, name=%s, state=%s, public_ips=%s, "
            "private_ips=%s, provider=%s ...>"
        ) % (
            self.uuid,
            self.name,
            state,
            self.public_ips,
            self.private_ips,
            self.driver.name,
        )


class NodeSize(UuidMixin):
    """
    A Base NodeSize class to derive from.

    NodeSizes are objects which are typically returned a driver's
    list_sizes function.  They contain a number of different
    parameters which define how big an image is.

    The exact parameters available depends on the provider.

    N.B. Where a parameter is "unlimited" (for example bandwidth in
    Amazon) this will be given as 0.

    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
    >>> driver = DummyNodeDriver(0)
    >>> size = driver.list_sizes()[0]
    >>> size.ram
    128
    >>> size.bandwidth
    500
    >>> size.price
    4
    """

    def __init__(
        self,
        id,  # type: str
        name,  # type: str
        ram,  # type: int
        disk,  # type: int
        bandwidth,  # type: Optional[int]
        price,  # type: float
        driver,  # type: NodeDriver
        extra=None,  # type: Optional[dict]
    ):
        """
        :param id: Size ID.
        :type  id: ``str``

        :param name: Size name.
        :type  name: ``str``

        :param ram: Amount of memory (in MB) provided by this size.
        :type  ram: ``int``

        :param disk: Amount of disk storage (in GB) provided by this image.
        :type  disk: ``int``

        :param bandwidth: Amount of bandiwdth included with this size.
        :type  bandwidth: ``int``

        :param price: Price (in US dollars) of running this node for an hour.
        :type  price: ``float``

        :param driver: Driver this size belongs to.
        :type  driver: :class:`.NodeDriver`

        :param extra: Optional provider specific attributes associated with
                      this size.
        :type  extra: ``dict``
        """
        self.id = str(id)
        self.name = name
        self.ram = ram
        self.disk = disk
        self.bandwidth = bandwidth
        self.price = price
        self.driver = driver
        self.extra = extra or {}
        UuidMixin.__init__(self)

    def __repr__(self):
        return (
            "<NodeSize: id=%s, name=%s, ram=%s disk=%s bandwidth=%s "
            "price=%s driver=%s ...>"
        ) % (
            self.id,
            self.name,
            self.ram,
            self.disk,
            self.bandwidth,
            self.price,
            self.driver.name,
        )


class NodeImage(UuidMixin):
    """
    An operating system image.

    NodeImage objects are typically returned by the driver for the
    cloud provider in response to the list_images function

    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
    >>> driver = DummyNodeDriver(0)
    >>> image = driver.list_images()[0]
    >>> image.name
    'Ubuntu 9.10'

    Apart from name and id, there is no further standard information;
    other parameters are stored in a driver specific "extra" variable

    When creating a node, a node image should be given as an argument
    to the create_node function to decide which OS image to use.

    >>> node = driver.create_node(image=image)
    """

    def __init__(
        self,
        id,  # type: str
        name,  # type: str
        driver,  # type: NodeDriver
        extra=None,  # type: Optional[dict]
    ):
        """
        :param id: Image ID.
        :type id: ``str``

        :param name: Image name.
        :type name: ``str``

        :param driver: Driver this image belongs to.
        :type driver: :class:`.NodeDriver`

        :param extra: Optional provided specific attributes associated with
                      this image.
        :type extra: ``dict``
        """
        self.id = str(id)
        self.name = name
        self.driver = driver
        self.extra = extra or {}
        UuidMixin.__init__(self)

    def __repr__(self):
        return ("<NodeImage: id=%s, name=%s, driver=%s  ...>") % (
            self.id,
            self.name,
            self.driver.name,
        )


class NodeImageMember(UuidMixin):
    """
    A member of an image. At some cloud providers there is a mechanism
    to share images. Once an image is shared with another account that
    user will be a 'member' of the image.

    For example, see the image members schema in the OpenStack Image
    Service API v2 documentation. https://developer.openstack.org/
    api-ref/image/v2/index.html#image-members-schema

    NodeImageMember objects are typically returned by the driver for the
    cloud provider in response to the list_image_members method
    """

    def __init__(
        self,
        id,  # type: str
        image_id,  # type: str
        state,  # type: NodeImageMemberState
        driver,  # type: NodeDriver
        created=None,  # type: datetime.datetime
        extra=None,  # type: Optional[dict]
    ):
        """
        :param id: Image member ID.
        :type id: ``str``

        :param id: The associated image ID.
        :type id: ``str``

        :param state: State of the NodeImageMember. If not
                      provided, will default to UNKNOWN.
        :type state: :class:`.NodeImageMemberState`

        :param driver: Driver this image belongs to.
        :type driver: :class:`.NodeDriver`

        :param      created: A datetime object that represents when the
                             image member was created
        :type       created: ``datetime.datetime``

        :param extra: Optional provided specific attributes associated with
                      this image.
        :type extra: ``dict``
        """
        self.id = str(id)
        self.image_id = str(image_id)
        self.state = state
        self.driver = driver
        self.created = created
        self.extra = extra or {}
        UuidMixin.__init__(self)

    def __repr__(self):
        return (
            "<NodeImageMember: id=%s, image_id=%s, " "state=%s, driver=%s  ...>"
        ) % (self.id, self.image_id, self.state, self.driver.name)


class NodeLocation(object):
    """
    A physical location where nodes can be.

    >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
    >>> driver = DummyNodeDriver(0)
    >>> location = driver.list_locations()[0]
    >>> location.country
    'US'
    """

    def __init__(
        self,
        id,  # type: str
        name,  # type: str
        country,  # type: str
        driver,  # type: NodeDriver
        extra=None,  # type: Optional[dict]
    ):
        """
        :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:`.NodeDriver`

        :param extra: Optional provided specific attributes associated with
                      this location.
        :type extra: ``dict``
        """
        self.id = str(id)
        self.name = name
        self.country = country
        self.driver = driver
        self.extra = extra or {}

    def __repr__(self):
        return ("<NodeLocation: id=%s, name=%s, country=%s, driver=%s>") % (
            self.id,
            self.name,
            self.country,
            self.driver.name,
        )


class NodeAuthSSHKey(object):
    """
    An SSH key to be installed for authentication to a node.

    This is the actual contents of the users ssh public key which will
    normally be installed as root's public key on the node.

    >>> pubkey = '...' # read from file
    >>> from libcloud.compute.base import NodeAuthSSHKey
    >>> k = NodeAuthSSHKey(pubkey)
    >>> k
    <NodeAuthSSHKey>
    """

    def __init__(self, pubkey):
        # type: (str) -> None
        """
        :param pubkey: Public key material.
        :type pubkey: ``str``
        """
        self.pubkey = pubkey

    def __repr__(self):
        return "<NodeAuthSSHKey>"


class NodeAuthPassword(object):
    """
    A password to be used for authentication to a node.
    """

    def __init__(self, password, generated=False):
        # type: (str, bool) -> None
        """
        :param password: Password.
        :type password: ``str``

        :type generated: ``True`` if this password was automatically generated,
                         ``False`` otherwise.
        """
        self.password = password
        self.generated = generated

    def __repr__(self):
        return "<NodeAuthPassword>"


class StorageVolume(UuidMixin):
    """
    A base StorageVolume class to derive from.
    """

    def __init__(
        self,
        id,  # type: str
        name,  # type: str
        size,  # type: int
        driver,  # type: NodeDriver
        state=None,  # type: Optional[StorageVolumeState]
        extra=None,  # type: Optional[Dict]
    ):
        # type: (...) -> None
        """
        :param id: Storage volume ID.
        :type id: ``str``

        :param name: Storage volume name.
        :type name: ``str``

        :param size: Size of this volume (in GB).
        :type size: ``int``

        :param driver: Driver this image belongs to.
        :type driver: :class:`.NodeDriver`

        :param state: Optional state of the StorageVolume. If not
                      provided, will default to UNKNOWN.
        :type state: :class:`.StorageVolumeState`

        :param extra: Optional provider specific attributes.
        :type extra: ``dict``
        """
        self.id = id
        self.name = name
        self.size = size
        self.driver = driver
        self.extra = extra
        self.state = state
        UuidMixin.__init__(self)

    def list_snapshots(self):
        # type: () -> List[VolumeSnapshot]
        """
        :rtype: ``list`` of ``VolumeSnapshot``
        """
        return self.driver.list_volume_snapshots(volume=self)

    def attach(self, node, device=None):
        # type: (Node, Optional[str]) -> bool
        """
        Attach this volume to a node.

        :param node: Node to attach volume to
        :type node: :class:`.Node`

        :param device: Where the device is exposed,
                            e.g. '/dev/sdb (optional)
        :type device: ``str``

        :return: ``True`` if attach was successful, ``False`` otherwise.
        :rtype: ``bool``
        """
        return self.driver.attach_volume(node=node, volume=self, device=device)

    def detach(self):
        # type: () -> bool
        """
        Detach this volume from its node

        :return: ``True`` if detach was successful, ``False`` otherwise.
        :rtype: ``bool``
        """
        return self.driver.detach_volume(volume=self)

    def snapshot(self, name):
        # type: (str) -> VolumeSnapshot
        """
        Creates a snapshot of this volume.

        :return: Created snapshot.
        :rtype: ``VolumeSnapshot``
        """
        return self.driver.create_volume_snapshot(volume=self, name=name)

    def destroy(self):
        # type: () -> bool
        """
        Destroy this storage volume.

        :return: ``True`` if destroy was successful, ``False`` otherwise.
        :rtype: ``bool``
        """

        return self.driver.destroy_volume(volume=self)

    def __repr__(self):
        return "<StorageVolume id=%s size=%s driver=%s>" % (
            self.id,
            self.size,
            self.driver.name,
        )


class VolumeSnapshot(object):
    """
    A base VolumeSnapshot class to derive from.
    """

    def __init__(
        self,
        id,  # type: str
        driver,  # type: NodeDriver
        size=None,  # type: int
        extra=None,  # type: Optional[Dict]
        created=None,  # type: Optional[datetime.datetime]
        state=None,  # type: StorageVolumeState
        name=None,  # type: Optional[str]
    ):
        # type: (...) -> None
        """
        VolumeSnapshot constructor.

        :param      id: Snapshot ID.
        :type       id: ``str``

        :param      driver: The driver that represents a connection to the
                            provider
        :type       driver: `NodeDriver`

        :param      size: A snapshot size in GB.
        :type       size: ``int``

        :param      extra: Provider depends parameters for snapshot.
        :type       extra: ``dict``

        :param      created: A datetime object that represents when the
                             snapshot was created
        :type       created: ``datetime.datetime``

        :param      state: A string representing the state the snapshot is
                           in. See `libcloud.compute.types.StorageVolumeState`.
        :type       state: ``StorageVolumeState``

        :param      name: A string representing the name of the snapshot
        :type       name: ``str``
        """
        self.id = id
        self.driver = driver
        self.size = size
        self.extra = extra or {}
        self.created = created
        self.state = state
        self.name = name

    def destroy(self):
        # type: () -> bool
        """
        Destroys this snapshot.

        :rtype: ``bool``
        """
        return self.driver.destroy_volume_snapshot(snapshot=self)

    def __repr__(self):
        return '<VolumeSnapshot "%s" id=%s size=%s driver=%s state=%s>' % (
            self.name,
            self.id,
            self.size,
            self.driver.name,
            self.state,
        )


class KeyPair(object):
    """
    Represents a SSH key pair.
    """

    def __init__(
        self,
        name,  # type: str
        public_key,  # type: str
        fingerprint,  # type: str
        driver,  # type: NodeDriver
        private_key=None,  # type: Optional[str]
        extra=None,  # type: Optional[Dict]
    ):
        # type: (...) -> None
        """
        Constructor.

        :keyword    name: Name of the key pair object.
        :type       name: ``str``

        :keyword    fingerprint: Key fingerprint.
        :type       fingerprint: ``str``

        :keyword    public_key: Public key in OpenSSH format.
        :type       public_key: ``str``

        :keyword    private_key: Private key in PEM format.
        :type       private_key: ``str``

        :keyword    extra: Provider specific attributes associated with this
                           key pair. (optional)
        :type       extra: ``dict``
        """
        self.name = name
        self.fingerprint = fingerprint
        self.public_key = public_key
        self.private_key = private_key
        self.driver = driver
        self.extra = extra or {}

    def __repr__(self):
        return "<KeyPair name=%s fingerprint=%s driver=%s>" % (
            self.name,
            self.fingerprint,
            self.driver.name,
        )


class NodeDriver(BaseDriver):
    """
    A base NodeDriver class to derive from

    This class is always subclassed by a specific driver.  For
    examples of base behavior of most functions (except deploy node)
    see the dummy driver.
    """

    connectionCls = ConnectionKey  # type: Type[Connection]
    name = None  # type: str
    api_name = None  # type: str
    website = None  # type: str
    type = None  # type: Union[Provider,str]
    port = None  # type: int
    features = {"create_node": []}  # type: Dict[str, List[str]]

    """
    List of available features for a driver.
        - :meth:`libcloud.compute.base.NodeDriver.create_node`
            - ssh_key: Supports :class:`.NodeAuthSSHKey` as an authentication
              method for nodes.
            - password: Supports :class:`.NodeAuthPassword` as an
              authentication
              method for nodes.
            - generates_password: Returns a password attribute on the Node
              object returned from creation.
    """

    NODE_STATE_MAP = {}  # type: Dict[str, NodeState]

    def list_nodes(self, *args, **kwargs):
        # type: (Any, Any) -> List[Node]
        """
        List all nodes.

        :return:  list of node objects
        :rtype: ``list`` of :class:`.Node`
        """
        raise NotImplementedError("list_nodes not implemented for this driver")

    def list_sizes(self, location=None):
        # type: (Optional[NodeLocation]) -> List[NodeSize]
        """
        List sizes on a provider

        :param location: The location at which to list sizes
        :type location: :class:`.NodeLocation`

        :return: list of node size objects
        :rtype: ``list`` of :class:`.NodeSize`
        """
        raise NotImplementedError("list_sizes not implemented for this driver")

    def list_locations(self):
        # type: () -> List[NodeLocation]
        """
        List data centers for a provider

        :return: list of node location objects
        :rtype: ``list`` of :class:`.NodeLocation`
        """
        raise NotImplementedError("list_locations not implemented for this driver")

    def create_node(
        self,
        name,  # type: str
        size,  # type: NodeSize
        image,  # type: NodeImage
        location=None,  # type: Optional[NodeLocation]
        auth=None,  # type: T_Auth
    ):
        # type: (...) -> Node
        """
        Create a new node instance. This instance will be started
        automatically.

        Not all hosting API's are created equal and to allow libcloud to
        support as many as possible there are some standard supported
        variations of ``create_node``. These are declared using a
        ``features`` API.
        You can inspect ``driver.features['create_node']`` to see what
        variation of the API you are dealing with:

        ``ssh_key``
            You can inject a public key into a new node allows key based SSH
            authentication.
        ``password``
            You can inject a password into a new node for SSH authentication.
            If no password is provided libcloud will generated a password.
            The password will be available as
            ``return_value.extra['password']``.
        ``generates_password``
            The hosting provider will generate a password. It will be returned
            to you via ``return_value.extra['password']``.

        Some drivers allow you to set how you will authenticate with the
        instance that is created. You can inject this initial authentication
        information via the ``auth`` parameter.

        If a driver supports the ``ssh_key`` feature flag for ``created_node``
        you can upload a public key into the new instance::

            >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
            >>> driver = DummyNodeDriver(0)
            >>> auth = NodeAuthSSHKey('pubkey data here')
            >>> node = driver.create_node("test_node", auth=auth)

        If a driver supports the ``password`` feature flag for ``create_node``
        you can set a password::

            >>> driver = DummyNodeDriver(0)
            >>> auth = NodeAuthPassword('mysecretpassword')
            >>> node = driver.create_node("test_node", auth=auth)

        If a driver supports the ``password`` feature and you don't provide the
        ``auth`` argument libcloud will assign a password::

            >>> driver = DummyNodeDriver(0)
            >>> node = driver.create_node("test_node")
            >>> password = node.extra['password']

        A password will also be returned in this way for drivers that declare
        the ``generates_password`` feature, though in that case the password is
        actually provided to the driver API by the hosting provider rather than
        generated by libcloud.

        You can only pass a :class:`.NodeAuthPassword` or
        :class:`.NodeAuthSSHKey` to ``create_node`` via the auth parameter if
        has the corresponding feature flag.

        :param name:   String with a name for this new node (required)
        :type name:   ``str``

        :param size:   The size of resources allocated to this node.
                            (required)
        :type size:   :class:`.NodeSize`

        :param image:  OS Image to boot on node. (required)
        :type image:  :class:`.NodeImage`

        :param location: Which data center to create a node in. If empty,
                              undefined behavior will be selected. (optional)
        :type location: :class:`.NodeLocation`

        :param auth:   Initial authentication information for the node
                            (optional)
        :type auth:   :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword`

        :return: The newly created node.
        :rtype: :class:`.Node`
        """
        raise NotImplementedError("create_node not implemented for this driver")

    def deploy_node(
        self,
        deploy,  # type: Deployment
        ssh_username="root",  # type: str
        ssh_alternate_usernames=None,  # type: Optional[List[str]]
        ssh_port=22,  # type: int
        ssh_timeout=10,  # type: int
        ssh_key=None,  # type: Optional[T_Ssh_key]
        ssh_key_password=None,  # type: Optional[str]
        auth=None,  # type: T_Auth
        timeout=SSH_CONNECT_TIMEOUT,  # type: int
        max_tries=3,  # type: int
        ssh_interface="public_ips",  # type: str
        at_exit_func=None,  # type: Callable
        wait_period=5,  # type: int
        **create_node_kwargs,
    ):
        # type: (...) -> Node
        """
        Create a new node, and start deployment.

        In order to be able to SSH into a created node access credentials are
        required.

        A user can pass either a :class:`.NodeAuthPassword` or
        :class:`.NodeAuthSSHKey` to the ``auth`` argument. If the
        ``create_node`` implementation supports that kind if credential (as
        declared in ``self.features['create_node']``) then it is passed on to
        ``create_node``. Otherwise it is not passed on to ``create_node`` and
        it is only used for authentication.

        If the ``auth`` parameter is not supplied but the driver declares it
        supports ``generates_password`` then the password returned by
        ``create_node`` will be used to SSH into the server.

        Finally, if the ``ssh_key_file`` is supplied that key will be used to
        SSH into the server.

        This function may raise a :class:`DeploymentException`, if a
        create_node call was successful, but there is a later error (like SSH
        failing or timing out).  This exception includes a Node object which
        you may want to destroy if incomplete deployments are not desirable.

        >>> from libcloud.compute.drivers.dummy import DummyNodeDriver
        >>> from libcloud.compute.deployment import ScriptDeployment
        >>> from libcloud.compute.deployment import MultiStepDeployment
        >>> from libcloud.compute.base import NodeAuthSSHKey
        >>> driver = DummyNodeDriver(0)
        >>> key = NodeAuthSSHKey('...') # read from file
        >>> script = ScriptDeployment("yum -y install emacs strace tcpdump")
        >>> msd = MultiStepDeployment([key, script])
        >>> def d():
        ...     try:
        ...         driver.deploy_node(deploy=msd)
        ...     except NotImplementedError:
        ...         print ("not implemented for dummy driver")
        >>> d()
        not implemented for dummy driver

        Deploy node is typically not overridden in subclasses.  The
        existing implementation should be able to handle most such.

        :param deploy: Deployment to run once machine is online and
                            available to SSH.
        :type deploy: :class:`Deployment`

        :param ssh_username: Optional name of the account which is used
                                  when connecting to
                                  SSH server (default is root)
        :type ssh_username: ``str``

        :param ssh_alternate_usernames: Optional list of ssh usernames to
                                             try to connect with if using the
                                             default one fails
        :type ssh_alternate_usernames: ``list``

        :param ssh_port: Optional SSH server port (default is 22)
        :type ssh_port: ``int``

        :param ssh_timeout: Optional SSH connection timeout in seconds
                                 (default is 10)
        :type ssh_timeout: ``float``

        :param auth:   Initial authentication information for the node
                            (optional)
        :type auth:   :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword`

        :param ssh_key: A path (or paths) to an SSH private key with which
                             to attempt to authenticate. (optional)
        :type ssh_key: ``str`` or ``list`` of ``str``

        :param ssh_key_password: Optional password used for encrypted keys.
        :type ssh_key_password: ``str``

        :param timeout: How many seconds to wait before timing out.
                             (default is 600)
        :type timeout: ``int``

        :param max_tries: How many times to retry if a deployment fails
                               before giving up (default is 3)
        :type max_tries: ``int``

        :param ssh_interface: The interface to wait for. Default is
                                   'public_ips', other option is 'private_ips'.
        :type ssh_interface: ``str``

        :param at_exit_func: Optional atexit handler function which will be
                             registered and called with created node if user
                             cancels the deploy process (e.g. CTRL+C), after
                             the node has been created, but before the deploy
                             process has finished.

                             This method gets passed in two keyword arguments:

                             - driver -> node driver in question
                             - node -> created Node object

                             Keep in mind that this function will only be
                             called in such scenario. In case the method
                             finishes (this includes throwing an exception),
                             at exit handler function won't be called.
        :type at_exit_func: ``func``

        :param wait_period: How many seconds to wait between each iteration
                            while waiting for node to transition into
                            running state and have IP assigned. (default is 5)
        :type wait_period: ``int``

        """
        if not libcloud.compute.ssh.have_paramiko:
            raise RuntimeError(
                "paramiko is not installed. You can install "
                + "it using pip: pip install paramiko"
            )

        if auth:
            if not isinstance(auth, (NodeAuthSSHKey, NodeAuthPassword)):
                raise NotImplementedError(
                    "If providing auth, only NodeAuthSSHKey or"
                    "NodeAuthPassword is supported"
                )
        elif ssh_key:
            # If an ssh_key is provided we can try deploy_node
            pass
        elif "create_node" in self.features:
            f = self.features["create_node"]
            if "generates_password" not in f and "password" not in f:
                raise NotImplementedError("deploy_node not implemented for this driver")
        else:
            raise NotImplementedError("deploy_node not implemented for this driver")

        # NOTE 1: This is a workaround for legacy code. Sadly a lot of legacy
        # code uses **kwargs in "create_node()" method and simply ignores
        # "deploy_node()" arguments which are passed to it.
        # That's obviously far from idea that's why we first try to pass only
        # non-deploy node arguments to the "create_node()" methods and if it
        # that doesn't work, fall back to the old approach and simply pass in
        # all the arguments
        # NOTE 2: Some drivers which use password based SSH authentication
        # rely on password being stored on the "auth" argument and that's why
        # we also propagate that argument to "create_node()" method.
        try:
            # NOTE: We only pass auth to the method if auth argument is
            # provided
            if auth:
                node = self.create_node(auth=auth, **create_node_kwargs)
            else:
                node = self.create_node(**create_node_kwargs)
        except TypeError as e:
            msg_1_re = r"create_node\(\) missing \d+ required " "positional arguments.*"
            msg_2_re = r"create_node\(\) takes at least \d+ arguments.*"
            if re.match(msg_1_re, str(e)) or re.match(msg_2_re, str(e)):
                # pylint: disable=unexpected-keyword-arg
                node = self.create_node(  # type: ignore
                    deploy=deploy,
                    ssh_username=ssh_username,
                    ssh_alternate_usernames=ssh_alternate_usernames,
                    ssh_port=ssh_port,
                    ssh_timeout=ssh_timeout,
                    ssh_key=ssh_key,
                    auth=auth,
                    timeout=timeout,
                    max_tries=max_tries,
                    ssh_interface=ssh_interface,
                    **create_node_kwargs,
                )
                # pylint: enable=unexpected-keyword-arg
            else:
                raise e

        if at_exit_func:
            atexit.register(at_exit_func, driver=self, node=node)

        password = None
        if auth:
            if isinstance(auth, NodeAuthPassword):
                password = auth.password
        elif "password" in node.extra:
            password = node.extra["password"]

        wait_timeout = timeout or NODE_ONLINE_WAIT_TIMEOUT

        # Wait until node is up and running and has IP assigned
        try:
            node, ip_addresses = self.wait_until_running(
                nodes=[node],
                wait_period=wait_period,
                timeout=wait_timeout,
                ssh_interface=ssh_interface,
            )[0]
        except Exception as e:
            if at_exit_func:
                atexit.unregister(at_exit_func)

            raise DeploymentError(node=node, original_exception=e, driver=self)

        ssh_alternate_usernames = ssh_alternate_usernames or []
        deploy_timeout = timeout or SSH_CONNECT_TIMEOUT

        deploy_error = None

        for username in [ssh_username] + ssh_alternate_usernames:
            try:
                self._connect_and_run_deployment_script(
                    task=deploy,
                    node=node,
                    ssh_hostname=ip_addresses[0],
                    ssh_port=ssh_port,
                    ssh_username=username,
                    ssh_password=password,
                    ssh_key_file=ssh_key,
                    ssh_key_password=ssh_key_password,
                    ssh_timeout=ssh_timeout,
                    timeout=deploy_timeout,
                    max_tries=max_tries,
                )
            except Exception as e:
                # Try alternate username
                # Todo: Need to fix paramiko so we can catch a more specific
                # exception
                deploy_error = e
            else:
                # Script successfully executed, don't try alternate username
                deploy_error = None
                break

        if deploy_error is not None:
            if at_exit_func:
                atexit.unregister(at_exit_func)

            raise DeploymentError(
                node=node, original_exception=deploy_error, driver=self
            )

        if at_exit_func:
            atexit.unregister(at_exit_func)

        return node

    def reboot_node(self, node):
        # type: (Node) -> bool
        """
        Reboot a node.

        :param node: The node to be rebooted
        :type node: :class:`.Node`

        :return: True if the reboot was successful, otherwise False
        :rtype: ``bool``
        """
        raise NotImplementedError("reboot_node not implemented for this driver")

    def start_node(self, node):
        # type: (Node) -> bool
        """
        Start a node.

        :param node: The node to be started
        :type node: :class:`.Node`

        :return: True if the start was successful, otherwise False
        :rtype: ``bool``
        """
        raise NotImplementedError("start_node not implemented for this driver")

    def stop_node(self, node):
        # type: (Node) -> bool
        """
        Stop a node

        :param node: The node to be stopped.
        :type node: :class:`.Node`

        :return: True if the stop was successful, otherwise False
        :rtype: ``bool``
        """
        raise NotImplementedError("stop_node not implemented for this driver")

    def destroy_node(self, node):
        # type: (Node) -> bool
        """
        Destroy a node.

        Depending upon the provider, this may destroy all data associated with
        the node, including backups.

        :param node: The node to be destroyed
        :type node: :class:`.Node`

        :return: True if the destroy was successful, False otherwise.
        :rtype: ``bool``
        """
        raise NotImplementedError("destroy_node not implemented for this driver")

    ##
    # Volume and snapshot management methods
    ##

    def list_volumes(self):
        # type: () -> List[StorageVolume]
        """
        List storage volumes.

        :rtype: ``list`` of :class:`.StorageVolume`
        """
        raise NotImplementedError("list_volumes not implemented for this driver")

    def list_volume_snapshots(self, volume):
        # type: (StorageVolume) -> List[VolumeSnapshot]
        """
        List snapshots for a storage volume.

        :rtype: ``list`` of :class:`VolumeSnapshot`
        """
        raise NotImplementedError(
            "list_volume_snapshots not implemented for this driver"
        )

    def create_volume(
        self,
        size,  # type: int
        name,  # type: str
        location=None,  # Optional[NodeLocation]
        snapshot=None,  # Optional[VolumeSnapshot]
    ):
        # type: (...) -> StorageVolume
        """
        Create a new volume.

        :param size: Size of volume in gigabytes (required)
        :type size: ``int``

        :param name: Name of the volume to be created
        :type name: ``str``

        :param location: Which data center to create a volume in. If
                               empty, undefined behavior will be selected.
                               (optional)
        :type location: :class:`.NodeLocation`

        :param snapshot:  Snapshot from which to create the new
                          volume.  (optional)
        :type snapshot: :class:`.VolumeSnapshot`

        :return: The newly created volume.
        :rtype: :class:`StorageVolume`
        """
        raise NotImplementedError("create_volume not implemented for this driver")

    def create_volume_snapshot(self, volume, name=None):
        # type: (StorageVolume, Optional[str]) -> VolumeSnapshot
        """
        Creates a snapshot of the storage volume.

        :param volume: The StorageVolume to create a VolumeSnapshot from
        :type volume: :class:`.StorageVolume`

        :param name: Name of created snapshot (optional)
        :type name: `str`

        :rtype: :class:`VolumeSnapshot`
        """
        raise NotImplementedError(
            "create_volume_snapshot not implemented for this driver"
        )

    def attach_volume(self, node, volume, device=None):
        # type: (Node, StorageVolume, Optional[str]) -> bool
        """
        Attaches volume to node.

        :param node: Node to attach volume to.
        :type node: :class:`.Node`

        :param volume: Volume to attach.
        :type volume: :class:`.StorageVolume`

        :param device: Where the device is exposed, e.g. '/dev/sdb'
        :type device: ``str``

        :rytpe: ``bool``
        """
        raise NotImplementedError("attach not implemented for this driver")

    def detach_volume(self, volume):
        # type: (StorageVolume) -> bool
        """
        Detaches a volume from a node.

        :param volume: Volume to be detached
        :type volume: :class:`.StorageVolume`

        :rtype: ``bool``
        """

        raise NotImplementedError("detach not implemented for this driver")

    def destroy_volume(self, volume):
        # type: (StorageVolume) -> bool
        """
        Destroys a storage volume.

        :param volume: Volume to be destroyed
        :type volume: :class:`StorageVolume`

        :rtype: ``bool``
        """

        raise NotImplementedError("destroy_volume not implemented for this driver")

    def destroy_volume_snapshot(self, snapshot):
        # type: (VolumeSnapshot) -> bool
        """
        Destroys a snapshot.

        :param snapshot: The snapshot to delete
        :type snapshot: :class:`VolumeSnapshot`

        :rtype: :class:`bool`
        """
        raise NotImplementedError(
            "destroy_volume_snapshot not implemented for this driver"
        )

    ##
    # Image management methods
    ##

    def list_images(self, location=None):
        # type: (Optional[NodeLocation]) -> List[NodeImage]
        """
        List images on a provider.

        :param location: The location at which to list images.
        :type location: :class:`.NodeLocation`

        :return: list of node image objects.
        :rtype: ``list`` of :class:`.NodeImage`
        """
        raise NotImplementedError("list_images not implemented for this driver")

    def create_image(self, node, name, description=None):
        # type: (Node, str, Optional[str]) -> List[NodeImage]
        """
        Creates an image from a node object.

        :param node: Node to run the task on.
        :type node: :class:`.Node`

        :param name: name for new image.
        :type name: ``str``

        :param description: description for new image.
        :type name: ``description``

        :rtype: :class:`.NodeImage`:
        :return: NodeImage instance on success.

        """
        raise NotImplementedError("create_image not implemented for this driver")

    def delete_image(self, node_image):
        # type: (NodeImage) -> bool
        """
        Deletes a node image from a provider.

        :param node_image: Node image object.
        :type node_image: :class:`.NodeImage`

        :return: ``True`` if delete_image was successful, ``False`` otherwise.
        :rtype: ``bool``
        """

        raise NotImplementedError("delete_image not implemented for this driver")

    def get_image(self, image_id):
        # type: (str) -> NodeImage
        """
        Returns a single node image from a provider.

        :param image_id: Node to run the task on.
        :type image_id: ``str``

        :rtype :class:`.NodeImage`:
        :return: NodeImage instance on success.
        """
        raise NotImplementedError("get_image not implemented for this driver")

    def copy_image(self, source_region, node_image, name, description=None):
        # type: (str, NodeImage, str, Optional[str]) -> NodeImage
        """
        Copies an image from a source region to the current region.

        :param source_region: Region to copy the node from.
        :type source_region: ``str``

        :param node_image: NodeImage to copy.
        :type node_image: :class:`.NodeImage`:

        :param name: name for new image.
        :type name: ``str``

        :param description: description for new image.
        :type name: ``str``

        :rtype: :class:`.NodeImage`:
        :return: NodeImage instance on success.
        """
        raise NotImplementedError("copy_image not implemented for this driver")

    ##
    # SSH key pair management methods
    ##

    def list_key_pairs(self):
        # type: () -> List[KeyPair]
        """
        List all the available key pair objects.

        :rtype: ``list`` of :class:`.KeyPair` objects
        """
        raise NotImplementedError("list_key_pairs not implemented for this driver")

    def get_key_pair(self, name):
        # type: (str) -> KeyPair
        """
        Retrieve a single key pair.

        :param name: Name of the key pair to retrieve.
        :type name: ``str``

        :rtype: :class:`.KeyPair`
        """
        raise NotImplementedError("get_key_pair not implemented for this driver")

    def create_key_pair(self, name):
        # type: (str) -> KeyPair
        """
        Create a new key pair object.

        :param name: Key pair name.
        :type name: ``str``

        :rtype: :class:`.KeyPair` object
        """
        raise NotImplementedError("create_key_pair not implemented for this driver")

    def import_key_pair_from_string(self, name, key_material):
        # type: (str, str) -> KeyPair
        """
        Import a new public key from string.

        :param name: Key pair name.
        :type name: ``str``

        :param key_material: Public key material.
        :type key_material: ``str``

        :rtype: :class:`.KeyPair` object
        """
        raise NotImplementedError(
            "import_key_pair_from_string not implemented for this driver"
        )

    def import_key_pair_from_file(self, name, key_file_path):
        # type: (str, str) -> KeyPair
        """
        Import a new public key from string.

        :param name: Key pair name.
        :type name: ``str``

        :param key_file_path: Path to the public key file.
        :type key_file_path: ``str``

        :rtype: :class:`.KeyPair` object
        """
        key_file_path = os.path.expanduser(key_file_path)

        with open(key_file_path, "r") as fp:
            key_material = fp.read().strip()

        return self.import_key_pair_from_string(name=name, key_material=key_material)

    def delete_key_pair(self, key_pair):
        # type: (KeyPair) -> bool
        """
        Delete an existing key pair.

        :param key_pair: Key pair object.
        :type key_pair: :class:`.KeyPair`

        :rtype: ``bool``
        """
        raise NotImplementedError("delete_key_pair not implemented for this driver")

    def wait_until_running(
        self,
        nodes,  # type: List[Node]
        wait_period=5,  # type: float
        timeout=600,  # type: int
        ssh_interface="public_ips",  # type: str
        force_ipv4=True,  # type: bool
        ex_list_nodes_kwargs=None,  # type: Optional[Dict]
    ):
        # type: (...) -> List[Tuple[Node, List[str]]]
        """
        Block until the provided nodes are considered running.

        Node is considered running when it's state is "running" and when it has
        at least one IP address assigned.

        :param nodes: List of nodes to wait for.
        :type nodes: ``list`` of :class:`.Node`

        :param wait_period: How many seconds to wait between each loop
                            iteration. (default is 3)
        :type wait_period: ``int``

        :param timeout: How many seconds to wait before giving up.
                        (default is 600)
        :type timeout: ``int``

        :param ssh_interface: Which attribute on the node to use to obtain
                              an IP address. Valid options: public_ips,
                              private_ips. Default is public_ips.
        :type ssh_interface: ``str``

        :param force_ipv4: Ignore IPv6 addresses (default is True).
        :type force_ipv4: ``bool``

        :param ex_list_nodes_kwargs: Optional driver-specific keyword arguments
                                     which are passed to the ``list_nodes``
                                     method.
        :type ex_list_nodes_kwargs: ``dict``

        :return: ``[(Node, ip_addresses)]`` list of tuple of Node instance and
                 list of ip_address on success.
        :rtype: ``list`` of ``tuple``
        """
        ex_list_nodes_kwargs = ex_list_nodes_kwargs or {}

        def is_supported(address):
            # type: (str) -> bool
            """
            Return True for supported address.
            """
            if force_ipv4 and not is_valid_ip_address(
                address=address, family=socket.AF_INET
            ):
                return False
            return True

        def filter_addresses(addresses):
            # type: (List[str]) -> List[str]
            """
            Return list of supported addresses.
            """
            return [address for address in addresses if is_supported(address)]

        if ssh_interface not in ["public_ips", "private_ips"]:
            raise ValueError(
                "ssh_interface argument must either be " + "public_ips or private_ips"
            )

        start = time.time()
        end = start + timeout

        uuids = set([node.uuid for node in nodes])

        while time.time() < end:
            all_nodes = self.list_nodes(**ex_list_nodes_kwargs)
            matching_nodes = list([node for node in all_nodes if node.uuid in uuids])

            if len(matching_nodes) > len(uuids):
                found_uuids = [node.uuid for node in matching_nodes]
                msg = (
                    "Unable to match specified uuids "
                    + "(%s) with existing nodes. Found " % (uuids)
                    + "multiple nodes with same uuid: (%s)" % (found_uuids)
                )
                raise LibcloudError(value=msg, driver=self)

            running_nodes = [
                node for node in matching_nodes if node.state == NodeState.RUNNING
            ]
            addresses = []
            for node in running_nodes:
                node_addresses = filter_addresses(getattr(node, ssh_interface))
                if len(node_addresses) >= 1:
                    addresses.append(node_addresses)

            if len(running_nodes) == len(uuids) == len(addresses):
                return list(zip(running_nodes, addresses))
            else:
                time.sleep(wait_period)
                continue

        raise LibcloudError(value="Timed out after %s seconds" % (timeout), driver=self)

    def _get_and_check_auth(self, auth):
        # type: (T_Auth) -> T_Auth
        """
        Helper function for providers supporting :class:`.NodeAuthPassword` or
        :class:`.NodeAuthSSHKey`

        Validates that only a supported object type is passed to the auth
        parameter and raises an exception if it is not.

        If no :class:`.NodeAuthPassword` object is provided but one is expected
        then a password is automatically generated.
        """

        if isinstance(auth, NodeAuthPassword):
            if "password" in self.features["create_node"]:
                return auth
            raise LibcloudError(
                "Password provided as authentication information, but password"
                "not supported",
                driver=self,
            )

        if isinstance(auth, NodeAuthSSHKey):
            if "ssh_key" in self.features["create_node"]:
                return auth
            raise LibcloudError(
                "SSH Key provided as authentication information, but SSH Key"
                "not supported",
                driver=self,
            )

        if "password" in self.features["create_node"]:
            value = os.urandom(16)
            value = binascii.hexlify(value).decode("ascii")

            # Some providers require password to also include uppercase
            # characters so convert some characters to uppercase
            password = ""
            for char in value:
                if not char.isdigit() and char.islower():
                    if random.randint(0, 1) == 1:
                        char = char.upper()

                password += char

            return NodeAuthPassword(password, generated=True)

        if auth:
            raise LibcloudError(
                '"auth" argument provided, but it was not a NodeAuthPassword'
                "or NodeAuthSSHKey object",
                driver=self,
            )

    def _wait_until_running(
        self,
        node,
        wait_period=3,
        timeout=600,
        ssh_interface="public_ips",
        force_ipv4=True,
    ):
        # type: (Node, float, int, str, bool) -> List[Tuple[Node, List[str]]]
        # This is here for backward compatibility and will be removed in the
        # next major release
        return self.wait_until_running(
            nodes=[node],
            wait_period=wait_period,
            timeout=timeout,
            ssh_interface=ssh_interface,
            force_ipv4=force_ipv4,
        )

    def _ssh_client_connect(self, ssh_client, wait_period=1.5, timeout=300):
        # type: (BaseSSHClient, float, int) -> BaseSSHClient
        """
        Try to connect to the remote SSH server. If a connection times out or
        is refused it is retried up to timeout number of seconds.

        :param ssh_client: A configured SSHClient instance
        :type ssh_client: ``SSHClient``

        :param wait_period: How many seconds to wait between each loop
                            iteration. (default is 1.5)
        :type wait_period: ``int``

        :param timeout: How many seconds to wait before giving up.
                        (default is 300)
        :type timeout: ``int``

        :return: ``SSHClient`` on success
        """
        start = time.time()
        end = start + timeout

        while time.time() < end:
            try:
                ssh_client.connect()
            except SSH_TIMEOUT_EXCEPTION_CLASSES as e:
                # Errors which represent fatal invalid key files which should
                # be propagated to the user without us retrying
                message = str(e).lower()

                for fatal_msg in SSH_FATAL_ERROR_MSGS:
                    if fatal_msg in message:
                        raise e

                # Retry if a connection is refused, timeout occurred,
                # or the connection fails due to failed authentication.
                try:
                    ssh_client.close()
                except Exception:
                    # Exception on close() should not be fatal since client
                    # socket might already be closed
                    pass

                time.sleep(wait_period)
                continue
            else:
                return ssh_client

        raise LibcloudError(
            value="Could not connect to the remote SSH " + "server. Giving up.",
            driver=self,
        )

    def _connect_and_run_deployment_script(
        self,
        task,  # type: Deployment
        node,  # type: Node
        ssh_hostname,  # type: str
        ssh_port,  # type: int
        ssh_username,  # type: str
        ssh_password,  # type: Optional[str]
        ssh_key_file,  # type: Optional[T_Ssh_key]
        ssh_key_password,  # type: Optional[str]
        ssh_timeout,  # type: int
        timeout,  # type: int
        max_tries,  # type: int
    ):
        """
        Establish an SSH connection to the node and run the provided deployment
        task.

        :rtype: :class:`.Node`:
        :return: Node instance on success.
        """
        ssh_client = SSHClient(
            hostname=ssh_hostname,
            port=ssh_port,
            username=ssh_username,
            password=ssh_key_password or ssh_password,
            key_files=ssh_key_file,
            timeout=ssh_timeout,
        )

        ssh_client = self._ssh_client_connect(ssh_client=ssh_client, timeout=timeout)

        # Execute the deployment task
        node = self._run_deployment_script(
            task=task, node=node, ssh_client=ssh_client, max_tries=max_tries
        )
        return node

    def _run_deployment_script(self, task, node, ssh_client, max_tries=3):
        # type: (Deployment, Node, BaseSSHClient, int) -> Node
        """
        Run the deployment script on the provided node. At this point it is
        assumed that SSH connection has already been established.

        :param task: Deployment task to run.
        :type task: :class:`Deployment`

        :param node: Node to run the task on.
        :type node: ``Node``

        :param ssh_client: A configured and connected SSHClient instance.
        :type ssh_client: :class:`SSHClient`

        :param max_tries: How many times to retry if a deployment fails
                          before giving up. (default is 3)
        :type max_tries: ``int``

        :rtype: :class:`.Node`
        :return: ``Node`` Node instance on success.
        """
        tries = 0

        while tries < max_tries:
            try:
                node = task.run(node, ssh_client)
            except SSHCommandTimeoutError as e:
                # Command timeout exception is fatal so we don't retry it.
                raise e
            except Exception as e:
                tries += 1

                if "ssh session not active" in str(e).lower():
                    # Sometimes connection gets closed or disconnected half
                    # way through for wahtever reason.
                    # If this happens, we try to re-connect before
                    # re-attempting to run the step.
                    try:
                        ssh_client.close()
                    except Exception:
                        # Non fatal since connection is most likely already
                        # closed at this point
                        pass

                    timeout = int(ssh_client.timeout) if ssh_client.timeout else 10
                    ssh_client = self._ssh_client_connect(
                        ssh_client=ssh_client, timeout=timeout
                    )

                if tries >= max_tries:
                    tb = traceback.format_exc()
                    raise LibcloudError(
                        value="Failed after %d tries: %s.\n%s"
                        % (max_tries, str(e), tb),
                        driver=self,
                    )
            else:
                # Deployment succeeded
                ssh_client.close()
                return node

        return node

    def _get_size_price(self, size_id):
        # type: (str) -> Optional[float]
        """
        Return pricing information for the provided size id.
        """
        return get_size_price(
            driver_type="compute", driver_name=self.api_name, size_id=size_id
        )


if __name__ == "__main__":
    import doctest

    doctest.testmod()
