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