import six

from .. import errors
from ..constants import IS_WINDOWS_PLATFORM
from ..utils import (
    check_resource, format_environment, format_extra_hosts, parse_bytes,
    split_command, convert_service_networks,
)


class TaskTemplate(dict):
    """
    Describe the task specification to be used when creating or updating a
    service.

    Args:

        container_spec (ContainerSpec): Container settings for containers
          started as part of this task.
        log_driver (DriverConfig): Log configuration for containers created as
          part of the service.
        resources (Resources): Resource requirements which apply to each
          individual container created as part of the service.
        restart_policy (RestartPolicy): Specification for the restart policy
          which applies to containers created as part of this service.
        placement (Placement): Placement instructions for the scheduler.
            If a list is passed instead, it is assumed to be a list of
            constraints as part of a :py:class:`Placement` object.
        networks (:py:class:`list`): List of network names or IDs or
            :py:class:`NetworkAttachmentConfig` to attach the service to.
        force_update (int): A counter that triggers an update even if no
            relevant parameters have been changed.
    """
    def __init__(self, container_spec, resources=None, restart_policy=None,
                 placement=None, log_driver=None, networks=None,
                 force_update=None):
        self['ContainerSpec'] = container_spec
        if resources:
            self['Resources'] = resources
        if restart_policy:
            self['RestartPolicy'] = restart_policy
        if placement:
            if isinstance(placement, list):
                placement = Placement(constraints=placement)
            self['Placement'] = placement
        if log_driver:
            self['LogDriver'] = log_driver
        if networks:
            self['Networks'] = convert_service_networks(networks)

        if force_update is not None:
            if not isinstance(force_update, int):
                raise TypeError('force_update must be an integer')
            self['ForceUpdate'] = force_update

    @property
    def container_spec(self):
        return self.get('ContainerSpec')

    @property
    def resources(self):
        return self.get('Resources')

    @property
    def restart_policy(self):
        return self.get('RestartPolicy')

    @property
    def placement(self):
        return self.get('Placement')


class ContainerSpec(dict):
    """
    Describes the behavior of containers that are part of a task, and is used
    when declaring a :py:class:`~docker.types.TaskTemplate`.

    Args:

        image (string): The image name to use for the container.
        command (string or list):  The command to be run in the image.
        args (:py:class:`list`): Arguments to the command.
        hostname (string): The hostname to set on the container.
        env (dict): Environment variables.
        workdir (string): The working directory for commands to run in.
        user (string): The user inside the container.
        labels (dict): A map of labels to associate with the service.
        mounts (:py:class:`list`): A list of specifications for mounts to be
            added to containers created as part of the service. See the
            :py:class:`~docker.types.Mount` class for details.
        stop_grace_period (int): Amount of time to wait for the container to
            terminate before forcefully killing it.
        secrets (:py:class:`list`): List of :py:class:`SecretReference` to be
            made available inside the containers.
        tty (boolean): Whether a pseudo-TTY should be allocated.
        groups (:py:class:`list`): A list of additional groups that the
            container process will run as.
        open_stdin (boolean): Open ``stdin``
        read_only (boolean): Mount the container's root filesystem as read
            only.
        stop_signal (string): Set signal to stop the service's containers
        healthcheck (Healthcheck): Healthcheck
            configuration for this service.
        hosts (:py:class:`dict`): A set of host to IP mappings to add to
            the container's ``hosts`` file.
        dns_config (DNSConfig): Specification for DNS
            related configurations in resolver configuration file.
        configs (:py:class:`list`): List of :py:class:`ConfigReference` that
            will be exposed to the service.
        privileges (Privileges): Security options for the service's containers.
        isolation (string): Isolation technology used by the service's
            containers. Only used for Windows containers.
        init (boolean): Run an init inside the container that forwards signals
            and reaps processes.
    """
    def __init__(self, image, command=None, args=None, hostname=None, env=None,
                 workdir=None, user=None, labels=None, mounts=None,
                 stop_grace_period=None, secrets=None, tty=None, groups=None,
                 open_stdin=None, read_only=None, stop_signal=None,
                 healthcheck=None, hosts=None, dns_config=None, configs=None,
                 privileges=None, isolation=None, init=None):
        self['Image'] = image

        if isinstance(command, six.string_types):
            command = split_command(command)
        self['Command'] = command
        self['Args'] = args

        if hostname is not None:
            self['Hostname'] = hostname
        if env is not None:
            if isinstance(env, dict):
                self['Env'] = format_environment(env)
            else:
                self['Env'] = env
        if workdir is not None:
            self['Dir'] = workdir
        if user is not None:
            self['User'] = user
        if groups is not None:
            self['Groups'] = groups
        if stop_signal is not None:
            self['StopSignal'] = stop_signal
        if stop_grace_period is not None:
            self['StopGracePeriod'] = stop_grace_period
        if labels is not None:
            self['Labels'] = labels
        if hosts is not None:
            self['Hosts'] = format_extra_hosts(hosts, task=True)

        if mounts is not None:
            parsed_mounts = []
            for mount in mounts:
                if isinstance(mount, six.string_types):
                    parsed_mounts.append(Mount.parse_mount_string(mount))
                else:
                    # If mount already parsed
                    parsed_mounts.append(mount)
            self['Mounts'] = parsed_mounts

        if secrets is not None:
            if not isinstance(secrets, list):
                raise TypeError('secrets must be a list')
            self['Secrets'] = secrets

        if configs is not None:
            if not isinstance(configs, list):
                raise TypeError('configs must be a list')
            self['Configs'] = configs

        if dns_config is not None:
            self['DNSConfig'] = dns_config
        if privileges is not None:
            self['Privileges'] = privileges
        if healthcheck is not None:
            self['Healthcheck'] = healthcheck

        if tty is not None:
            self['TTY'] = tty
        if open_stdin is not None:
            self['OpenStdin'] = open_stdin
        if read_only is not None:
            self['ReadOnly'] = read_only

        if isolation is not None:
            self['Isolation'] = isolation

        if init is not None:
            self['Init'] = init


class Mount(dict):
    """
    Describes a mounted folder's configuration inside a container. A list of
    :py:class:`Mount` would be used as part of a
    :py:class:`~docker.types.ContainerSpec`.

    Args:

        target (string): Container path.
        source (string): Mount source (e.g. a volume name or a host path).
        type (string): The mount type (``bind`` / ``volume`` / ``tmpfs`` /
            ``npipe``). Default: ``volume``.
        read_only (bool): Whether the mount should be read-only.
        consistency (string): The consistency requirement for the mount. One of
        ``default```, ``consistent``, ``cached``, ``delegated``.
        propagation (string): A propagation mode with the value ``[r]private``,
          ``[r]shared``, or ``[r]slave``. Only valid for the ``bind`` type.
        no_copy (bool): False if the volume should be populated with the data
          from the target. Default: ``False``. Only valid for the ``volume``
          type.
        labels (dict): User-defined name and labels for the volume. Only valid
          for the ``volume`` type.
        driver_config (DriverConfig): Volume driver configuration. Only valid
          for the ``volume`` type.
        tmpfs_size (int or string): The size for the tmpfs mount in bytes.
        tmpfs_mode (int): The permission mode for the tmpfs mount.
    """
    def __init__(self, target, source, type='volume', read_only=False,
                 consistency=None, propagation=None, no_copy=False,
                 labels=None, driver_config=None, tmpfs_size=None,
                 tmpfs_mode=None):
        self['Target'] = target
        self['Source'] = source
        if type not in ('bind', 'volume', 'tmpfs', 'npipe'):
            raise errors.InvalidArgument(
                'Unsupported mount type: "{}"'.format(type)
            )
        self['Type'] = type
        self['ReadOnly'] = read_only

        if consistency:
            self['Consistency'] = consistency

        if type == 'bind':
            if propagation is not None:
                self['BindOptions'] = {
                    'Propagation': propagation
                }
            if any([labels, driver_config, no_copy, tmpfs_size, tmpfs_mode]):
                raise errors.InvalidArgument(
                    'Incompatible options have been provided for the bind '
                    'type mount.'
                )
        elif type == 'volume':
            volume_opts = {}
            if no_copy:
                volume_opts['NoCopy'] = True
            if labels:
                volume_opts['Labels'] = labels
            if driver_config:
                volume_opts['DriverConfig'] = driver_config
            if volume_opts:
                self['VolumeOptions'] = volume_opts
            if any([propagation, tmpfs_size, tmpfs_mode]):
                raise errors.InvalidArgument(
                    'Incompatible options have been provided for the volume '
                    'type mount.'
                )
        elif type == 'tmpfs':
            tmpfs_opts = {}
            if tmpfs_mode:
                if not isinstance(tmpfs_mode, six.integer_types):
                    raise errors.InvalidArgument(
                        'tmpfs_mode must be an integer'
                    )
                tmpfs_opts['Mode'] = tmpfs_mode
            if tmpfs_size:
                tmpfs_opts['SizeBytes'] = parse_bytes(tmpfs_size)
            if tmpfs_opts:
                self['TmpfsOptions'] = tmpfs_opts
            if any([propagation, labels, driver_config, no_copy]):
                raise errors.InvalidArgument(
                    'Incompatible options have been provided for the tmpfs '
                    'type mount.'
                )

    @classmethod
    def parse_mount_string(cls, string):
        parts = string.split(':')
        if len(parts) > 3:
            raise errors.InvalidArgument(
                'Invalid mount format "{0}"'.format(string)
            )
        if len(parts) == 1:
            return cls(target=parts[0], source=None)
        else:
            target = parts[1]
            source = parts[0]
            mount_type = 'volume'
            if source.startswith('/') or (
                IS_WINDOWS_PLATFORM and source[0].isalpha() and
                source[1] == ':'
            ):
                # FIXME: That windows condition will fail earlier since we
                # split on ':'. We should look into doing a smarter split
                # if we detect we are on Windows.
                mount_type = 'bind'
            read_only = not (len(parts) == 2 or parts[2] == 'rw')
            return cls(target, source, read_only=read_only, type=mount_type)


class Resources(dict):
    """
    Configures resource allocation for containers when made part of a
    :py:class:`~docker.types.ContainerSpec`.

    Args:

        cpu_limit (int): CPU limit in units of 10^9 CPU shares.
        mem_limit (int): Memory limit in Bytes.
        cpu_reservation (int): CPU reservation in units of 10^9 CPU shares.
        mem_reservation (int): Memory reservation in Bytes.
        generic_resources (dict or :py:class:`list`): Node level generic
          resources, for example a GPU, using the following format:
          ``{ resource_name: resource_value }``. Alternatively, a list of
          of resource specifications as defined by the Engine API.
    """
    def __init__(self, cpu_limit=None, mem_limit=None, cpu_reservation=None,
                 mem_reservation=None, generic_resources=None):
        limits = {}
        reservation = {}
        if cpu_limit is not None:
            limits['NanoCPUs'] = cpu_limit
        if mem_limit is not None:
            limits['MemoryBytes'] = mem_limit
        if cpu_reservation is not None:
            reservation['NanoCPUs'] = cpu_reservation
        if mem_reservation is not None:
            reservation['MemoryBytes'] = mem_reservation
        if generic_resources is not None:
            reservation['GenericResources'] = (
                _convert_generic_resources_dict(generic_resources)
            )
        if limits:
            self['Limits'] = limits
        if reservation:
            self['Reservations'] = reservation


def _convert_generic_resources_dict(generic_resources):
    if isinstance(generic_resources, list):
        return generic_resources
    if not isinstance(generic_resources, dict):
        raise errors.InvalidArgument(
            'generic_resources must be a dict or a list'
            ' (found {})'.format(type(generic_resources))
        )
    resources = []
    for kind, value in six.iteritems(generic_resources):
        resource_type = None
        if isinstance(value, int):
            resource_type = 'DiscreteResourceSpec'
        elif isinstance(value, str):
            resource_type = 'NamedResourceSpec'
        else:
            raise errors.InvalidArgument(
                'Unsupported generic resource reservation '
                'type: {}'.format({kind: value})
            )
        resources.append({
            resource_type: {'Kind': kind, 'Value': value}
        })
    return resources


class UpdateConfig(dict):
    """

    Used to specify the way container updates should be performed by a service.

    Args:

        parallelism (int): Maximum number of tasks to be updated in one
          iteration (0 means unlimited parallelism). Default: 0.
        delay (int): Amount of time between updates, in nanoseconds.
        failure_action (string): Action to take if an updated task fails to
          run, or stops running during the update. Acceptable values are
          ``continue``, ``pause``, as well as ``rollback`` since API v1.28.
          Default: ``continue``
        monitor (int): Amount of time to monitor each updated task for
          failures, in nanoseconds.
        max_failure_ratio (float): The fraction of tasks that may fail during
          an update before the failure action is invoked, specified as a
          floating point number between 0 and 1. Default: 0
        order (string): Specifies the order of operations when rolling out an
          updated task. Either ``start_first`` or ``stop_first`` are accepted.
    """
    def __init__(self, parallelism=0, delay=None, failure_action='continue',
                 monitor=None, max_failure_ratio=None, order=None):
        self['Parallelism'] = parallelism
        if delay is not None:
            self['Delay'] = delay
        if failure_action not in ('pause', 'continue', 'rollback'):
            raise errors.InvalidArgument(
                'failure_action must be one of `pause`, `continue`, `rollback`'
            )
        self['FailureAction'] = failure_action

        if monitor is not None:
            if not isinstance(monitor, int):
                raise TypeError('monitor must be an integer')
            self['Monitor'] = monitor

        if max_failure_ratio is not None:
            if not isinstance(max_failure_ratio, (float, int)):
                raise TypeError('max_failure_ratio must be a float')
            if max_failure_ratio > 1 or max_failure_ratio < 0:
                raise errors.InvalidArgument(
                    'max_failure_ratio must be a number between 0 and 1'
                )
            self['MaxFailureRatio'] = max_failure_ratio

        if order is not None:
            if order not in ('start-first', 'stop-first'):
                raise errors.InvalidArgument(
                    'order must be either `start-first` or `stop-first`'
                )
            self['Order'] = order


class RollbackConfig(UpdateConfig):
    """
    Used to specify the way containe rollbacks should be performed by a service

    Args:
        parallelism (int): Maximum number of tasks to be rolled back in one
          iteration (0 means unlimited parallelism). Default: 0
        delay (int): Amount of time between rollbacks, in nanoseconds.
        failure_action (string): Action to take if a rolled back task fails to
          run, or stops running during the rollback. Acceptable values are
          ``continue``, ``pause`` or ``rollback``.
          Default: ``continue``
        monitor (int): Amount of time to monitor each rolled back task for
          failures, in nanoseconds.
        max_failure_ratio (float): The fraction of tasks that may fail during
          a rollback before the failure action is invoked, specified as a
          floating point number between 0 and 1. Default: 0
        order (string): Specifies the order of operations when rolling out a
          rolled back task. Either ``start_first`` or ``stop_first`` are
          accepted.
    """
    pass


class RestartConditionTypesEnum(object):
    _values = (
        'none',
        'on-failure',
        'any',
    )
    NONE, ON_FAILURE, ANY = _values


class RestartPolicy(dict):
    """
    Used when creating a :py:class:`~docker.types.ContainerSpec`,
    dictates whether a container should restart after stopping or failing.

    Args:

        condition (string): Condition for restart (``none``, ``on-failure``,
          or ``any``). Default: `none`.
        delay (int): Delay between restart attempts. Default: 0
        max_attempts (int): Maximum attempts to restart a given container
          before giving up. Default value is 0, which is ignored.
        window (int): Time window used to evaluate the restart policy. Default
          value is 0, which is unbounded.
    """

    condition_types = RestartConditionTypesEnum

    def __init__(self, condition=RestartConditionTypesEnum.NONE, delay=0,
                 max_attempts=0, window=0):
        if condition not in self.condition_types._values:
            raise TypeError(
                'Invalid RestartPolicy condition {0}'.format(condition)
            )

        self['Condition'] = condition
        self['Delay'] = delay
        self['MaxAttempts'] = max_attempts
        self['Window'] = window


class DriverConfig(dict):
    """
    Indicates which driver to use, as well as its configuration. Can be used
    as ``log_driver`` in a :py:class:`~docker.types.ContainerSpec`,
    for the `driver_config` in a volume :py:class:`~docker.types.Mount`, or
    as the driver object in
    :py:meth:`create_secret`.

    Args:

        name (string): Name of the driver to use.
        options (dict): Driver-specific options. Default: ``None``.
    """
    def __init__(self, name, options=None):
        self['Name'] = name
        if options:
            self['Options'] = options


class EndpointSpec(dict):
    """
    Describes properties to access and load-balance a service.

    Args:

        mode (string): The mode of resolution to use for internal load
          balancing between tasks (``'vip'`` or ``'dnsrr'``). Defaults to
          ``'vip'`` if not provided.
        ports (dict): Exposed ports that this service is accessible on from the
          outside, in the form of ``{ published_port: target_port }`` or
          ``{ published_port: <port_config_tuple> }``. Port config tuple format
          is ``(target_port [, protocol [, publish_mode]])``.
          Ports can only be provided if the ``vip`` resolution mode is used.
    """
    def __init__(self, mode=None, ports=None):
        if ports:
            self['Ports'] = convert_service_ports(ports)
        if mode:
            self['Mode'] = mode


def convert_service_ports(ports):
    if isinstance(ports, list):
        return ports
    if not isinstance(ports, dict):
        raise TypeError(
            'Invalid type for ports, expected dict or list'
        )

    result = []
    for k, v in six.iteritems(ports):
        port_spec = {
            'Protocol': 'tcp',
            'PublishedPort': k
        }

        if isinstance(v, tuple):
            port_spec['TargetPort'] = v[0]
            if len(v) >= 2 and v[1] is not None:
                port_spec['Protocol'] = v[1]
            if len(v) == 3:
                port_spec['PublishMode'] = v[2]
            if len(v) > 3:
                raise ValueError(
                    'Service port configuration can have at most 3 elements: '
                    '(target_port, protocol, mode)'
                )
        else:
            port_spec['TargetPort'] = v

        result.append(port_spec)
    return result


class ServiceMode(dict):
    """
        Indicate whether a service should be deployed as a replicated or global
        service, and associated parameters

        Args:
            mode (string): Can be either ``replicated`` or ``global``
            replicas (int): Number of replicas. For replicated services only.
    """
    def __init__(self, mode, replicas=None):
        if mode not in ('replicated', 'global'):
            raise errors.InvalidArgument(
                'mode must be either "replicated" or "global"'
            )
        if mode != 'replicated' and replicas is not None:
            raise errors.InvalidArgument(
                'replicas can only be used for replicated mode'
            )
        self[mode] = {}
        if replicas is not None:
            self[mode]['Replicas'] = replicas

    @property
    def mode(self):
        if 'global' in self:
            return 'global'
        return 'replicated'

    @property
    def replicas(self):
        if self.mode != 'replicated':
            return None
        return self['replicated'].get('Replicas')


class SecretReference(dict):
    """
        Secret reference to be used as part of a :py:class:`ContainerSpec`.
        Describes how a secret is made accessible inside the service's
        containers.

        Args:
            secret_id (string): Secret's ID
            secret_name (string): Secret's name as defined at its creation.
            filename (string): Name of the file containing the secret. Defaults
                to the secret's name if not specified.
            uid (string): UID of the secret file's owner. Default: 0
            gid (string): GID of the secret file's group. Default: 0
            mode (int): File access mode inside the container. Default: 0o444
    """
    @check_resource('secret_id')
    def __init__(self, secret_id, secret_name, filename=None, uid=None,
                 gid=None, mode=0o444):
        self['SecretName'] = secret_name
        self['SecretID'] = secret_id
        self['File'] = {
            'Name': filename or secret_name,
            'UID': uid or '0',
            'GID': gid or '0',
            'Mode': mode
        }


class ConfigReference(dict):
    """
        Config reference to be used as part of a :py:class:`ContainerSpec`.
        Describes how a config is made accessible inside the service's
        containers.

        Args:
            config_id (string): Config's ID
            config_name (string): Config's name as defined at its creation.
            filename (string): Name of the file containing the config. Defaults
                to the config's name if not specified.
            uid (string): UID of the config file's owner. Default: 0
            gid (string): GID of the config file's group. Default: 0
            mode (int): File access mode inside the container. Default: 0o444
    """
    @check_resource('config_id')
    def __init__(self, config_id, config_name, filename=None, uid=None,
                 gid=None, mode=0o444):
        self['ConfigName'] = config_name
        self['ConfigID'] = config_id
        self['File'] = {
            'Name': filename or config_name,
            'UID': uid or '0',
            'GID': gid or '0',
            'Mode': mode
        }


class Placement(dict):
    """
        Placement constraints to be used as part of a :py:class:`TaskTemplate`

        Args:
            constraints (:py:class:`list` of str): A list of constraints
            preferences (:py:class:`list` of tuple): Preferences provide a way
                to make the scheduler aware of factors such as topology. They
                are provided in order from highest to lowest precedence and
                are expressed as ``(strategy, descriptor)`` tuples. See
                :py:class:`PlacementPreference` for details.
            maxreplicas (int): Maximum number of replicas per node
            platforms (:py:class:`list` of tuple): A list of platforms
                expressed as ``(arch, os)`` tuples
    """
    def __init__(self, constraints=None, preferences=None, platforms=None,
                 maxreplicas=None):
        if constraints is not None:
            self['Constraints'] = constraints
        if preferences is not None:
            self['Preferences'] = []
            for pref in preferences:
                if isinstance(pref, tuple):
                    pref = PlacementPreference(*pref)
                self['Preferences'].append(pref)
        if maxreplicas is not None:
            self['MaxReplicas'] = maxreplicas
        if platforms:
            self['Platforms'] = []
            for plat in platforms:
                self['Platforms'].append({
                    'Architecture': plat[0], 'OS': plat[1]
                })


class PlacementPreference(dict):
    """
        Placement preference to be used as an element in the list of
        preferences for :py:class:`Placement` objects.

        Args:
            strategy (string): The placement strategy to implement. Currently,
                the only supported strategy is ``spread``.
            descriptor (string): A label descriptor. For the spread strategy,
                the scheduler will try to spread tasks evenly over groups of
                nodes identified by this label.
    """
    def __init__(self, strategy, descriptor):
        if strategy != 'spread':
            raise errors.InvalidArgument(
                'PlacementPreference strategy value is invalid ({}):'
                ' must be "spread".'.format(strategy)
            )
        self['Spread'] = {'SpreadDescriptor': descriptor}


class DNSConfig(dict):
    """
        Specification for DNS related configurations in resolver configuration
        file (``resolv.conf``). Part of a :py:class:`ContainerSpec` definition.

        Args:
            nameservers (:py:class:`list`): The IP addresses of the name
                servers.
            search (:py:class:`list`): A search list for host-name lookup.
            options (:py:class:`list`): A list of internal resolver variables
                to be modified (e.g., ``debug``, ``ndots:3``, etc.).
    """
    def __init__(self, nameservers=None, search=None, options=None):
        self['Nameservers'] = nameservers
        self['Search'] = search
        self['Options'] = options


class Privileges(dict):
    r"""
        Security options for a service's containers.
        Part of a :py:class:`ContainerSpec` definition.

        Args:
            credentialspec_file (str): Load credential spec from this file.
                The file is read by the daemon, and must be present in the
                CredentialSpecs subdirectory in the docker data directory,
                which defaults to ``C:\ProgramData\Docker\`` on Windows.
                Can not be combined with credentialspec_registry.

            credentialspec_registry (str): Load credential spec from this value
                in the Windows registry. The specified registry value must be
                located in: ``HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
                \Virtualization\Containers\CredentialSpecs``.
                Can not be combined with credentialspec_file.

            selinux_disable (boolean): Disable SELinux
            selinux_user (string): SELinux user label
            selinux_role (string): SELinux role label
            selinux_type (string): SELinux type label
            selinux_level (string): SELinux level label
    """
    def __init__(self, credentialspec_file=None, credentialspec_registry=None,
                 selinux_disable=None, selinux_user=None, selinux_role=None,
                 selinux_type=None, selinux_level=None):
        credential_spec = {}
        if credentialspec_registry is not None:
            credential_spec['Registry'] = credentialspec_registry
        if credentialspec_file is not None:
            credential_spec['File'] = credentialspec_file

        if len(credential_spec) > 1:
            raise errors.InvalidArgument(
                'credentialspec_file and credentialspec_registry are mutually'
                ' exclusive'
            )

        selinux_context = {
            'Disable': selinux_disable,
            'User': selinux_user,
            'Role': selinux_role,
            'Type': selinux_type,
            'Level': selinux_level,
        }

        if len(credential_spec) > 0:
            self['CredentialSpec'] = credential_spec

        if len(selinux_context) > 0:
            self['SELinuxContext'] = selinux_context


class NetworkAttachmentConfig(dict):
    """
        Network attachment options for a service.

        Args:
            target (str): The target network for attachment.
                Can be a network name or ID.
            aliases (:py:class:`list`): A list of discoverable alternate names
                for the service.
            options (:py:class:`dict`): Driver attachment options for the
                network target.
    """
    def __init__(self, target, aliases=None, options=None):
        self['Target'] = target
        self['Aliases'] = aliases
        self['DriverOpts'] = options
