# -*- coding: utf-8 -*-
"""
Module for handling maas calls.

:optdepends:    pyapi-maas Python adapter
:configuration: This module is not usable until the following are specified
                either in a pillar or in the minion's config file::

        maas.url: 'https://maas.domain.com/'
        maas.token: fdsfdsdsdsfa:fsdfae3fassd:fdsfdsfsafasdfsa

"""

from __future__ import absolute_import

import collections
import copy
import hashlib
import io
import json
import logging
import time
import urllib2
# Salt utils
from salt.exceptions import CommandExecutionError, SaltInvocationError

LOG = logging.getLogger(__name__)

SIZE = {
    "M": 1000000,
    "G": 1000000000,
    "T": 1000000000000,
}

RAID = {
    0: "raid-0",
    1: "raid-1",
    5: "raid-5",
    10: "raid-10",
}

# Import third party libs
try:
    import netaddr
    HAS_NETADDR = True
except ImportError:
    HAS_NETADDR = False

try:
    from maas_client import MAASClient, MAASDispatcher, MAASOAuth
    HAS_MASS = True
except ImportError:
    HAS_MASS = False


def __virtual__():
    """
    Only load this module if maas-client
    is installed on this minion.
    """
    if not HAS_NETADDR:
        return False, "'netaddr' python library is unavailable"
    if not HAS_MASS:
        return False, "MaaS client library is unavailable"
    return 'maasng'


APIKEY_FILE = '/var/lib/maas/.maas_credentials'


def _format_data(data):
    class Lazy:
        def __str__(self):
            return ' '.join(['{0}={1}'.format(k, v)
                             for k, v in data.iteritems()])
    return Lazy()


def _create_maas_client(api_url=None):
    if not api_url:
        api_url = 'http://localhost:5240/MAAS'
    global APIKEY_FILE
    try:
        api_token = file(APIKEY_FILE).read().splitlines()[-1].strip()\
            .split(':')
    except:
        LOG.exception('token')
    auth = MAASOAuth(*api_token)
    dispatcher = MAASDispatcher()
    return MAASClient(auth, dispatcher, api_url)


def _get_blockdevice_id_by_name(hostname, device):

    # TODO validation
    return list_blockdevices(hostname)[device]["id"]


def _get_volume_group_id_by_name(hostname, device):

    # TODO validation
    return list_volume_groups(hostname)[device]["id"]


def _get_volume_id_by_name(hostname, volume_name, volume_group, maas_volname=True):

    if not maas_volname:
        # MAAS-like name
        volume_name = str("%s-%s" % (volume_group, volume_name))
    # TODO validation
    return get_volumes(hostname, volume_group)[volume_name]["id"]


def _get_partition_id_by_name(hostname, device, partition):

    # TODO validation
    return list_partitions(hostname, device)[partition]["id"]

def is_valid_ipv4(address):
    """Verify that address represents a valid IPv4 address.
    :param address: Value to verify
    :type address: string
    :returns: bool
    .. versionadded:: 1.1
    """
    try:
        return netaddr.valid_ipv4(address)
    except netaddr.AddrFormatError:
        return False

def is_valid_ipv6(address):
    """Verify that address represents a valid IPv6 address.
    :param address: Value to verify
    :type address: string
    :returns: bool
    .. versionadded:: 1.1
    """
    if not address:
        return False

    parts = address.rsplit("%", 1)
    address = parts[0]
    scope = parts[1] if len(parts) > 1 else None
    if scope is not None and (len(scope) < 1 or len(scope) > 15):
        return False

    try:
        return netaddr.valid_ipv6(address, netaddr.core.INET_PTON)
    except netaddr.AddrFormatError:
        return False

# MACHINE SECTION


def get_machine(hostname):
    """
    Get information aboout specified machine

    CLI Example:

    .. code-block:: bash

        salt-call maasng.get_machine server_hostname

    Error codes:
        0 : Machine not found
    """
    try:
        return list_machines()[hostname]
    except KeyError:
        return {"error":
                       { 0: "Machine not found" }
               }


def list_machines(status_filter=None):
    """
    Get list of all machines from maas server

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_machines
        salt 'maas-node' maasng.list_machines status_filter=[Deployed,Ready]
    """
    machines = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/machines/').read())
    for item in json_res:
        if not status_filter or item['status_name'] in status_filter:
            machines[item["hostname"]] = item
    return machines


def create_machine():
    # TODO

    return False


def update_machine():
    # TODO

    return False

def delete_machine(hostname):
    """
    Delete specified machine

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_machine server_hostname
        salt-call maasng.delete_machine server_hostname
    """
    result = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.debug('delete_machine: {}'.format(system_id))
    maas.delete(
        u"api/2.0/machines/{0}/".format(system_id)).read()

    result["new"] = "Machine {0} deleted".format(hostname)
    return result

def machine_power_state(hostname):
    """
    Query the power state of a node.

    :param hostname: Node hostname

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.machine_power_state kvm06

    """
    result = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.debug('action_machine: {}'.format(system_id))

    # TODO validation
    json_res = json.loads(maas.get(
        u"api/2.0/machines/{0}/".format(system_id), "query_power_state").read())
    LOG.info(json_res)

    return json_res

def action_machine(hostname, action, comment=None):
    """
    Send simple action (e.g. mark_broken, mark_fixed) to machine.

    :param action:  Action to send for machine (one of MaaS' op codes)
    :param comment: Optional comment for the event log.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.action_machine server_hostname mark_broken comment='dead'
    """
    result = {}
    data = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.debug('action_machine: {}'.format(system_id))

    # TODO validation
    if comment:
        data["comment"] = comment
    json_res = json.loads(maas.post(
        u"api/2.0/machines/{0}/".format(system_id), action, **data).read())
    LOG.info(json_res)
    result["new"] = "Machine {0} action {1} executed".format(hostname, action)

    return result

# END MACHINE SECTION
# RAID SECTION


def create_raid(hostname, name, level, disks=[], partitions=[], **kwargs):
    """
    Create new raid on machine.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.create_raid hostname=kvm03 name=md0 level=1 disks=[vdb,vdc] partitions=[vdd-part1,vde-part1]
    """

    result = {}

    if len(disks) == 0 and len(partitions) == 0:
        result["error"] = "Disks or partitions need to be provided"

    disk_ids = []
    partition_ids = []

    for disk in disks:
        try:
            disk_ids.append(str(_get_blockdevice_id_by_name(hostname, disk)))
        except KeyError:
            result["error"] = "Device {0} does not exists on machine {1}".format(
                disk, hostname)
            return result

    for partition in partitions:
        try:
            device = partition.split("-")[0]
            device_part = list_partitions(hostname, device)
            partition_ids.append(str(device_part[partition]["id"]))
        except KeyError:
            result["error"] = "Partition {0} does not exists on machine {1}".format(
                partition, hostname)
            return result

    data = {
        "name": name,
        "level": RAID[int(level)],
        "block_devices": disk_ids,
        "partitions": partition_ids,
    }

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    # TODO validation
    LOG.info(data)
    json_res = json.loads(
        maas.post(u"api/2.0/nodes/{0}/raids/".format(system_id), None, **data).read())
    LOG.info(json_res)
    result["new"] = "Raid {0} created".format(name)

    return result


def list_raids(hostname):
    """
    Get list all raids on machine

    CLI Example:

    .. code-block:: bash

        salt-call maasng.list_raids server_hostname
    """

    raids = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    # TODO validation
    json_res = json.loads(
        maas.get(u"api/2.0/nodes/{0}/raids/".format(system_id)).read())
    LOG.debug('list_raids:{} {}'.format(system_id, json_res))
    for item in json_res:
        raids[item["name"]] = item
    return raids


def get_raid(hostname, name):
    """
    Get information about specific raid on machine

    CLI Example:

    .. code-block:: bash

        salt-call maasng.get_raids server_hostname md0
    """

    return list_raids(hostname)[name]


def _get_raid_id_by_name(hostname, raid_name):
    return get_raid(hostname, raid_name)['id']


def delete_raid(hostname, raid_name):
    """
    Delete RAID on a machine.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_raid server_hostname raid_name
        salt-call maasng.delete_raid server_hostname raid_name
    """
    result = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    raid_id = _get_raid_id_by_name(hostname, raid_name)
    LOG.debug('delete_raid: {} {}'.format(system_id, raid_id))
    maas.delete(
        u"api/2.0/nodes/{0}/raid/{1}/".format(system_id, raid_id)).read()

    result["new"] = "Raid {0} deleted".format(raid_name)
    return result

# END RAID SECTION
# BLOCKDEVICES SECTION


def list_blockdevices(hostname):
    """
    Get list of all blockdevices (disks) on machine

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_blockdevices server_hostname
        salt-call maasng.list_blockdevices server_hostname
    """
    ret = {}

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    # TODO validation if exists

    json_res = json.loads(
        maas.get(u"api/2.0/nodes/{0}/blockdevices/".format(system_id)).read())
    LOG.info(json_res)
    for item in json_res:
        ret[item["name"]] = item

    return ret


def get_blockdevice(hostname, name):
    """
    Get information about blockdevice (disk) on machine

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_blockdevice server_hostname sda
        salt-call maasng.get_blockdevice server_hostname sda
    """

    return list_blockdevices(hostname)[name]

# END BLOCKDEVICES SECTION
# PARTITIONS


def list_partitions(hostname, device):
    """
    Get list of all partitions on specific device located on specific machine

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_partitions server_hostname sda
        salt-call maasng.list_partitions server_hostname sda
    """
    ret = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    partitions = get_blockdevice(hostname, device)["partitions"]
    LOG.info(partitions)

    #json_res = json.loads(maas.get(u"api/2.0/nodes/{0}/blockdevices/{1}/partitions/".format(system_id, device_id)).read())
    # LOG.info(json_res)

    if len(device) > 0:
        for item in partitions:
            name = item["path"].split('/')[-1]
            ret[name] = item

    return ret


def get_partition(hostname, device, partition):
    """
    Get information about specific parition on device located on machine

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_partition server_hostname disk_name partition
        salt-call maasng.get_partition server_hostname disk_name partition

        root_size = size in GB
    """

    return list_partitions(partition)[name]


def create_partition(hostname, disk, size, fs_type=None, mount=None, mount_options=None):
    """
    Create new partition on device.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_partition server_hostname disk_name 10 ext4 "/"
        salt-call maasng.create_partition server_hostname disk_name 10 ext4 "/"
    """
    # TODO validation
    result = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    device_id = _get_blockdevice_id_by_name(hostname, disk)
    LOG.info(device_id)

    value, unit = size[:-1], size[-1]
    calc_size = str(int(value) * SIZE[unit])
    LOG.info(calc_size)

    data = {
        "size": calc_size
    }

    # TODO validation
    partition = json.loads(maas.post(
        u"api/2.0/nodes/{0}/blockdevices/{1}/partitions/".format(system_id, device_id), None, **data).read())
    LOG.info(partition)
    result["partition"] = "Partition created on {0}".format(disk)

    if fs_type != None:
        data_fs_type = {
            "fstype": fs_type
        }
        partition_id = str(partition["id"])
        LOG.info("Partition id: " + partition_id)
        # TODO validation
        json_res = json.loads(maas.post(u"api/2.0/nodes/{0}/blockdevices/{1}/partition/{2}".format(
            system_id, device_id, partition_id), "format", **data_fs_type).read())
        LOG.info(json_res)
        result["filesystem"] = "Filesystem {0} created".format(fs_type)

    if mount != None:
        data = {
            "mount_point": mount
        }
        if mount_options:
            data["mount_options"] = mount_options

        # TODO validation
        json_res = json.loads(maas.post(u"api/2.0/nodes/{0}/blockdevices/{1}/partition/{2}".format(
            system_id, device_id, str(partition['id'])), "mount", **data).read())
        LOG.info(json_res)
        result["mount"] = "Mount point {0} created".format(mount)

    return result


def list_dnsresources():
    """
    List DNS resources known to MAAS.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.list_dnsresources

    """
    result = {}
    res_json = []
    maas = _create_maas_client()

    # TODO validation
    result = json.loads(maas.get(u"api/2.0/dnsresources/").read())
    for elem in result:
        ip_addresses = []
        for ip in elem["ip_addresses"]:
            ip_addresses.append(ip["ip"])
        res_json.append(
            {
                "ip_addresses": ip_addresses,
                "id": elem["id"],
                "fqdn": elem["fqdn"],
                "hostname": elem["fqdn"].split(".")[0]
            }
        )

    LOG.debug(res_json)

    return res_json


def list_ipaddresses():
    """
    List IP addresses known to MAAS.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.list_ipaddresses

    """
    result = {}
    res_json = []
    maas = _create_maas_client()

    # TODO validation
    result = json.loads(maas.get(u"api/2.0/ipaddresses/?all").read())
    for elem in result:
        res_json.append(
            {
                "ip": elem["ip"],
                "owner": { "username": elem["owner"]["username"] },
                "created": elem["created"],
                "alloc_type_name": elem["alloc_type_name"],
                "alloc_type": elem["alloc_type"],
                "subnet": {
                    "id": elem["subnet"]["id"],
                    "cidr": elem["subnet"]["cidr"],
                    "name": elem["subnet"]["name"]
                }
            }
        )

    LOG.debug(res_json)

    return res_json


def reserve_ipaddress(hostname,subnet,ip=""):
    """
    Reserve IP address for specified hostname in specified subnet

    CLI Example:

    .. code-block:: bash

        salt-call maasng.reserve_ipaddress hostname 192.168.0.0/24 192.168.0.254
        salt-call maasng.reserve_ipaddress hostname 192.168.0.0/24

    """
    result = {}
    data = {}
    maas = _create_maas_client()

    data = {
        "subnet": subnet,
        "hostname": hostname
    }

    if ip:
        data["ip"] = ip

    # TODO validation
    result = json.loads(maas.post(u"api/2.0/ipaddresses/", "reserve", **data).read())
    res_json = {
                   "created": result["created"],
                   "type": "DNS",
                   "hostname": hostname,
                   "ip": result["ip"]
               }

    LOG.info(res_json)

    return res_json


def release_ipaddress(ipaddress):
    """
    Release an IP address that was previously reserved by the user.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.release_ipaddress 192.168.2.10

    """
    result = {}
    data = {}
    maas = _create_maas_client()

    data = {
      "ip": ipaddress
    }

    # TODO validation
    return maas.post(u"api/2.0/ipaddresses/", "release", **data).read()


def sync_address_pool():
    """
    Manage address pool for ext_pillar.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.sync_address_pool

    """

    address_pool = __pillar__["address_pool"]
    LOG.debug("Address pool:")
    LOG.debug(address_pool)

    cluster_networks = __pillar__["cluster_networks"]
    LOG.debug("Cluster networks:")
    LOG.debug(cluster_networks)

    dnsresources = list_dnsresources()
    LOG.debug("DNS resources:")
    LOG.debug(dnsresources)

    machines = list_machines()
    LOG.debug("Machines:")
    LOG.debug(machines)

    for net in address_pool:
        if net == "external":
            continue
        for addr in address_pool[net]['pool']:
            ipaddr = address_pool[net]['pool'][addr]
            if ipaddr == "":
                LOG.debug('Releasing IP address for: ' + addr)
                release_required = False
                for elem in dnsresources:
                    if elem["hostname"] == addr:
                        release_required = True
                        ip_addresses = elem["ip_addresses"]
                if release_required:
                    for ip in ip_addresses:
                        res = release_ipaddress(ip)
                        LOG.debug(res)
                else:
                    LOG.debug('IP for ' + addr + ' already released')
            elif is_valid_ipv6(ipaddr) or is_valid_ipv4(ipaddr):
                LOG.debug('Ensure static IP address "' + ipaddr + '" for ' + addr)
                reserve_required = True
                for elem in dnsresources:
                    if elem["hostname"] == addr:
                        reserve_required = False
                for elem, elemval in machines.iteritems():
                    for iface in elemval["interface_set"]:
                        for link in iface["links"]:
                            if "ip_address" in link:
                                if link["ip_address"] == ipaddr:
                                    reserve_required = False
                if reserve_required:
                    res = reserve_ipaddress(addr, cluster_networks[net]['cidr'], ipaddr)
                    reserve_required = False
                    LOG.debug(res)
                else:
                    LOG.debug('Static IP address "' + ipaddr + '" for ' + addr + ' ensured')
            else:
                LOG.debug('Requesting IP address for' + addr)
                reserve_required = True
                for elem in dnsresources:
                    if elem["hostname"] == addr:
                        reserve_required = False
                        ip = elem["ip_addresses"][0]
                if reserve_required:
                    res = reserve_ipaddress(addr, cluster_networks[net]['cidr'])
                    LOG.debug(res)
                else:
                    LOG.debug(addr + " already has IP " + ip)

    return True


def delete_partition(hostname, disk, partition_name):
    """
    Delete partition on device.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_partition server_hostname disk_name partition_name
        salt-call maasng.delete_partition server_hostname disk_name partition_name

        root_size = size in GB
    """
    result = {}
    data = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    device_id = _get_blockdevice_id_by_name(hostname, disk)
    LOG.info(device_id)

    partition_id = _get_partition_id_by_name(hostname, disk, partition_name)

    maas.delete(u"api/2.0/nodes/{0}/blockdevices/{1}/partition/{2}".format(
        system_id, device_id, partition_id)).read()
    result["new"] = "Partition {0} deleted".format(partition_name)
    return result


def delete_partition_by_id(hostname, disk, partition_id):
    """
    Delete partition on device. Partition spefified by id of parition

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_partition_by_id server_hostname disk_name partition_id
        salt-call maasng.delete_partition_by_id server_hostname disk_name partition_id

        root_size = size in GB
    """
    result = {}
    data = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    device_id = _get_blockdevice_id_by_name(hostname, disk)
    LOG.info(device_id)

    maas.delete(u"api/2.0/nodes/{0}/blockdevices/{1}/partition/{2}".format(
        system_id, device_id, partition_id)).read()
    result["new"] = "Partition {0} deleted".format(partition_id)
    return result
# END PARTITIONS
# DISK LAYOUT


def drop_storage_schema(hostname, disk=None):
    """
    #1. Drop lv
    #2. Drop vg
    #3. Drop md # need to zero-block?
    #3. Drop part
    """

    if __opts__['test']:
        ret['result'] = None
        ret['comment'] = 'Storage schema on {0} will be removed'.format(
            hostname)
        return ret
    # TODO validation if exists
    vgs = list_volume_groups(hostname)
    for vg in vgs:
        delete_volume_group(hostname, vg)

    raids = list_raids(hostname)
    for raid in raids:
        delete_raid(hostname, raid)

    blocks = list_blockdevices(hostname)
    for block_d in blocks:
        partitions = __salt__['maasng.list_partitions'](hostname, block_d)
        for partition_name, partition in partitions.iteritems():
            LOG.info('delete partition:\n{}'.format(partition))
            __salt__['maasng.delete_partition_by_id'](
                hostname, block_d, partition["id"])


def update_disk_layout(hostname, layout, root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None):
    """
    Update disk layout. Flat or LVM layout supported.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.update_disk_layout server_hostname lvm root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None
        salt-call maasng.update_disk_layout server_hostname lvm root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None

        root_size = size in GB
    """
    result = {}
    data = {
        "storage_layout": layout,
    }

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    if layout == 'custom':
        drop_storage_schema(hostname)
        result["new"] = {
            "storage_layout": layout,
        }

        return result

    if root_size != None:
        bit_size = str(root_size * 1073741824)
        LOG.info(bit_size)
        data["root_size"] = bit_size

    if root_device != None:
        LOG.info(root_device)
        data["root_device"] = str(
            _get_blockdevice_id_by_name(hostname, root_device))

    if layout == 'lvm':
        if volume_group != None:
            LOG.info(volume_group)
            data["vg_name"] = volume_group
        if volume_name != None:
            LOG.info(volume_name)
            data["lv_name"] = volume_name
        if volume_size != None:
            vol_size = str(volume_size * 1073741824)
            LOG.info(vol_size)
            data["lv_size"] = vol_size

    # TODO validation
    json_res = json.loads(maas.post(
        u"api/2.0/machines/{0}/".format(system_id), "set_storage_layout", **data).read())
    LOG.info(json_res)
    result["new"] = {
        "storage_layout": layout,
    }

    return result

# END DISK LAYOUT
# LVM


def list_volume_groups(hostname):
    """
    Get list of all volume group on machine.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_volume_groups server_hostname
        salt-call maasng.list_volume_groups server_hostname
    """
    volume_groups = {}

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    # TODO validation if exists

    json_res = json.loads(
        maas.get(u"api/2.0/nodes/{0}/volume-groups/".format(system_id)).read())
    LOG.info(json_res)
    for item in json_res:
        volume_groups[item["name"]] = item
    # return
    return volume_groups


def get_volume_group(hostname, name):
    """
    Get information about specific volume group on machine.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_blockdevices server_hostname
        salt-call maasng.list_blockdevices server_hostname
    """
    # TODO validation that exists
    return list_volume_groups(hostname)[name]


def create_volume_group(hostname, volume_group_name, disks=[], partitions=[]):
    """
    Create new volume group on machine. Disks or partitions needs to be provided.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_volume_group volume_group_name, disks=[sda,sdb], partitions=[]
        salt-call maasng.create_volume_group server_hostname
    """
    result = {}

    data = {
        "name": volume_group_name,
    }

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    disk_ids = []
    partition_ids = []

    for disk in disks:
        p_disk = get_blockdevice(hostname, disk)
        if p_disk["partition_table_type"] == None:
            disk_ids.append(str(p_disk["id"]))
        else:
            result["error"] = "Device {0} on" \
                              "machine {1} cointains partition" \
                              "table".format(disk, hostname)
            return result

    for partition in partitions:
        try:
            device = partition.split("-")[0]
            device_part = list_partitions(hostname, device)
            partition_ids.append(str(device_part[partition]["id"]))
        except KeyError:
            result["error"] = "Partition {0} does" \
                              "not exists on " \
                              "machine {1}".format(partition, hostname)
            return result

    data["block_devices"] = disk_ids
    data["partitions"] = partition_ids
    LOG.info(partition_ids)
    LOG.info(partitions)

    # TODO validation
    json_res = json.loads(maas.post(
        u"api/2.0/nodes/{0}/volume-groups/".format(system_id), None, **data).read())
    LOG.info(json_res)
    result["new"] = "Volume group {0} created".format(json_res["name"])

    return result


def delete_volume_group(hostname, name):
    """
    Delete volume group on machine.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_volume_group server_hostname vg0
        salt-call maasng.delete_volume_group server_hostname vg0
    """

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.debug('delete_volume_group:{}'.format(system_id))

    vg_id = str(_get_volume_group_id_by_name(hostname, name))
    for vol in get_volumes(hostname, name):
        delete_volume(hostname, vol, name)

    # TODO validation
    json_res = json.loads(maas.delete(
        u"api/2.0/nodes/{0}/volume-group/{1}/".format(system_id, vg_id)).read() or 'null')
    LOG.info(json_res)

    return True


def create_volume(hostname, volume_name, volume_group, size, fs_type=None,
                  mount=None, mount_options=None):
    """
    Create volume on volume group.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_volume server_hostname volume_name, volume_group, size, fs_type=None, mount=None
        salt-call maasng.create_volume server_hostname volume_name, volume_group, size, fs_type=None, mount=None
    """

    data = {
        "name": volume_name,
    }

    value, unit = size[:-1], size[-1]
    bit_size = str(int(value) * SIZE[unit])
    LOG.info(bit_size)

    data["size"] = bit_size

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.info(system_id)

    volume_group_id = str(_get_volume_group_id_by_name(hostname, volume_group))

    LOG.info(volume_group_id)

    # TODO validation
    json_res = json.loads(maas.post(u"api/2.0/nodes/{0}/volume-group/{1}/".format(
        system_id, volume_group_id), "create_logical_volume", **data).read())
    LOG.info(json_res)

    if fs_type != None or mount != None:
        ret = create_volume_filesystem(
            hostname, volume_group + "-" + volume_name, fs_type, mount, mount_options)

    return True


def delete_volume(hostname, volume_name, volume_group):
    """
    Delete volume from volume group.
    Tips: maas always use 'volume_group-volume_name' name schema.Example: 'vg0-glusterfs'
          This function expexts same format.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.delete_volume server_hostname volume_name volume_group
        salt 'maas-node' maasng.delete_volume server_hostname vg0-vol0 vg0
        salt-call maasng.delete_volume server_hostname volume_name volume_group
    """

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    LOG.debug('delete_volume:{}'.format(system_id))

    volume_group_id = str(_get_volume_group_id_by_name(hostname, volume_group))
    volume_id = str(_get_volume_id_by_name(
        hostname, volume_name, volume_group))

    if None in [volume_group_id, volume_id]:
        return False

    data = {
        "id": volume_id,
    }

    # TODO validation
    json_res = json.loads(maas.post(u"api/2.0/nodes/{0}/volume-group/{1}/".format(
        system_id, volume_group_id), "delete_logical_volume", **data).read() or 'null')
    return True


def get_volumes(hostname, vg_name):
    """
    Get list of volumes in volume group.
    """
    volumes = {}
    _volumes = list_volume_groups(
        hostname)[vg_name].get('logical_volumes', False)
    if _volumes:
        for item in _volumes:
            volumes[item["name"]] = item
    return volumes

# END LVM


def create_volume_filesystem(hostname, device, fs_type=None, mount=None, mount_options=None):

    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]

    blockdevices_id = _get_blockdevice_id_by_name(hostname, device)
    data = {}
    if fs_type != None:
        data["fstype"] = fs_type
        # TODO validation
        json_res = json.loads(maas.post(u"/api/2.0/nodes/{0}/blockdevices/{1}/".format(
            system_id, blockdevices_id), "format", **data).read())
        LOG.info(json_res)

    if mount != None:
        data["mount_point"] = mount
        if mount_options:
            data["mount_options"] = mount_options
        # TODO validation
        json_res = json.loads(maas.post(u"/api/2.0/nodes/{0}/blockdevices/{1}/".format(
            system_id, blockdevices_id), "mount", **data).read())
        LOG.info(json_res)

    return True


def set_boot_disk(hostname, name):
    """
    Create volume on volume group.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.set_boot_disk server_hostname disk_name
        salt-call maasng.set_boot_disk server_hostname disk_name
    """
    data = {}
    result = {}
    maas = _create_maas_client()
    system_id = get_machine(hostname)["system_id"]
    blockdevices_id = _get_blockdevice_id_by_name(hostname, name)

    maas.post(u"/api/2.0/nodes/{0}/blockdevices/{1}/".format(
        system_id, blockdevices_id), "set_boot_disk", **data).read()
    # TODO validation for error response
    # (disk does not exists and node does not exists)
    result["new"] = "Disk {0} was set as bootable".format(name)

    return result

# NETWORKING


def list_fabric():
    """
    Get list of all fabric

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_fabric
    """
    fabrics = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/fabrics/').read())
    LOG.info(json_res)
    for item in json_res:
        fabrics[item["name"]] = item
    return fabrics


def check_fabric(name):
    """
    Simple check that fabric already defined
    Return format:
    update  - require update
    correct - fully coincides # not implemented
    not_exist  - need's to be created
    """

    ret = 'not_exist'
    fabrics = list_fabric()
    if name in fabrics.keys():
        LOG.debug("Requested fabrics with  name:{} already exist".format(name))
        ret = 'update'
    return ret


def check_fabric_guess_with_cidr(name, cidrs):
    """
     Check, that fabric  already defined OR it was autodiscovered
     WA to fix issue with hardcoded 'fabric-0'
     - Find all auto-discovered subnets by cidr
     - find all subnets, that SHOULD be configured to THIS subent
     Warning: most probably, will fail if some subnet defined
     to another fabric :(

    { 'update'    : ID }  - require update
    { 'correct'   : ID } - fully coincides # not implemented
    { 'not_exist' : None }  - need's to be created

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.check_fabric_guess_with_cidr name='' cidrs=[]
    """

    ret = {'not_exist': None}
    fabrics = list_fabric()
    # Simple check
    if name in fabrics:
        LOG.debug("Requested fabrics with name:{} already exist".format(name))
        f_id = fabrics[name]['id']
        ret = {'update': f_id}
    # Cidr check
    # All discovered subnets by cidr
    d_subnets = list_subnets(sort_by='cidr')
    # Check, that requested cidr already in discovered.
    # If it is - it would mean that fabric already
    # exist(fabric-0,most probably) but should be renamed.
    # Works only for first shot ;(
    # due curren-single-maas logic for 'vlan-subnet' mapping.
    # Probably, it will fail with future MAAS releases.
    for cidr in cidrs:
        if cidr in d_subnets:
            f_id = d_subnets[cidr]['vlan']['fabric_id']
            f_name = d_subnets[cidr]['vlan']['fabric']
            LOG.warning("Detected cidr:{} in fabric:{}".format(cidr, f_name))
            LOG.warning("Guessing, that fabric "
                        "with current name:{}\n should be "
                        "renamed to:{}".format(f_name, name))
            ret = {'update': f_id}
            return ret
    return ret


def create_fabric(name, description=None, fabric_id=None, update=False):
    """
    Create new fabric.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_fabric name='123'
    """
    result = {}
    data = {
        "name": name,
        "class_type": '',

    }
    if description:
        data['description'] = description

    maas = _create_maas_client()
    json_res = None
    try:
        if update:
            json_res = json.loads(
                maas.put(u"api/2.0/fabrics/{0}/".format(fabric_id),
                         **data).read())
            result["new"] = "Fabric  {0} created".format(json_res["name"])
        else:
            json_res = json.loads(
                maas.post(u"api/2.0/fabrics/", None, **data).read())
            result["changes"] = "Fabric  {0} updated".format(json_res["name"])
    except Exception as inst:
        LOG.debug("create_fabric data:{}".format(data))
        m = inst.message
        LOG.error("Message:{0}".format(m))
        result['result'] = False
        result['comment'] = 'Error creating fabric: {0}'.format(name)
        result['error'] = m
        return result
    LOG.debug("crete_fabric:{}".format(json_res))
    result['result'] = True
    return result


def list_subnets(sort_by='name'):
    """
    Get list of subnets from maas server

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_subnets
    """
    subnets = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/subnets/').read())
    for item in json_res:
        subnets[item[sort_by]] = item
    return subnets


def list_vlans(fabric, sort_by='vid'):
    """
    Get list of vlans in fabric

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_vlans fabric_name
    """
    vlans = {}
    maas = _create_maas_client()
    fabric_id = get_fabricid(fabric)

    try:
        json_res = json.loads(
            maas.get(u'api/2.0/fabrics/{0}/vlans/'.format(fabric_id)).read())
    except Exception as inst:
        m = inst.message
        LOG.error("Message:{0}".format(m))
    LOG.debug(json_res)
    for item in json_res:
        vlans[item[sort_by]] = item
    return vlans


def get_fabricid(fabric):
    """
    Get id for specific fabric

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_fabricid fabric_name
    """
    try:
        return list_fabric()[fabric]['id']
    except KeyError:
        return {"error": "Fabric not found on MaaS server"}


def check_vlan_in_fabric(fabric, vlan):
    """
    Check that VLAN exactly defined
    Return format:
    update  - require update
    correct - fully coincides # not implemented
    not_exist  - need's to be created
    """

    ret = 'not_exist'
    vlans = list_vlans(fabric)
    if vlan in vlans.keys():
        LOG.debug("Requested VLAN:{} already exist"
                  "in FABRIC:{}".format(vlan, fabric))
        ret = 'update'
    return ret


def create_vlan_in_fabric(name, fabric, vlan, description, primary_rack, mtu=1500,
                          dhcp_on=False, update=False, vlan_id="", relay_vlan=None):
    """
    Update vlan
    CLI Example:
    .. code-block:: bash
        salt 'maas-node' maasng.update_vlan name, fabric, vid, description, dhcp_on
    """
    result = {}

    data = {
        "name": name,
        "dhcp_on": str(dhcp_on),
        "description": description,
        "primary_rack": list_racks()[primary_rack]['system_id'],
    }
    if mtu:
        data['mtu'] = str(mtu)
    if relay_vlan:
        data['relay_vlan'] = str(relay_vlan)
    vlan = str(vlan)
    maas = _create_maas_client()
    fabric_id = get_fabricid(fabric)
    try:
        if update:
            # MAAS have buggy logic here. Fallowing api reference, here should
            # be passed VID - which mean, API ID for vlan.
            # Otherwise, at least for maas 2.3.3-6498-ge4db91d exactly VLAN
            # should be passed. so, make temp.backward-convertation.
            # json_res = json.loads(maas.put(u'api/2.0/fabrics/{0}/vlans/{1}/'.format(fabric_id,vlan_id), **data).read())
            json_res = json.loads(maas.put(
                u'api/2.0/fabrics/{0}/vlans/{1}/'.format(fabric_id, vlan),
                **data).read())
        else:
            data['vid'] = str(vlan)
            json_res = json.loads(maas.post(
                u'api/2.0/fabrics/{0}/vlans/'.format(fabric_id), None, **data).read())
    except Exception as inst:
        LOG.debug("create_vlan_in_fabric data:{}".format(data))
        m = inst.message
        LOG.error("Message:{0}".format(m))
        result['result'] = False
        result['comment'] = 'Error updating vlan: {0}'.format(name)
        result['error'] = m
        return result
    LOG.debug("create_vlan_in_fabric:{}".format(json_res))
    result["new"] = "Vlan {0} was updated".format(json_res["name"])

    return result


def check_subnet(cidr, name, fabric, gateway_ip):
    """
    Check that subnet exactly defined
    Return format:
    update  - require update
    correct - fully coincides # not implemented
    not_exist  - need's to be created
    """

    ret = 'not_exist'
    subnets = list_subnets(sort_by='cidr')
    if cidr in subnets.keys():
        LOG.debug("Requested subnet cidr:{} already exist".format(cidr))
        ret = 'update'
    return ret


def create_subnet(cidr='', name='', fabric='', gateway_ip='', vlan='',
                  update=False, subnet_id=''):
    """
    Create subnet

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_subnet cidr, name, fabric, gateway_ip
    """

    fabric_id = get_fabricid(fabric)
    result = {}
    vlan = str(vlan)
    data = {
        "cidr": cidr,
        "name": name,
        "fabric": str(fabric_id),
        "gateway_ip": gateway_ip,
        'vlan': vlan,
    }
    maas = _create_maas_client()
    # FIXME: vlan definition not work in 2.3.3-6498-ge4db91d.
    LOG.warning("Ignoring parameter vlan:{}".format(vlan))
    data.pop('vlan', '')
    try:
        if update:
            json_res = json.loads(
                maas.put(u"api/2.0/subnets/{0}/".format(subnet_id), **data).read())
        else:
            json_res = json.loads(
                maas.post(u"api/2.0/subnets/", None, **data).read())
    except Exception as inst:
        LOG.debug("create_subnet data:{}".format(data))
        m = inst.message
        LOG.error("Message:{0}".format(m))
        result['result'] = False
        result['comment'] = 'Error creating subnet: {0}'.format(name)
        result['error'] = m
        return result
    LOG.debug("create_subnet:{}".format(json_res))
    result["new"] = "Subnet {0} with CIDR {1}" \
                    "and gateway {2} was created".format(
                        name, cidr, gateway_ip)

    return result


def get_subnet(subnet):
    """
    Get details for specific subnet

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_subnet subnet_name
    """
    try:
        return list_subnets()[subnet]
    except KeyError:
        return {"error": "Subnet not found on MaaS server"}


def get_subnetid(subnet):
    """
    Get id for specific subnet

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_subnetid subnet_name
    """
    try:
        return list_subnets()[subnet]['id']
    except KeyError:
        return {"error": "Subnet not found on MaaS server"}


def list_ipranges():
    """
    Get list of all ipranges from maas server

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_ipranges
    """
    ipranges = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/ipranges/').read())
    for item in json_res:
        ipranges[item["start_ip"]] = item
    return ipranges


def create_iprange(type_range, start_ip, end_ip, subnet=None, comment=None):
    """
    Create ip range

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.create_iprange type, start ip, end ip, comment
    """
    result = {}

    data = {
        "type": type_range,
        "start_ip": start_ip,
        "end_ip": end_ip,
    }
    if comment:
        data['comment'] = comment
    if subnet:
        subnet_id = list_subnets()[subnet]['id']
        data['subnet'] = str(subnet_id)
    maas = _create_maas_client()
    _name = "Type:{}: {}-{}".format(type_range, start_ip, end_ip)
    try:
        json_res = json.loads(
            maas.post(u"api/2.0/ipranges/", None, **data).read())
    except Exception as inst:
        m = inst.message
        LOG.error("Message:{0}".format(m))
        result['result'] = False
        result['comment'] = 'Error creating iprange:{0}'.format(_name)
        result['error'] = m
        return result
    result["new"] = "Iprange: {0} has been created".format(_name)
    LOG.debug("create_iprange:{}".format(json_res))

    return result


def get_iprangeid(start_ip):
    """
    Get id for ip range from maas server

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_iprangeid start_ip
    """
    try:
        return list_ipranges()[start_ip]['id']
    except KeyError:
        return {"error": "Ip range not found on MaaS server"}


def get_startip(start_ip):
    """
    Get start ip for ip range

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_startip start ip
    """
    try:
        return list_ipranges()[start_ip]
    except KeyError:
        return {"error": "Ip range not found on MaaS server"}
# END NETWORKING

# MAAS CONFIG SECTION


def _getHTTPCode(url):
    code = '003'
    m = ''
    try:
        connection = urllib2.urlopen(url)
        code = connection.getcode()
        connection.close()
    except (urllib2.HTTPError, urllib2.URLError) as e:
        try:
            code = e.getcode()
        except:
            m = e.reason
            pass
        LOG.debug("Unexpected http code:{} from "
                  "url:{}\nwith message:{}".format(code, url, m))
        pass
    return code


def wait_for_http_code(url=None, expected=[200]):
    """
    Simple function, which just wait for avaible api, aka wait for 200.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.wait_for_http_code url expected=[200]

    """
    ret = {}
    started_at = time.time()
    poll_time = 5
    timeout = 60 * 2
    while _getHTTPCode(url) not in expected:
        c_timeout = timeout - (time.time() - started_at)
        if c_timeout <= 0:
            ret['result'] = False
            ret["comment"] = "api:{} not answered in time".format(url)
            return ret
        LOG.info(
            "Waiting for api:{0}\n"
            "sleep for:{1}s "
            "Left:{2}/{3}s".format(url, poll_time, round(c_timeout),
                                   timeout))
        time.sleep(poll_time)
    ret['result'] = True
    ret["comment"] = "MAAS API:{} up.".format(url)
    return ret


def _get_boot_source_id_by_url(url):
    # FIXME: fix ret\validation
    try:
        bs_id = get_boot_source(url=url)["id"]
    except KeyError:
        return {"error": "boot-source:{0} not exist!".format(url)}
    return bs_id


def get_boot_source(url=None):
    """
    Read a boot source by url. If url not specified - return all.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_boot_source url

    """
    boot_sources = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/boot-sources/').read() or 'null')
    for item in json_res:
        boot_sources[str(item["url"])] = item
    if url:
        return boot_sources.get(url, {})
    return boot_sources


def delete_boot_source(url, bs_id=None):
    """
    Delete a boot source by url.

    CLI Example:

    .. code-block:: bash

        sal 'maas-node' maasng.delete url

    """
    result = {}
    if not bs_id:
        bs_id = _get_boot_source_id_by_url(url)
    maas = _create_maas_client()
    json_res = json.loads(maas.delete(
        u'/api/2.0/boot-sources/{0}/'.format(bs_id)).read() or 'null')
    LOG.debug("delete_boot_source:{}".format(json_res))
    result["new"] = "Boot-resource {0} deleted".format(url)
    return result


def boot_sources_delete_all_others(except_urls=[]):
    """
    Delete all boot-sources, except defined in 'except_urls' list.
    """
    result = {'changes': {}}
    maas_boot_sources = get_boot_source()
    if 0 in [len(except_urls), len(maas_boot_sources)]:
        result['result'] = None
        result["comment"] = "'except_urls' or 'maas boot-sources' for " \
                            "delete empty. No changes goinng to be."
        return result
    # FIXME: fix 'changes' accumulator
    for url in maas_boot_sources.keys():
        if url not in except_urls:
            LOG.info("Removing boot-source:{}".format(url))
            boot_resources_import(action='stop_import', wait=True)
            result["changes"] = delete_boot_source(url)
    return result


def create_boot_source(url, keyring_filename='', keyring_data='', wait=False):
    """
    Create and import maas boot-source: link to maas-ephemeral repo
    Be aware, those step will import resource to rack ctrl, but you also need to import
    them into the region!


    :param url:               The URL of the BootSource.
    :param keyring_filename:  The path to the keyring file for this BootSource.
    :param keyring_data:      The GPG keyring for this BootSource, base64-encoded data.

    """

    # TODO: not work with 'update' currently => keyring update may fail.
    result = {}

    data = {
        "url": url,
        "keyring_filename": keyring_filename,
        "keyring_data": str(keyring_data),
    }

    maas = _create_maas_client()
    if url in get_boot_source():
        result['result'] = None
        result["comment"] = "boot resource already exist"
        return result

    # NOTE: maas.post will return 400, if url already defined.
    json_res = json.loads(
        maas.post(u'api/2.0/boot-sources/', None, **data).read())
    if wait:
        LOG.debug(
            "Sleep for 5s,to get MaaS some time to process previous request")
        time.sleep(5)
        ret = boot_resources_is_importing(wait=True)
        if ret is dict:
            return ret
    LOG.debug("create_boot_source:{}".format(json_res))
    result["new"] = "boot resource {0} was created".format(json_res["url"])

    return result


def boot_resources_import(action='import', wait=False):
    """
    import/stop_import the boot resources.

    :param action:  import\stop_import
    :param wait:    True\False. Wait till process finished.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.boot_resources_import action='import'

    """
    maas = _create_maas_client()
    # Have no idea why, but usual jsonloads not work here..
    imp = maas.post(u'api/2.0/boot-resources/', action)
    if imp.code == 200:
        LOG.debug('boot_resources_import:{}'.format(imp.readline()))
        if wait:
            boot_resources_is_importing(wait=True)
        return True
    else:
        return False


def boot_resources_is_importing(wait=False):
    maas = _create_maas_client()
    result = {}
    if wait:
        started_at = time.time()
        poll_time = 5
        timeout = 60 * 15
        while boot_resources_is_importing(wait=False):
            c_timeout = timeout - (time.time() - started_at)
            if c_timeout <= 0:
                result['result'] = False
                result["comment"] = "Boot-resources import not finished in time"
                return result
            LOG.info(
                "Waiting boot-resources import done\n"
                "sleep for:{}s "
                "Left:{}/{}s".format(poll_time, round(c_timeout), timeout))
            time.sleep(poll_time)
        return json.loads(
            maas.get(u'api/2.0/boot-resources/', 'is_importing').read())
    else:
        return json.loads(
            maas.get(u'api/2.0/boot-resources/', 'is_importing').read())

#####
# def boot_sources_selections_delete_all_others(except_urls=[]):
#    """
#    """
#    result = {}
#    return result


def is_boot_source_selections_in(dict1, list1):
    """
    Check that requested boot-selection already in maas bs selections,
    if True- return bss id.
    # FIXME: those hack check doesn't look good.
    """
    for bs in list1:
        same = set(dict1.keys()) & set(bs.keys())
        if all(elem in same for elem in
               ['os', 'release', 'arches', 'subarches', 'labels']):
            LOG.debug("boot-selection in maas:{0}\n"
                      "looks same to requested:{1}".format(bs, dict1))
            return bs['id']
    return False


def get_boot_source_selections(bs_url):
    """
    Get boot-source selections.
    """
    # check for key_error!
    bs_id = _get_boot_source_id_by_url(bs_url)
    maas = _create_maas_client()
    json_res = json.loads(
        maas.get(u'/api/2.0/boot-sources/{0}/selections/'.format(bs_id)).read())
    LOG.debug(
        "get_boot_source_selections for url:{} \n{}".format(bs_url, json_res))
    return json_res


def create_boot_source_selections(bs_url, os, release, arches="*",
                                  subarches="*", labels="*", wait=True):
    """
         Create a new boot source selection for bs_url.
        :param os:        The OS (e.g. ubuntu, centos) for which to import resources.Required.
        :param release:   The release for which to import resources. Required.
        :param arches:    The architecture list for which to import resources.
        :param subarches: The subarchitecture list for which to import resources.
        :param labels:    The label lists for which to import resources.
    """

    result = {"result": True, 'name': bs_url, 'changes': None}

    data = {
        "os": os,
        "release": release,
        "arches": arches,
        "subarches": subarches,
        "labels": labels,
    }

    maas = _create_maas_client()
    bs_id = _get_boot_source_id_by_url(bs_url)
    # TODO add pre-create verify
    maas_bs_s = get_boot_source_selections(bs_url)
    if is_boot_source_selections_in(data, maas_bs_s):
        result["result"] = True
        result["comment"] = 'Requested boot-source selection ' \
                            'for {0} already exist.'.format(
            bs_url)
        return result

    # NOTE: maas.post will return 400, if url already defined.
    # Also, maas need's some time to import info about stream.
    # unfortunatly, maas don't have any call to check stream-import-info - so, we need to implement
    # at least simple retry ;(
    json_res = False
    poll_time = 5
    for i in range(0, 10):
        try:
            json_res = json.loads(
                maas.post(u'api/2.0/boot-sources/{0}/selections/'.format(bs_id), None,
                          **data).read())
        except Exception as inst:
            m = inst.message
            LOG.warning("boot_source_selections "
                        "catch error during processing. Most-probably, "
                        "streams data not imported yet.\nSleep:{}s "
                        "Retry:{}/10".format(poll_time, i))
            LOG.warning("Message:{0}".format(m))
            time.sleep(poll_time)
            continue
        break
    LOG.debug("create_boot_source_selections:{}".format(json_res))
    if not json_res:
        result["result"] = False
        result["comment"] = 'Failed to create requested boot-source selection' \
                            ' for {0}.'.format(bs_url)
        return result
    if wait:
        LOG.debug(
            "Sleep for 5s,to get MaaS some time to process previous request")
        time.sleep(5)
        ret = boot_resources_import(action='import', wait=True)
        if ret is dict:
            return ret
    result["comment"] = "boot-source selection for {0} was created".format(
        bs_url)
    result["new"] = data

    return result

# END MAAS CONFIG SECTION

# RACK CONTROLLERS SECTION


def get_rack(hostname):
    """
    Get information about specified rackd

    CLI Example:

    .. code-block:: bash

        salt-call maasng.get_rack rack_hostname
    """
    try:
        return list_racks()[hostname]
    except KeyError:
        return {"error": "rack:{} not found on MaaS server".format(hostname)}


def list_racks(sort_by='hostname'):
    """
    Get list of all rack controllers from maas server

    CLI Example:

    .. code-block:: bash

        salt-call maasng.list_racks
    """
    racks = {}
    maas = _create_maas_client()
    json_res = json.loads(
        maas.get(u"/api/2.0/rackcontrollers/").read() or 'null')
    for item in json_res:
        racks[item[sort_by]] = item
    return racks


def sync_bs_to_rack(hostname=None):
    """
    Sync RACK boot-sources with REGION. If no hostname probided  - sync to all.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.sync_bs_to_rack rack_hostname
    """
    ret = {}
    maas = _create_maas_client()
    if not hostname:
        LOG.info("boot-sources sync initiated for ALL Rack's")
        # Convert to json-like format
        json_res = json.loads('["{0}"]'.format(
            maas.post(u"/api/2.0/rackcontrollers/",
                      'import_boot_images').read()))
        LOG.debug("sync_bs_to_rack:{}".format(json_res))
        ret['result'] = True
        ret['comment'] = "boot-sources sync initiated for ALL Rack's"
        return ret
    LOG.info("boot-sources sync initiated for RACK:{0}".format(hostname))
    # Convert to json-like format
    json_res = json.loads('["{0}"]'.format(maas.post(
        u"/api/2.0/rackcontrollers/{0}/".format(
            get_rack(hostname)['system_id']),
        'import_boot_images').read()))
    LOG.debug("sync_bs_to_rack:{}".format(json_res))
    ret['result'] = True
    ret['comment'] = "boot-sources sync initiated for {0} Rack's".format(
        hostname)
    return


def rack_list_boot_imgs(hostname):
    ret = {}
    maas = _create_maas_client()
    LOG.debug("rack_list_boot_imgs:{}".format(hostname))
    ret = json.loads(maas.get(u"/api/2.0/rackcontrollers/{0}/".format(
        get_rack(hostname)['system_id']), 'list_boot_images').read() or 'null')
    return ret


def is_rack_synced(hostname):
    rez = rack_list_boot_imgs(hostname)['status']
    if rez == 'synced':
        return True
    return False

# TODO do we actually need _exact_ check per-pack?
# def wait_for_images_on_rack(hostname):
#
#    """
#    WA function, to be able check that RACK actually done SYNC images
#    for REQUIRED images at least.
#    Required image to be fetched from
#    reclass:maas:region:boot_sources_selections:[keys]:os/release formation
#
#    CLI Example:
#
#    .. code-block:: bash
#
#        salt-call maasng.wait_for_sync_bs_to_rack rack_hostname
#    """
#    try:
#        bss = __salt__['config.get']('maas')['region']['boot_sources_selections']
#    except KeyError:
#        ret['result'] = None
#        ret['comment'] = "boot_sources_selections definition for sync not found."
#        return ret
#    s_names = []
#    # Format  u'name': u'ubuntu/xenial'
#    for v in bss.values():s_names.append("{0}/{1}".format(v['os'],v['release']))
#    # Each names, should be in rack and whole rack should be in  sync-ed state


def sync_and_wait_bs_to_all_racks():
    """
    Sync ALL rack's with regions source images.

    CLI Example:

    .. code-block:: bash

        salt-call maasng.sync_and_wait_bs_to_all_racks
    """
    sync_bs_to_rack()
    for rack in list_racks().keys():
        wait_for_sync_bs_to_rack(hostname=rack)
    return True


def wait_for_sync_bs_to_rack(hostname=None):
    """
    Wait for boot images sync finished, on exact rack

    CLI Example:

    .. code-block:: bash

        salt-call maasng.wait_for_sync_bs_to_rack rack_hostname
    """
    ret = {}
    started_at = time.time()
    poll_time = 5
    timeout = 60 * 15
    while not is_rack_synced(hostname):
        c_timeout = timeout - (time.time() - started_at)
        if c_timeout <= 0:
            ret['result'] = False
            ret[
                "comment"] = "Boot-resources sync on rackd:{0}" \
                             "not finished in time".format(
                hostname)
            return ret
        LOG.info(
            "Waiting boot-resources sync done to rack:{0}\n"
            "sleep for:{1}s "
            "Left:{2}/{3}s".format(hostname, poll_time, round(c_timeout),
                                   timeout))
        time.sleep(poll_time)
    ret['result'] = is_rack_synced(hostname)
    ret["comment"] = "Boot-resources sync on rackd:{0} finished".format(
        hostname)
    return ret

# END RACK CONTROLLERS SECTION
# SSHKEYS


def list_sshkeys():
    """
    Get list of all sshkeys

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.list_sshkeys
        salt-call maasng.list_sshkeys
    """
    ssh = {}
    maas = _create_maas_client()
    json_res = json.loads(maas.get(u'api/2.0/account/prefs/sshkeys/').read())
    LOG.info(json_res)
    for item in json_res:
        ssh[item["key"]] = item
    return ssh


def add_sshkey(sshkey):
    """
    Add SSH key for user to MAAS.

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.add_sshkey sshkey
        salt-call maasng.add_sshkey sshkey
    """
    data = {
        "key": sshkey,
    }
    result = {}
    maas = _create_maas_client()

    maas.post(u"/api/2.0/account/prefs/sshkeys/", None, **data).read()
    result["new"] = "SSH Key {0} was added.".format(sshkey)

    return result


def get_sshkey(sshkey):
    """
    Get start ip for ip range

    CLI Example:

    .. code-block:: bash

        salt 'maas-node' maasng.get_sshkey sshkey
        salt-call maasng.get_sshkey sshkey
    """
    try:
        return list_sshkeys()[sshkey]
    except KeyError:
        return {"error": "SSH key not found on MaaS server"}
# END SSHKEYS
