PROD-18932
Change-Id: Icdfc04a62c49027db650820f3e625efcb9a749d9
diff --git a/README.rst b/README.rst
index 2f85ea0..5a7429e 100644
--- a/README.rst
+++ b/README.rst
@@ -169,6 +169,39 @@
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
NOTE: Vid 0 has default name untagged in MaaS UI
diff --git a/_modules/maasng.py b/_modules/maasng.py
index dc8527b..54f15ae 100644
--- a/_modules/maasng.py
+++ b/_modules/maasng.py
@@ -99,8 +99,8 @@
if not maas_volname:
# MAAS-like name
- volume_name = str("%s-%s" % (volume_group,volume_name))
- ##TODO validation
+ volume_name = str("%s-%s" % (volume_group, volume_name))
+ # TODO validation
return get_volumes(hostname, volume_group)[volume_name]["id"]
@@ -233,8 +233,9 @@
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())
+ # 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
@@ -271,11 +272,12 @@
salt-call maasng.delete_raid server_hostname raid_name
"""
result = {}
- maas=_create_maas_client()
+ 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()
+ 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
@@ -497,7 +499,7 @@
# DISK LAYOUT
-def drop_storage_schema(hostname,disk=None):
+def drop_storage_schema(hostname, disk=None):
"""
#1. Drop lv
#2. Drop vg
@@ -507,9 +509,10 @@
if __opts__['test']:
ret['result'] = None
- ret['comment'] = 'Storage schema on {0} will be removed'.format(hostname)
+ ret['comment'] = 'Storage schema on {0} will be removed'.format(
+ hostname)
return ret
- #TODO validation if exists
+ # TODO validation if exists
vgs = list_volume_groups(hostname)
for vg in vgs:
delete_volume_group(hostname, vg)
@@ -523,7 +526,8 @@
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"])
+ __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):
@@ -591,6 +595,7 @@
# END DISK LAYOUT
# LVM
+
def list_volume_groups(hostname):
"""
Get list of all volume group on machine.
@@ -709,10 +714,11 @@
vg_id = str(_get_volume_group_id_by_name(hostname, name))
for vol in get_volumes(hostname, name):
- delete_volume(hostname,vol,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')
+ # 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
@@ -754,7 +760,8 @@
LOG.info(json_res)
if fs_type != None or mount != None:
- ret = create_volume_filesystem(hostname, volume_group + "-" + volume_name, fs_type, mount)
+ ret = create_volume_filesystem(
+ hostname, volume_group + "-" + volume_name, fs_type, mount)
return True
@@ -774,12 +781,13 @@
salt-call maasng.delete_volume server_hostname volume_name volume_group
"""
- maas=_create_maas_client()
+ 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))
+ volume_id = str(_get_volume_id_by_name(
+ hostname, volume_name, volume_group))
if None in [volume_group_id, volume_id]:
return False
@@ -788,8 +796,9 @@
"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')
+ # 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
@@ -798,7 +807,8 @@
Get list of volumes in volume group.
"""
volumes = {}
- _volumes = list_volume_groups(hostname)[vg_name].get('logical_volumes', False)
+ _volumes = list_volume_groups(
+ hostname)[vg_name].get('logical_volumes', False)
if _volumes:
for item in _volumes:
volumes[item["name"]] = item
@@ -897,7 +907,7 @@
maas = _create_maas_client()
json_res = json.loads(maas.post(u"api/2.0/fabrics/", None, **data).read())
- LOG.info(json_res)
+ LOG.debug("crete_fabric:{}".format(json_res))
result["new"] = "Fabrics {0} created".format(json_res["name"])
return result
@@ -933,7 +943,7 @@
"""
vlans = {}
maas = _create_maas_client()
- fabric_id = get_fabric(fabric)
+ fabric_id = get_fabricid(fabric)
json_res = json.loads(
maas.get(u'api/2.0/fabrics/{0}/vlans/'.format(fabric_id)).read())
@@ -943,7 +953,7 @@
return vlans
-def get_fabric(fabric):
+def get_fabricid(fabric):
"""
Get id for specific fabric
@@ -951,7 +961,7 @@
.. code-block:: bash
- salt-call maasng.get_fabric fabric_name
+ salt 'maas-node' maasng.get_fabricid fabric_name
"""
try:
return list_fabric()[fabric]['id']
@@ -962,11 +972,8 @@
def update_vlan(name, fabric, vid, description, primary_rack, dhcp_on=False):
"""
Update vlan
-
CLI Example:
-
.. code-block:: bash
-
salt 'maas-node' maasng.update_vlan name, fabric, vid, description, dhcp_on
"""
result = {}
@@ -978,7 +985,7 @@
"primary_rack": primary_rack,
}
maas = _create_maas_client()
- fabric_id = get_fabric(fabric)
+ 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())
@@ -987,6 +994,164 @@
return result
+
+def list_subnets():
+ """
+ Get list of subnet from maas server
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'maas-node' maasng.list_subnet
+ """
+ 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
+
+
+def create_subnet(cidr, name, fabric, gateway_ip):
+ """
+ Create subnet
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'maas-node' maasng.create_subnet cidr, name, fabric, gateway_ip
+ """
+
+ fabric_id = get_fabricid(fabric)
+ result = {}
+
+ data = {
+ "cidr": cidr,
+ "name": name,
+ "fabric": str(fabric_id),
+ "gateway_ip": gateway_ip,
+ }
+ maas = _create_maas_client()
+
+ json_res = json.loads(maas.post(u"api/2.0/subnets/", None, **data).read())
+ 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_subnet()[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_subnet()[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, comment):
+ """
+ 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,
+ "comment": comment,
+ }
+ maas = _create_maas_client()
+
+ json_res = json.loads(maas.post(u"api/2.0/ipranges/", None, **data).read())
+
+ 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
+
+
+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
@@ -1158,7 +1323,7 @@
maas.get(u'api/2.0/boot-resources/', 'is_importing').read())
#####
-#def boot_sources_selections_delete_all_others(except_urls=[]):
+# def boot_sources_selections_delete_all_others(except_urls=[]):
# """
# """
# result = {}
diff --git a/_states/maasng.py b/_states/maasng.py
index 1cc69f7..66987d2 100644
--- a/_states/maasng.py
+++ b/_states/maasng.py
@@ -1,4 +1,3 @@
-
import logging
from salt.exceptions import CommandExecutionError, SaltInvocationError
@@ -67,7 +66,8 @@
hostname, layout_type, root_size, root_device, volume_group, volume_name, volume_size)
elif layout_type == "custom":
- ret["changes"] = __salt__['maasng.update_disk_layout'](hostname, layout_type)
+ ret["changes"] = __salt__[
+ 'maasng.update_disk_layout'](hostname, layout_type)
else:
ret["comment"] = "Not supported layout provided. Choose flat or lvm"
@@ -436,3 +436,71 @@
labels=labels,
wait=wait)
return ret
+
+
+def iprange_present(name, type_range, start_ip, end_ip, comment):
+ '''
+
+ :param name: Name of iprange
+ :param type_range: Type of iprange
+ :param start_ip: Start ip of iprange
+ :param end_ip: End ip of iprange
+ :param comment: Comment for specific iprange
+
+ '''
+
+ ret = {'name': name,
+ 'changes': {},
+ '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:
+ 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)
+ return ret
+
+ ret["changes"] = __salt__['maasng.create_iprange'](
+ type_range=type_range, start_ip=start_ip, end_ip=end_ip, comment=comment)
+
+ return ret
+
+
+def subnet_present(cidr, name, fabric, gateway_ip):
+ '''
+
+ :param cidr: Cidr for subnet
+ :param name: Name of subnet
+ :param fabric: Name of fabric for subnet
+ :param gateway_ip: gateway_ip
+
+ '''
+
+ ret = {'name': name,
+ 'changes': {},
+ '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
+
+ ret["changes"] = __salt__['maasng.create_subnet'](
+ cidr=cidr, name=name, fabric=fabric, gateway_ip=gateway_ip)
+
+ return ret
diff --git a/maas/region.sls b/maas/region.sls
index b0d9516..fc57871 100644
--- a/maas/region.sls
+++ b/maas/region.sls
@@ -279,15 +279,46 @@
- cmd: maas_login_admin
{%- endif %}
-{%- if region.get('subnets', False) %}
-maas_subnets:
- module.run:
- - name: maas.process_subnets
+{%- if region.subnets is defined %}
+{%- for subnet_name, subnet in region.subnets.iteritems() %}
+maas_create_subnet_{{ subnet_name }}:
+ maasng.subnet_present:
+ - cidr: {{ subnet.cidr }}
+ - name: {{ subnet_name }}
+ - fabric: {{ subnet.fabric }}
+ - gateway_ip: {{ subnet.gateway_ip }}
- require:
- cmd: maas_login_admin
{%- if region.get('fabrics', False) %}
- module: maas_fabrics
{%- 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 }}:
+ maasng.iprange_present:
+ - name: {{ range_name }}
+ - type_range: {{ iprange.type }}
+ - start_ip: {{ iprange.start }}
+ - end_ip: {{ iprange.end }}
+ - comment: {{ iprange.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 }}
+{%- endif %}
+{%- endfor %}
{%- endif %}
{%- if region.get('devices', False) %}