blob: b71c9d9ea3396deffef2a08c249a917d3257ef94 [file] [log] [blame]
Ondrej Smolab57a23b2018-01-24 11:18:24 +01001import logging
2from salt.exceptions import CommandExecutionError, SaltInvocationError
3
4LOG = logging.getLogger(__name__)
5
6SIZE = {
7 "M": 1000000,
8 "G": 1000000000,
9 "T": 1000000000000,
10}
11
12RAID = {
13 0: "raid-0",
14 1: "raid-1",
15 5: "raid-5",
16 10: "raid-10",
17}
18
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020019
Ondrej Smolab57a23b2018-01-24 11:18:24 +010020def __virtual__():
azvyagintsevf3515c82018-06-26 18:59:05 +030021 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +010022 Load MaaSng module
azvyagintsevf3515c82018-06-26 18:59:05 +030023 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +010024 return 'maasng'
25
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020026
azvyagintsev3ff2ef12018-06-01 21:30:45 +030027def disk_layout_present(hostname, layout_type, root_size=None, root_device=None,
28 volume_group=None, volume_name=None, volume_size=None,
29 disk={}, **kwargs):
Ondrej Smolab57a23b2018-01-24 11:18:24 +010030 '''
31 Ensure that the disk layout does exist
32
33 :param name: The name of the cloud that should not exist
34 '''
35 ret = {'name': hostname,
36 'changes': {},
37 'result': True,
38 'comment': 'Disk layout "{0}" updated'.format(hostname)}
39
40 machine = __salt__['maasng.get_machine'](hostname)
41 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020042 ret['comment'] = "State execution failed for machine {0}".format(
43 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010044 ret['result'] = False
45 ret['changes'] = machine
46 return ret
47
48 if machine["status_name"] != "Ready":
49 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
50 return ret
51
52 if __opts__['test']:
53 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020054 ret['comment'] = 'Disk layout will be updated on {0}, this action will delete current layout.'.format(
55 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010056 return ret
57
58 if layout_type == "flat":
59
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020060 ret["changes"] = __salt__['maasng.update_disk_layout'](
61 hostname, layout_type, root_size, root_device)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010062
63 elif layout_type == "lvm":
64
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020065 ret["changes"] = __salt__['maasng.update_disk_layout'](
66 hostname, layout_type, root_size, root_device, volume_group, volume_name, volume_size)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010067
azvyagintsevbca1f462018-05-25 19:06:46 +030068 elif layout_type == "custom":
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +020069 ret["changes"] = __salt__[
70 'maasng.update_disk_layout'](hostname, layout_type)
azvyagintsevbca1f462018-05-25 19:06:46 +030071
Ondrej Smolab57a23b2018-01-24 11:18:24 +010072 else:
73 ret["comment"] = "Not supported layout provided. Choose flat or lvm"
74 ret['result'] = False
75
76 return ret
77
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020078
azvyagintsev3ff2ef12018-06-01 21:30:45 +030079def raid_present(hostname, name, level, devices=[], partitions=[],
80 partition_schema={}):
Ondrej Smolab57a23b2018-01-24 11:18:24 +010081 '''
82 Ensure that the raid does exist
83
84 :param name: The name of the cloud that should not exist
85 '''
86
87 ret = {'name': name,
88 'changes': {},
89 'result': True,
90 'comment': 'Raid {0} presented on {1}'.format(name, hostname)}
91
92 machine = __salt__['maasng.get_machine'](hostname)
93 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020094 ret['comment'] = "State execution failed for machine {0}".format(
95 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010096 ret['result'] = False
97 ret['changes'] = machine
98 return ret
99
100 if machine["status_name"] != "Ready":
101 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
102 return ret
103
104 if __opts__['test']:
105 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200106 ret['comment'] = 'Raid {0} will be updated on {1}'.format(
107 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100108 return ret
109
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200110 # Validate that raid exists
111 # With correct devices/partition
112 # OR
113 # Create raid
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100114
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200115 ret["changes"] = __salt__['maasng.create_raid'](
116 hostname=hostname, name=name, level=level, disks=devices, partitions=partitions)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100117
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200118 # TODO partitions
119 ret["changes"].update(disk_partition_present(
120 hostname, name, partition_schema)["changes"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100121
122 if "error" in ret["changes"]:
123 ret["result"] = False
124
125 return ret
126
127
128def disk_partition_present(hostname, disk, partition_schema={}):
129 '''
130 Ensure that the disk has correct partititioning schema
131
132 :param name: The name of the cloud that should not exist
133 '''
134
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200135 # 1. Validate that disk has correct values for size and mount
136 # a. validate count of partitions
137 # b. validate size of partitions
138 # 2. If not delete all partitions on disk and recreate schema
139 # 3. Validate type exists
140 # if should not exits
141 # delete mount and unformat
142 # 4. Validate mount exists
143 # 5. if not enforce umount or mount
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100144
145 ret = {'name': hostname,
146 'changes': {},
147 'result': True,
148 'comment': 'Disk layout {0} presented'.format(disk)}
149
150 machine = __salt__['maasng.get_machine'](hostname)
151 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200152 ret['comment'] = "State execution failed for machine {0}".format(
153 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100154 ret['result'] = False
155 ret['changes'] = machine
156 return ret
157
158 if machine["status_name"] != "Ready":
159 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
160 return ret
161
162 if __opts__['test']:
163 ret['result'] = None
164 ret['comment'] = 'Partition schema will be changed on {0}'.format(disk)
165 return ret
166
167 partitions = __salt__['maasng.list_partitions'](hostname, disk)
168
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200169 # Calculate actual size in bytes from provided data
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100170 for part_name, part in partition_schema.iteritems():
171 size, unit = part["size"][:-1], part["size"][-1]
172 part["calc_size"] = int(size) * SIZE[unit]
173
174 if len(partitions) == len(partition_schema):
175
176 for part_name, part in partition_schema.iteritems():
177 LOG.info('validated {0}'.format(part["calc_size"]))
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200178 LOG.info('validated {0}'.format(
179 int(partitions[disk+"-"+part_name.split("-")[-1]]["size"])))
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100180 if part["calc_size"] == int(partitions[disk+"-"+part_name.split("-")[-1]]["size"]):
181 LOG.info('validated')
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200182 # TODO validate size (size from maas is not same as calculate?)
183 # TODO validate mount
184 # TODO validate fs type
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100185 else:
186 LOG.info('breaking')
187 break
188 return ret
189
190 #DELETE and RECREATE
191 LOG.info('delete')
192 for partition_name, partition in partitions.iteritems():
193 LOG.info(partition)
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200194 # TODO IF LVM create ERROR
195 ret["changes"] = __salt__['maasng.delete_partition_by_id'](
196 hostname, disk, partition["id"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100197
198 LOG.info('recreating')
199 for part_name, part in partition_schema.iteritems():
200 LOG.info("partitition for creation")
201 LOG.info(part)
202 if "mount" not in part:
203 part["mount"] = None
204 if "type" not in part:
205 part["type"] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200206 ret["changes"] = __salt__['maasng.create_partition'](
207 hostname, disk, part["size"], part["type"], part["mount"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100208
209 if "error" in ret["changes"]:
210 ret["result"] = False
211
212 return ret
213
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200214
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100215def volume_group_present(hostname, name, devices=[], partitions=[]):
216 '''
217 Ensure that the disk layout does exist
218
219 :param name: The name of the cloud that should not exist
220 '''
221 ret = {'name': hostname,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200222 'changes': {},
223 'result': True,
224 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100225
226 machine = __salt__['maasng.get_machine'](hostname)
227 if "error" in machine:
azvyagintsevf3515c82018-06-26 18:59:05 +0300228 ret['comment'] = "State execution" \
229 "failed for machine {0}".format(hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100230 ret['result'] = False
231 ret['changes'] = machine
232 return ret
233
234 if machine["status_name"] != "Ready":
235 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
236 return ret
237
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200238 # TODO validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100239 vgs = __salt__['maasng.list_volume_groups'](hostname)
240
241 if name in vgs:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200242 # TODO validation for devices and partitions
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100243 return ret
244
245 if __opts__['test']:
246 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200247 ret['comment'] = 'LVM group {0} will be updated on {1}'.format(
248 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100249 return ret
250
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200251 ret["changes"] = __salt__['maasng.create_volume_group'](
252 hostname, name, devices, partitions)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100253
254 if "error" in ret["changes"]:
255 ret["result"] = False
256
257 return ret
258
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200259
azvyagintsevf3515c82018-06-26 18:59:05 +0300260def volume_present(hostname, name, volume_group_name, size, type=None,
261 mount=None):
262 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100263 Ensure that the disk layout does exist
264
265 :param name: The name of the cloud that should not exist
azvyagintsevf3515c82018-06-26 18:59:05 +0300266 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100267
268 ret = {'name': hostname,
269 'changes': {},
270 'result': True,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200271 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100272
273 machine = __salt__['maasng.get_machine'](hostname)
274 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200275 ret['comment'] = "State execution failed for machine {0}".format(
276 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100277 ret['result'] = False
278 ret['changes'] = machine
279 return ret
280
281 if machine["status_name"] != "Ready":
282 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
283 return ret
284
285 if __opts__['test']:
286 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200287 ret['comment'] = 'LVM volume {0} will be updated on {1}'.format(
288 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100289
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200290 # TODO validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100291
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200292 ret["changes"] = __salt__['maasng.create_volume'](
293 hostname, name, volume_group_name, size, type, mount)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100294
295 return ret
296
297
298def select_boot_disk(hostname, name):
299 '''
300 Select disk that will be used to boot partition
301
302 :param name: The name of disk on machine
303 :param hostname: The hostname of machine
304 '''
305
306 ret = {'name': hostname,
307 'changes': {},
308 'result': True,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200309 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100310
311 machine = __salt__['maasng.get_machine'](hostname)
312 if "error" in machine:
azvyagintsevf3515c82018-06-26 18:59:05 +0300313 ret['comment'] = "State execution" \
314 "failed for machine {0}".format(hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100315 ret['result'] = False
316 ret['changes'] = machine
317 return ret
318
319 if machine["status_name"] != "Ready":
320 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
321 return ret
322
323 if __opts__['test']:
324 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300325 ret['comment'] = 'LVM volume {0}' \
326 'will be updated on {1}'.format(name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100327
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200328 # TODO disk validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100329
330 ret["changes"] = __salt__['maasng.set_boot_disk'](hostname, name)
331
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200332 return ret
333
334
Petr Ruzicka80471852018-07-13 14:08:27 +0200335def vlan_present_in_fabric(name, fabric, vlan, primary_rack, description='', dhcp_on=False, mtu=1500):
azvyagintsevf3515c82018-06-26 18:59:05 +0300336 """
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200337
338 :param name: Name of vlan
339 :param fabric: Name of fabric
azvyagintsevf3515c82018-06-26 18:59:05 +0300340 :param vlan: Vlan id
Petr Ruzicka80471852018-07-13 14:08:27 +0200341 :param mtu: MTU
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200342 :param description: Description of vlan
343 :param dhcp_on: State of dhcp
Pavel Cizinsky864a3292018-05-25 16:24:48 +0200344 :param primary_rack: primary_rack
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200345
azvyagintsevf3515c82018-06-26 18:59:05 +0300346 """
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200347
348 ret = {'name': fabric,
349 'changes': {},
350 'result': True,
351 'comment': 'Module function maasng.update_vlan executed'}
352
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200353 if __opts__['test']:
354 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300355 ret['comment'] = 'Vlan {0} will be updated for {1}'.format(vlan, fabric)
356 return ret
357 # Check, that vlan already defined
358 _rez = __salt__['maasng.check_vlan_in_fabric'](fabric=fabric,
359 vlan=vlan)
360 if _rez == 'not_exist':
361 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
362 fabric=fabric,
363 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200364 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300365 description=description,
366 primary_rack=primary_rack,
367 dhcp_on=dhcp_on)
Michael Polenchukd25da792018-07-19 18:27:11 +0400368 ret['comment'] = 'Vlan {0} has ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300369 'been created for {1}'.format(name, fabric)
370 elif _rez == 'update':
371 _id = __salt__['maasng.list_vlans'](fabric)[vlan]['id']
372 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
373 fabric=fabric,
374 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200375 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300376 description=description,
377 primary_rack=primary_rack,
378 dhcp_on=dhcp_on,
379 update=True,
380 vlan_id=_id)
Michael Polenchukd25da792018-07-19 18:27:11 +0400381 ret['comment'] = 'Vlan {0} has been ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300382 'updated for {1}'.format(name, fabric)
383 ret['changes'] = changes
384
385 if "error" in changes:
386 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
387 ret['result'] = False
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200388 return ret
389
390 return ret
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300391
392
393def boot_source_present(url, keyring_file='', keyring_data=''):
394 """
395 Process maas boot-sources: link to maas-ephemeral repo
396
397
398 :param url: The URL of the BootSource.
399 :param keyring_file: The path to the keyring file for this BootSource.
400 :param keyring_data: The GPG keyring for this BootSource, base64-encoded data.
401 """
402 ret = {'name': url,
403 'changes': {},
404 'result': True,
405 'comment': 'boot-source {0} presented'.format(url)}
406
407 if __opts__['test']:
408 ret['result'] = None
409 ret['comment'] = 'boot-source {0} will be updated'.format(url)
410
411 maas_boot_sources = __salt__['maasng.get_boot_source']()
412 # TODO imlpement check and update for keyrings!
413 if url in maas_boot_sources.keys():
414 ret["result"] = True
415 ret["comment"] = 'boot-source {0} alredy exist'.format(url)
416 return ret
417 ret["changes"] = __salt__['maasng.create_boot_source'](url,
418 keyring_filename=keyring_file,
419 keyring_data=keyring_data)
420 return ret
421
422
423def boot_sources_selections_present(bs_url, os, release, arches="*",
424 subarches="*", labels="*", wait=True):
425 """
azvyagintsevcb54d142018-06-19 16:18:32 +0300426 Process maas boot-sources selection: set of resource configurathions,
427 to be downloaded from boot-source bs_url.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300428
429 :param bs_url: Boot-source url
azvyagintsevcb54d142018-06-19 16:18:32 +0300430 :param os: The OS (e.g. ubuntu, centos) for which to import
431 resources.Required.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300432 :param release: The release for which to import resources. Required.
433 :param arches: The architecture list for which to import resources.
434 :param subarches: The subarchitecture list for which to import resources.
435 :param labels: The label lists for which to import resources.
436 :param wait: Initiate import and wait for done.
437
438 """
439 ret = {'name': bs_url,
440 'changes': {},
441 'result': True,
442 'comment': 'boot-source {0} selection present'.format(bs_url)}
443
444 if __opts__['test']:
445 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300446 ret['comment'] = 'boot-source {0}' \
447 'selection will be updated'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300448
449 maas_boot_sources = __salt__['maasng.get_boot_source']()
450 if bs_url not in maas_boot_sources.keys():
451 ret["result"] = False
azvyagintsevf3515c82018-06-26 18:59:05 +0300452 ret["comment"] = 'Requested boot-source' \
453 '{0} not exist! Unable' \
454 'to proceed selection for it'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300455 return ret
456
azvyagintsevcb54d142018-06-19 16:18:32 +0300457 ret = __salt__['maasng.create_boot_source_selections'](bs_url,
458 os,
459 release,
460 arches=arches,
461 subarches=subarches,
462 labels=labels,
463 wait=wait)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300464 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200465
466
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300467def iprange_present(name, type_range, start_ip, end_ip, subnet=None,
468 comment=None):
469 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200470
471 :param name: Name of iprange
472 :param type_range: Type of iprange
473 :param start_ip: Start ip of iprange
474 :param end_ip: End ip of iprange
475 :param comment: Comment for specific iprange
476
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300477 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200478
479 ret = {'name': name,
480 'changes': {},
481 'result': True,
482 'comment': 'Module function maasng.iprange_present executed'}
483
azvyagintsevf3515c82018-06-26 18:59:05 +0300484 # Check, that range already defined
485 _rez = __salt__['maasng.get_startip'](start_ip)
486 if 'start_ip' in _rez.keys():
487 if _rez["start_ip"] == start_ip:
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200488 ret['comment'] = 'Iprange {0} already exist.'.format(name)
489 return ret
490
491 if __opts__['test']:
492 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300493 ret['comment'] = 'Ip range {0} will be ' \
494 'created with start ip: {1} ' \
495 'and end ip: {2} and ' \
496 'type {3}'.format(name, start_ip, end_ip, type_range)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200497 return ret
498
azvyagintsevf3515c82018-06-26 18:59:05 +0300499 changes = __salt__['maasng.create_iprange'](type_range=type_range,
500 start_ip=start_ip,
azvyagintsevf0904ac2018-07-05 18:53:26 +0300501 end_ip=end_ip,subnet=subnet, comment=comment)
azvyagintsevf3515c82018-06-26 18:59:05 +0300502 ret["changes"] = changes
503 if "error" in changes:
504 ret['comment'] = "State execution failed for iprange {0}".format(name)
505 ret['result'] = False
506 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200507 return ret
508
509
azvyagintsevf3515c82018-06-26 18:59:05 +0300510def subnet_present(cidr, name, fabric, gateway_ip, vlan):
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300511 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200512
513 :param cidr: Cidr for subnet
514 :param name: Name of subnet
515 :param fabric: Name of fabric for subnet
516 :param gateway_ip: gateway_ip
517
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300518 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200519
520 ret = {'name': name,
521 'changes': {},
522 'result': True,
523 'comment': 'Module function maasng.subnet_present executed'}
524
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200525 if __opts__['test']:
526 ret['result'] = None
527 ret['comment'] = 'Subnet {0} will be created for {1}'.format(
528 name, fabric)
529 return ret
azvyagintsevf3515c82018-06-26 18:59:05 +0300530 # Check, that subnet already defined
531 _rez = __salt__['maasng.check_subnet'](cidr, name, fabric, gateway_ip)
532 if _rez == 'not_exist':
533 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
534 fabric=fabric,
535 gateway_ip=gateway_ip,
536 vlan=vlan)
537 ret['comment'] = 'Subnet {0} ' \
538 'has been created for {1}'.format(name, fabric)
539 elif _rez == 'update':
540 _id = __salt__['maasng.list_subnets'](sort_by='cidr')[cidr]['id']
541 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
542 fabric=fabric,
543 gateway_ip=gateway_ip,
544 vlan=vlan, update=True,
545 subnet_id=_id)
546 ret['comment'] = 'Subnet {0} ' \
547 'has been updated for {1}'.format(name, fabric)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200548
azvyagintsevf3515c82018-06-26 18:59:05 +0300549 if "error" in changes:
550 ret['comment'] = "State execution failed for subnet {0}".format(name)
551 ret['result'] = False
552 ret['changes'] = changes
553 return ret
554
555 return ret
556
557
azvyagintsevf0904ac2018-07-05 18:53:26 +0300558def fabric_present(name, description=None):
azvyagintsevf3515c82018-06-26 18:59:05 +0300559 """
560
561 :param name: Name of fabric
562 :param description: Name of description
563
564 """
565
566 ret = {'name': name,
567 'changes': {},
568 'result': True,
569 'comment': 'Module function maasng.fabric_present executed'}
570
571 if __opts__['test']:
572 ret['result'] = None
azvyagintseva80fdfb2018-07-16 22:34:45 +0300573 ret['comment'] = 'fabric {0} will be updated'.format(name)
azvyagintsevf3515c82018-06-26 18:59:05 +0300574 return ret
575 # All requested subnets
576 _r_subnets = __salt__['config.get']('maas').get('region', {}).get('subnets',
577 {})
578 # Assumed subnet CIDrs, expected to be in requested fabric
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300579 _a_subnets = [_r_subnets[f]['cidr'] for f in _r_subnets.keys() if
azvyagintsevf3515c82018-06-26 18:59:05 +0300580 _r_subnets[f]['fabric'] == name]
581 _rez = __salt__['maasng.check_fabric_guess_with_cidr'](name=name,
582 cidrs=_a_subnets)
583
584 if 'not_exist' in _rez:
585 changes = __salt__['maasng.create_fabric'](name=name,
586 description=description)
587 ret['new'] = 'Fabric {0} has been created'.format(name)
588 elif 'update' in _rez:
589 f_id = _rez['update']
590 changes = __salt__['maasng.create_fabric'](name=name,
591 description=description,
592 update=True, fabric_id=f_id)
593 ret['new'] = 'Fabric {0} has been updated'.format(name)
594 ret['changes'] = changes
595
596 if "error" in changes:
597 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
598 ret['result'] = False
599 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200600
601 return ret