# -*- 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
    """
    maas = _create_maas_client()
    try:
        return json.loads(maas.get(u'api/2.0/machines/?hostname='+hostname).read())[0]
    except IndexError:
        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
