diff --git a/_modules/maasng.py b/_modules/maasng.py
new file mode 100644
index 0000000..f10b3bc
--- /dev/null
+++ b/_modules/maasng.py
@@ -0,0 +1,726 @@
+# -*- 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 os.path
+import time
+import urllib2
+#Salt utils
+from salt.exceptions import CommandExecutionError, SaltInvocationError
+
+LOG = logging.getLogger(__name__)
+
+SIZE = {
+    "M": 1000000,
+    "G": 1000000000,
+    "T": 1000000000000,
+}
+
+RAID = {
+    0: "raid-0",
+    1: "raid-1",
+    5: "raid-5",
+    10: "raid-10",
+}
+
+# Import third party libs
+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():
+    global APIKEY_FILE
+    try:
+        api_token = file(APIKEY_FILE).read().splitlines()[-1].strip()\
+            .split(':')
+    except:
+        LOG.exception('token')
+    auth = MAASOAuth(*api_token)
+    api_url = 'http://localhost:5240/MAAS'
+    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_partition_id_by_name(hostname, device, partition):
+
+    ##TODO validation
+    return list_partitions(hostname, device)[partition]["id"]
+
+####MACHINE SECTION
+
+def get_machine(hostname):
+    '''
+    Get information aboout specified machine
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt-call maasng.get_machine server_hostname
+    '''
+    try:
+        return list_machines()[hostname]
+    except KeyError:
+        return {"error": "Machine not found on MaaS server"}
+
+def list_machines():
+    '''
+    Get list of all machines from maas server
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt 'maas-node' maasng.list_machines
+    '''
+    machines={}
+    maas=_create_maas_client()
+    json_res = json.loads(maas.get(u'api/2.0/machines/').read())
+    for item in json_res:
+        machines[item["hostname"]] = item
+    return machines
+
+def create_machine():
+    ##TODO
+
+    return False
+
+def update_machine():
+    ##TODO
+
+    return False
+
+####MACHINE OPERATIONS
+##TODO
+
+####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
+    '''
+
+    maas=_create_maas_client()
+    system_id = get_machine(hostname)["system_id"]
+    LOG.info(system_id)
+    #TODO validation
+    json_res = json.loads(maas.get(u"api/2.0/nodes/{0}/raids/".format(system_id)).read())
+    LOG.info(json_res)
+
+    ##TODO return list of raid devices
+    return True
+
+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]
+
+
+####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]
+
+
+####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 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
+
+####CREATE DISK LAYOUT
+##TODO
+
+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 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
+
+
+####LVM
+##TODO
+
+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.info(system_id)
+
+    #TODO partitions
+    #for partition in partitions:
+    #    temp = disk.split("-")
+    #    disk_ids.append(str(_get_blockdevice_id_by_name(hostname, temp[] partition)))
+
+    #TODO partitions
+    vg_id = name
+
+    #TODO validation
+    json_res = json.loads(maas.delete(u"api/2.0/nodes/{0}/volume-group/{1}/".format(system_id, vg_id)).read())
+    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 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 create_partition_filesystem(hostname, partition, 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
