Refactor fabric|subnet|vlan|ranges
* return human-readable error in multiply plases
by default - just return 400
* fix passing 'primary_rack' into update_vlan command
maas_name != rack_controller name
And even more:
type primary_rack system_id != system name!
But,disabling thise - since not work in '2.3.3-6498-ge4db91d'
* fix vlan
VID != VLAN. Even if this logic partially broken in maas
* Fabrics:
fix ordering, since in case of creating subnet with VLAN
- create fabric
- create subnet with ranges and vid
- update fabric to provide DHCP
* ipranges: remove unneeded 'multiple' behaviour
Closes-Bug: PROD-21123 (PROD:21123)
Change-Id: I24c946882cdaf6d92e38d0ce79576a830fe1978f
diff --git a/README.rst b/README.rst
index 5a7429e..c8556ab 100644
--- a/README.rst
+++ b/README.rst
@@ -46,18 +46,37 @@
user: mirantis
token: "89EgtWkX45ddjMYpuL:SqVjxFG87Dr6kVf4Wp:5WLfbUgmm9XQtJxm3V2LUUy7bpCmqmnk"
fabrics:
- test-fabric1:
+ fabric1:
+ name: 'tf2'
description: "Test fabric"
- test-fabric2:
+ fabric2:
+ name: 'tf2'
description: "Test fabric2"
+ deploy_network:
+ name: 'deploy_network'
+ description: Fabric for deploy_network
+ vlans:
+ 0:
+ name: 'vlan 0'
+ description: Deploy VLAN
+ dhcp: true
+ primary_rack: "${linux:network:hostname}"
+
subnets:
subnet1:
- fabric: test-fabric1
+ fabric: ${maas:region:fabrics:deploy_network:name}
cidr: 2.2.3.0/24
gateway_ip: 2.2.3.2
- iprange: # reserved range for DHCP\auto mapping
- start: 2.2.3.20
- end: 2.2.3.250
+ vlan: 150
+ ipranges:
+ 1:
+ end: "2.2.3.40"
+ start: "2.2.3.20"
+ type: dynamic
+ 2:
+ end: "2.2.3.250"
+ start: "2.2.3.45"
+ type: static
dhcp_snippets:
test-snippet:
value: option bootfile-name "tftp://192.168.0.10/snippet";
@@ -169,38 +188,6 @@
sshprefs:
- 'ssh-rsa ASD.........dfsadf blah@blah'
-Multiple ip ranges for one particular subnet.
-
-.. code-block:: yaml
-
- maas:
- region:
- subnets:
- Subnet1:
- cidr: 10.10.0.0/16
- fabric: fabric-5
- gateway_ip: 10.10.0.1
- iprange:
- start: 10.10.191.241
- end: 10.10.255.244
- type: reserved
- Subnet2:
- cidr: 130.10.0.0/16
- fabric: fabric-6
- gateway_ip: 130.10.0.1
- multiple: True
- iprange:
- range1:
- start: 130.10.0.10
- end: 130.10.0.15
- type: dynamic
- comment: 'Coment 1'
- range2:
- start: 130.10.0.16
- end: 130.10.0.20
- type: reserved
- comment: 'Comment 2'
-
Update Vlan
diff --git a/_modules/maasng.py b/_modules/maasng.py
index c93f8ab..128457a 100644
--- a/_modules/maasng.py
+++ b/_modules/maasng.py
@@ -19,7 +19,6 @@
import io
import json
import logging
-import os.path
import time
import urllib2
# Salt utils
@@ -669,8 +668,9 @@
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)
+ result["error"] = "Device {0} on" \
+ "machine {1} cointains partition" \
+ "table".format(disk, hostname)
return result
for partition in partitions:
@@ -679,8 +679,9 @@
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)
+ result["error"] = "Partition {0} does" \
+ "not exists on " \
+ "machine {1}".format(partition, hostname)
return result
data["block_devices"] = disk_ids
@@ -725,7 +726,8 @@
return True
-def create_volume(hostname, volume_name, volume_group, size, fs_type=None, mount=None):
+def create_volume(hostname, volume_name, volume_group, size, fs_type=None,
+ mount=None):
"""
Create volume on volume group.
@@ -861,7 +863,8 @@
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)
+ # 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
@@ -888,7 +891,73 @@
return fabrics
-def create_fabric(name):
+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, fabric_id, description, update=False):
"""
Create new fabric.
@@ -896,61 +965,85 @@
.. code-block:: bash
- salt 'maas-node' maasng.create_fabric
+ salt 'maas-node' maasng.create_fabric name='123'
"""
result = {}
data = {
"name": name,
- "description": '',
"class_type": '',
}
+ if description:
+ data['description'] = description
maas = _create_maas_client()
- json_res = json.loads(maas.post(u"api/2.0/fabrics/", None, **data).read())
+ 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["new"] = "Fabrics {0} created".format(json_res["name"])
+ result['result'] = True
return result
-def list_subnet():
+def list_subnets(sort_by='name'):
"""
- Get list of all subnets
+ Get list of subnets from maas server
CLI Example:
.. code-block:: bash
- salt 'maas-node' maasng.list_subnet
+ salt 'maas-node' maasng.list_subnets
"""
subnets = {}
maas = _create_maas_client()
json_res = json.loads(maas.get(u'api/2.0/subnets/').read())
- LOG.info(json_res)
for item in json_res:
- subnets[item["name"]] = item
+ subnets[item[sort_by]] = item
return subnets
-def list_vlans(fabric):
+def list_vlans(fabric, sort_by='vid'):
"""
- Get list of all vlans for specific fabric
+ Get list of vlans in fabric
CLI Example:
.. code-block:: bash
- salt 'maas-node' maasng.list_vlans
+ salt 'maas-node' maasng.list_vlans fabric_name
"""
vlans = {}
maas = _create_maas_client()
fabric_id = get_fabricid(fabric)
- json_res = json.loads(
- maas.get(u'api/2.0/fabrics/{0}/vlans/'.format(fabric_id)).read())
- LOG.info(json_res)
+ 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["name"]] = item
+ vlans[item[sort_by]] = item
return vlans
@@ -970,7 +1063,26 @@
return {"error": "Frabic not found on MaaS server"}
-def update_vlan(name, fabric, vid, description, primary_rack, dhcp_on=False):
+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,
+ dhcp_on=False, update=False, vlan_id=""):
"""
Update vlan
CLI Example:
@@ -985,36 +1097,62 @@
"description": description,
"primary_rack": primary_rack,
}
+ vlan = str(vlan)
+ # FIXME: primary_rack definition not work in 2.3.3-6498-ge4db91d.
+ # Use default, auto-select:
+ LOG.warning("Ignoring parameter primary_rack:{}".format(primary_rack))
+ data.pop('primary_rack', '')
maas = _create_maas_client()
fabric_id = get_fabricid(fabric)
-
- json_res = json.loads(maas.put(
- u'api/2.0/fabrics/{0}/vlans/{1}/'.format(fabric_id, vid), **data).read())
- LOG.debug("update_vlan:{}".format(json_res))
+ 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 list_subnets():
+def check_subnet(cidr, name, fabric, gateway_ip):
"""
- Get list of subnet from maas server
-
- CLI Example:
-
- .. code-block:: bash
-
- salt 'maas-node' maasng.list_subnet
+ Check that subnet exactly defined
+ Return format:
+ update - require update
+ correct - fully coincides # not implemented
+ not_exist - need's to be created
"""
- subnets = {}
- maas = _create_maas_client()
- json_res = json.loads(maas.get(u'api/2.0/subnets/').read())
- for item in json_res:
- subnets[item["name"]] = item
- return subnets
+
+ 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):
+def create_subnet(cidr='', name='', fabric='', gateway_ip='', vlan='',
+ update=False, subnet_id=''):
"""
Create subnet
@@ -1027,19 +1165,37 @@
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()
-
- json_res = json.loads(maas.post(u"api/2.0/subnets/", None, **data).read())
+ # 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)
+ result["new"] = "Subnet {0} with CIDR {1}" \
+ "and gateway {2} was created".format(name, cidr, gateway_ip)
return result
@@ -1055,7 +1211,7 @@
salt 'maas-node' maasng.get_subnet subnet_name
"""
try:
- return list_subnet()[subnet]
+ return list_subnets()[subnet]
except KeyError:
return {"error": "Subnet not found on MaaS server"}
@@ -1071,7 +1227,7 @@
salt 'maas-node' maasng.get_subnetid subnet_name
"""
try:
- return list_subnet()[subnet]['id']
+ return list_subnets()[subnet]['id']
except KeyError:
return {"error": "Subnet not found on MaaS server"}
@@ -1094,7 +1250,7 @@
return ipranges
-def create_iprange(type_range, start_ip, end_ip, comment):
+def create_iprange(type_range, start_ip, end_ip, comment=None):
"""
Create ip range
@@ -1110,15 +1266,26 @@
"type": type_range,
"start_ip": start_ip,
"end_ip": end_ip,
- "comment": comment,
}
+ if comment:
+ data['comment'] = comment
maas = _create_maas_client()
-
- json_res = json.loads(maas.post(u"api/2.0/ipranges/", None, **data).read())
-
+ _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))
- result["new"] = "Iprange with type {0}, start ip {1}, end ip {2}, was created".format(
- type_range, start_ip, end_ip)
return result
@@ -1171,9 +1338,8 @@
except:
m = e.reason
pass
- LOG.debug(
- "Unexpected http code:{} from url:{}\n"
- "with message:{}".format(code, url, m))
+ LOG.debug("Unexpected http code:{} from "
+ "url:{}\nwith message:{}".format(code, url, m))
pass
return code
@@ -1385,16 +1551,16 @@
def is_boot_source_selections_in(dict1, list1):
"""
- Check that requested boot-selection already in maas bs selections, if True- return bss id.
+ 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}\nlooks same to requested:{1}".format(
- bs, dict1))
+ LOG.debug("boot-selection in maas:{0}\n"
+ "looks same to requested:{1}".format(bs, dict1))
return bs['id']
return False
@@ -1440,8 +1606,8 @@
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(
+ result["comment"] = 'Requested boot-source selection ' \
+ 'for {0} already exist.'.format(
bs_url)
return result
@@ -1458,7 +1624,10 @@
**data).read())
except Exception as inst:
m = inst.readlines()
- LOG.warning("boot_source_selections catch error during processing. Most-probably, streams not imported yet.Sleep:{}s\nRetry:{}/5".format(poll_time,i))
+ LOG.warning("boot_source_selections "
+ "catch error during processing. Most-probably, "
+ "streams not imported yet.\nSleep:{}s"
+ "Retry:{}/5".format(poll_time, i))
LOG.warning("Message:{0}".format(m))
time.sleep(poll_time)
continue
@@ -1466,8 +1635,8 @@
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)
+ result["comment"] = 'Failed to create requested boot-source selection' \
+ ' for {0}.'.format(bs_url)
return result
if wait:
LOG.debug(
diff --git a/_states/maasng.py b/_states/maasng.py
index 35aaa45..c381a18 100644
--- a/_states/maasng.py
+++ b/_states/maasng.py
@@ -18,9 +18,9 @@
def __virtual__():
- '''
+ """
Load MaaSng module
- '''
+ """
return 'maasng'
@@ -225,8 +225,8 @@
machine = __salt__['maasng.get_machine'](hostname)
if "error" in machine:
- ret['comment'] = "State execution failed for machine {0}".format(
- hostname)
+ ret['comment'] = "State execution" \
+ "failed for machine {0}".format(hostname)
ret['result'] = False
ret['changes'] = machine
return ret
@@ -257,12 +257,13 @@
return ret
-def volume_present(hostname, name, volume_group_name, size, type=None, mount=None):
- '''
+def volume_present(hostname, name, volume_group_name, size, type=None,
+ mount=None):
+ """
Ensure that the disk layout does exist
:param name: The name of the cloud that should not exist
- '''
+ """
ret = {'name': hostname,
'changes': {},
@@ -309,8 +310,8 @@
machine = __salt__['maasng.get_machine'](hostname)
if "error" in machine:
- ret['comment'] = "State execution failed for machine {0}".format(
- hostname)
+ ret['comment'] = "State execution" \
+ "failed for machine {0}".format(hostname)
ret['result'] = False
ret['changes'] = machine
return ret
@@ -321,8 +322,8 @@
if __opts__['test']:
ret['result'] = None
- ret['comment'] = 'LVM volume {0} will be updated on {1}'.format(
- name, hostname)
+ ret['comment'] = 'LVM volume {0}' \
+ 'will be updated on {1}'.format(name, hostname)
# TODO disk validation if exists
@@ -331,36 +332,57 @@
return ret
-def update_vlan(name, fabric, vid, description, primary_rack, dhcp_on=False):
- '''
+def vlan_present_in_fabric(name, fabric, vlan, description='',
+ primary_rack='', dhcp_on=False):
+ """
:param name: Name of vlan
:param fabric: Name of fabric
- :param vid: Vlan id
+ :param vlan: Vlan id
:param description: Description of vlan
:param dhcp_on: State of dhcp
:param primary_rack: primary_rack
- '''
+ """
ret = {'name': fabric,
'changes': {},
'result': True,
'comment': 'Module function maasng.update_vlan executed'}
- ret["changes"] = __salt__['maasng.update_vlan'](
- name=name, fabric=fabric, vid=vid, description=description,
- primary_rack=primary_rack, dhcp_on=dhcp_on)
-
- if "error" in fabric:
- ret['comment'] = "State execution failed for fabric {0}".format(fabric)
- ret['result'] = False
- ret['changes'] = fabric
- return ret
-
if __opts__['test']:
ret['result'] = None
- ret['comment'] = 'Vlan {0} will be updated for {1}'.format(vid, fabric)
+ ret['comment'] = 'Vlan {0} will be updated for {1}'.format(vlan, fabric)
+ return ret
+ # Check, that vlan already defined
+ _rez = __salt__['maasng.check_vlan_in_fabric'](fabric=fabric,
+ vlan=vlan)
+ if _rez == 'not_exist':
+ changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
+ fabric=fabric,
+ vlan=vlan,
+ description=description,
+ primary_rack=primary_rack,
+ dhcp_on=dhcp_on)
+ ret['comment'] = 'Vlan {0} has' \
+ 'been created for {1}'.format(name, fabric)
+ elif _rez == 'update':
+ _id = __salt__['maasng.list_vlans'](fabric)[vlan]['id']
+ changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
+ fabric=fabric,
+ vlan=vlan,
+ description=description,
+ primary_rack=primary_rack,
+ dhcp_on=dhcp_on,
+ update=True,
+ vlan_id=_id)
+ ret['comment'] = 'Vlan {0} has been' \
+ 'updated for {1}'.format(name, fabric)
+ ret['changes'] = changes
+
+ if "error" in changes:
+ ret['comment'] = "State execution failed for fabric {0}".format(fabric)
+ ret['result'] = False
return ret
return ret
@@ -419,16 +441,15 @@
if __opts__['test']:
ret['result'] = None
- ret['comment'] = 'boot-source {0} selection will be updated'.format(
- bs_url)
+ ret['comment'] = 'boot-source {0}' \
+ 'selection will be updated'.format(bs_url)
maas_boot_sources = __salt__['maasng.get_boot_source']()
if bs_url not in maas_boot_sources.keys():
ret["result"] = False
- ret[
- "comment"] = 'Requested boot-source {0} not exist! Unable' \
- 'to proceed selection for it'.format(
- bs_url)
+ ret["comment"] = 'Requested boot-source' \
+ '{0} not exist! Unable' \
+ 'to proceed selection for it'.format(bs_url)
return ret
ret = __salt__['maasng.create_boot_source_selections'](bs_url,
@@ -441,7 +462,7 @@
return ret
-def iprange_present(name, type_range, start_ip, end_ip, comment):
+def iprange_present(name, type_range, start_ip, end_ip, comment=''):
'''
:param name: Name of iprange
@@ -457,25 +478,33 @@
'result': True,
'comment': 'Module function maasng.iprange_present executed'}
- start = __salt__['maasng.get_startip'](start_ip)
- if 'start_ip' in start.keys():
- if start["start_ip"] == start_ip:
+ # Check, that range already defined
+ _rez = __salt__['maasng.get_startip'](start_ip)
+ if 'start_ip' in _rez.keys():
+ if _rez["start_ip"] == start_ip:
ret['comment'] = 'Iprange {0} already exist.'.format(name)
return ret
if __opts__['test']:
ret['result'] = None
- ret['comment'] = 'Ip range {0} will be created with start ip: {1} and end ip: {2} and type {3}'.format(
- name, start_ip, end_ip, type_range)
+ ret['comment'] = 'Ip range {0} will be ' \
+ 'created with start ip: {1} ' \
+ 'and end ip: {2} and ' \
+ 'type {3}'.format(name, start_ip, end_ip, type_range)
return ret
- ret["changes"] = __salt__['maasng.create_iprange'](
- type_range=type_range, start_ip=start_ip, end_ip=end_ip, comment=comment)
-
+ changes = __salt__['maasng.create_iprange'](type_range=type_range,
+ start_ip=start_ip,
+ end_ip=end_ip, comment=comment)
+ ret["changes"] = changes
+ if "error" in changes:
+ ret['comment'] = "State execution failed for iprange {0}".format(name)
+ ret['result'] = False
+ return ret
return ret
-def subnet_present(cidr, name, fabric, gateway_ip):
+def subnet_present(cidr, name, fabric, gateway_ip, vlan):
'''
:param cidr: Cidr for subnet
@@ -490,20 +519,80 @@
'result': True,
'comment': 'Module function maasng.subnet_present executed'}
- subnet = __salt__['maasng.get_subnet'](name)
- if 'name' in subnet.keys():
- if subnet['name'] == name:
- ret['comment'] = 'Subnet {0} already exist for fabric {1}'.format(
- name, fabric)
- return ret
-
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'Subnet {0} will be created for {1}'.format(
name, fabric)
return ret
+ # Check, that subnet already defined
+ _rez = __salt__['maasng.check_subnet'](cidr, name, fabric, gateway_ip)
+ if _rez == 'not_exist':
+ changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
+ fabric=fabric,
+ gateway_ip=gateway_ip,
+ vlan=vlan)
+ ret['comment'] = 'Subnet {0} ' \
+ 'has been created for {1}'.format(name, fabric)
+ elif _rez == 'update':
+ _id = __salt__['maasng.list_subnets'](sort_by='cidr')[cidr]['id']
+ changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
+ fabric=fabric,
+ gateway_ip=gateway_ip,
+ vlan=vlan, update=True,
+ subnet_id=_id)
+ ret['comment'] = 'Subnet {0} ' \
+ 'has been updated for {1}'.format(name, fabric)
- ret["changes"] = __salt__['maasng.create_subnet'](
- cidr=cidr, name=name, fabric=fabric, gateway_ip=gateway_ip)
+ if "error" in changes:
+ ret['comment'] = "State execution failed for subnet {0}".format(name)
+ ret['result'] = False
+ ret['changes'] = changes
+ return ret
+
+ return ret
+
+
+def fabric_present(name, description):
+ """
+
+ :param name: Name of fabric
+ :param description: Name of description
+
+ """
+
+ ret = {'name': name,
+ 'changes': {},
+ 'result': True,
+ 'comment': 'Module function maasng.fabric_present executed'}
+
+ if __opts__['test']:
+ ret['result'] = None
+ ret['comment'] = 'fabric {0} will be updated for {1}'.format(vlan, name)
+ return ret
+ # All requested subnets
+ _r_subnets = __salt__['config.get']('maas').get('region', {}).get('subnets',
+ {})
+ # Assumed subnet CIDrs, expected to be in requested fabric
+ _a_subnets = [f for f in _r_subnets.keys() if
+ _r_subnets[f]['fabric'] == name]
+ _rez = __salt__['maasng.check_fabric_guess_with_cidr'](name=name,
+ cidrs=_a_subnets)
+
+ if 'not_exist' in _rez:
+ changes = __salt__['maasng.create_fabric'](name=name,
+ description=description)
+ ret['new'] = 'Fabric {0} has been created'.format(name)
+ elif 'update' in _rez:
+ f_id = _rez['update']
+ changes = __salt__['maasng.create_fabric'](name=name,
+ description=description,
+ update=True, fabric_id=f_id)
+ ret['new'] = 'Fabric {0} has been updated'.format(name)
+ ret['changes'] = changes
+
+ if "error" in changes:
+ ret['comment'] = "State execution failed for fabric {0}".format(fabric)
+ ret['result'] = False
+ return ret
return ret
diff --git a/maas/region.sls b/maas/region.sls
index 1ef61ec..c6fe233 100644
--- a/maas/region.sls
+++ b/maas/region.sls
@@ -149,12 +149,10 @@
maas_warmup:
module.run:
- name: maasng.wait_for_http_code
-{#
# FIXME
+ - url: "http://localhost:5240/MAAS"
# 405 - should be removed ,since twisted will be fixed
# Currently - api always throw 405=>500 even if request has been made with 'expected 'HEAD
-#}
- - url: "http://localhost:5240/MAAS"
- expected: [200, 405]
- require_in:
- module: maas_set_admin_password
@@ -299,53 +297,76 @@
{%- endif %}
{%- if region.get('fabrics', False) %}
-maas_fabrics:
- module.run:
- - name: maas.process_fabrics
+ {%- for _, fabric in region.fabrics.iteritems() %}
+ {% set fabric_name=fabric.get('name', _) %}
+# First, create fabrics
+# Bakward-compat.name:
+
+maas_fabrics_{{ fabric_name }}:
+ maasng.fabric_present:
+ - name: {{ fabric_name }}
+ - description: {{ fabric.get('description', '') }}
- require:
- cmd: maas_login_admin
+
+# Second, add VLAN into fabric's
+ {%- for vlan_n, data in fabric.get('vlans',{}).iteritems() %}
+maas_vlan{{ vlan_n }}_present_for_{{ fabric_name }}:
+ maasng.vlan_present_in_fabric:
+ - vlan: {{ vlan_n }}
+ - fabric: {{ fabric_name }}
+ - name: {{ data.get('name','') }}
+ - description: {{ data.description }}
+ - primary_rack: {{ data.get('primary_rack', '') }}
+ {%- endfor %}
+ {%- endfor %}
{%- endif %}
+# Create subnets
{%- if region.subnets is defined %}
-{%- for subnet_name, subnet in region.subnets.iteritems() %}
-maas_create_subnet_{{ subnet_name }}:
+ {%- for _, subnet in region.subnets.iteritems() %}
+maas_create_subnet_{{ subnet.cidr }}:
maasng.subnet_present:
- cidr: {{ subnet.cidr }}
- - name: {{ subnet_name }}
+ - name: {{ subnet.get('name','') }}
- fabric: {{ subnet.fabric }}
+ - vlan: {{ subnet.get('vlan','') }}
- gateway_ip: {{ subnet.gateway_ip }}
- require:
- cmd: maas_login_admin
{%- if region.get('fabrics', False) %}
- - module: maas_fabrics
+ - maas_fabrics_{{ subnet.fabric }}
{%- endif %}
-{%- endfor %}
-
-{%- for subnet_name, subnet in region.subnets.iteritems() %}
-{%- if subnet.get('multiple') == True %}
-{%- for range_name, iprange in subnet.get('iprange',{}).items() %}
-maas_create_ipranger_{{ range_name }}:
+# create ranges
+ {%- for _r, iprange in subnet.get('ipranges',{}).iteritems() %}
+maas_create_iprange_{{ _r }}:
maasng.iprange_present:
- - name: {{ range_name }}
+ - name: {{ iprange.get('name', _r) }}
- type_range: {{ iprange.type }}
- start_ip: {{ iprange.start }}
- end_ip: {{ iprange.end }}
- - comment: {{ iprange.comment }}
+ - comment: {{ iprange.get('comment', "") }}
- require:
- - maas_create_subnet_{{ subnet_name }}
-{%- endfor %}
-{%- else %}
-maas_create_ipranger_{{ subnet_name }}:
- maasng.iprange_present:
- - name: {{ subnet.get('cidr', []) }}
- - type_range: {{ subnet.iprange.type }}
- - start_ip: {{ subnet.iprange.start }}
- - end_ip: {{ subnet.iprange.end }}
- - comment: {{ subnet.iprange.type }}
- - require:
- - maas_create_subnet_{{ subnet_name }}
+ - maas_create_subnet_{{ subnet.cidr }}
+ {%- endfor %}
+ {%- endfor %}
{%- endif %}
-{%- endfor %}
+
+# Get back to fabrics again and enable DHCP
+{%- if region.get('fabrics', False) %}
+ {%- for _, fabric in region.fabrics.iteritems() %}
+ {%- for vlan_n, data in fabric.get('vlans',{}).iteritems() %}
+ {% set fabric_name=fabric.get('name', _) %}
+maas_vlan{{ vlan_n }}_present_for_{{ fabric_name }}_dhcp:
+ maasng.vlan_present_in_fabric:
+ - vlan: {{ vlan_n }}
+ - fabric: {{ fabric_name }}
+ - name: {{ data.get('name','') }}
+ - description: {{ data.description }}
+ - primary_rack: {{ data.get('primary_rack', '') }}
+ - dhcp_on: {{ data.get('dhcp','False') }}
+ {%- endfor %}
+ {%- endfor %}
{%- endif %}
{%- if region.get('devices', False) %}
@@ -384,21 +405,6 @@
- onlyif: /bin/false
{%- endif %}
-{%- if region.fabrics is defined %}
-{%- for fabric_name, fabric in region.fabrics.iteritems() %}
-{%- for vid, vlan in fabric.get('vlan',{}).items() %}
-maas_update_vlan_for_{{ fabric_name }}_{{ vid }}:
- maasng.update_vlan:
- - vid: {{ vid }}
- - fabric: {{ fabric_name }}
- - name: {{ vlan.get('name','') }}
- - description: {{ vlan.description }}
- - primary_rack: {{ region.maas_config.maas_name }}
- - dhcp_on: {{ vlan.get('dhcp','False') }}
-{%- endfor %}
-{%- endfor %}
-{%- endif %}
-
{%- if region.get('sshprefs', False) %}
maas_sshprefs: