# -*- 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
import netaddr
# 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
HAS_MASS = False
try:
    from maas_client import MAASClient, MAASDispatcher, MAASOAuth
    HAS_MASS = True
except ImportError:
    LOG.debug('Missing MaaS client module is Missing. Skipping')


def __virtual__():
    """
    Only load this module if maas-client
    is installed on this minion.
    """
    if HAS_MASS:
        return 'maasng'
    return False


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):
    """
    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
        }

        # 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):
    """
    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)

    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):

    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
        # 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))
        try:
            m = inst.readlines()
        except:
            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.readlines()
        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=""):
    """
    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)
    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))
        try:
            m = inst.readlines()
        except:
            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))
        try:
            m = inst.readlines()
        except:
            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:
        try:
            m = inst.readlines()
        except:
            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.readlines()
            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
