blob: 22c68fc36cf88600fcafeda101b8f1279a6906d5 [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
azvyagintseve2e37a12018-11-01 14:45:49 +020027def maasng(funcname, *args, **kwargs):
28 """
29 Simple wrapper, for __salt__ maasng
30 :param funcname:
31 :param args:
32 :param kwargs:
33 :return:
34 """
35 return __salt__['maasng.{}'.format(funcname)](*args, **kwargs)
36
37
38def merge2dicts(d1, d2):
39 z = d1.copy()
40 z.update(d2)
41 return z
42
43
azvyagintsev3ff2ef12018-06-01 21:30:45 +030044def disk_layout_present(hostname, layout_type, root_size=None, root_device=None,
45 volume_group=None, volume_name=None, volume_size=None,
46 disk={}, **kwargs):
Ondrej Smolab57a23b2018-01-24 11:18:24 +010047 '''
48 Ensure that the disk layout does exist
49
50 :param name: The name of the cloud that should not exist
51 '''
52 ret = {'name': hostname,
53 'changes': {},
54 'result': True,
55 'comment': 'Disk layout "{0}" updated'.format(hostname)}
56
57 machine = __salt__['maasng.get_machine'](hostname)
58 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020059 ret['comment'] = "State execution failed for machine {0}".format(
60 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010061 ret['result'] = False
62 ret['changes'] = machine
63 return ret
64
65 if machine["status_name"] != "Ready":
66 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
67 return ret
68
69 if __opts__['test']:
70 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020071 ret['comment'] = 'Disk layout will be updated on {0}, this action will delete current layout.'.format(
72 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010073 return ret
74
75 if layout_type == "flat":
76
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020077 ret["changes"] = __salt__['maasng.update_disk_layout'](
78 hostname, layout_type, root_size, root_device)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010079
80 elif layout_type == "lvm":
81
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020082 ret["changes"] = __salt__['maasng.update_disk_layout'](
83 hostname, layout_type, root_size, root_device, volume_group, volume_name, volume_size)
Ondrej Smolab57a23b2018-01-24 11:18:24 +010084
azvyagintsevbca1f462018-05-25 19:06:46 +030085 elif layout_type == "custom":
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +020086 ret["changes"] = __salt__[
87 'maasng.update_disk_layout'](hostname, layout_type)
azvyagintsevbca1f462018-05-25 19:06:46 +030088
Ondrej Smolab57a23b2018-01-24 11:18:24 +010089 else:
90 ret["comment"] = "Not supported layout provided. Choose flat or lvm"
91 ret['result'] = False
92
93 return ret
94
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +020095
azvyagintsev3ff2ef12018-06-01 21:30:45 +030096def raid_present(hostname, name, level, devices=[], partitions=[],
97 partition_schema={}):
Ondrej Smolab57a23b2018-01-24 11:18:24 +010098 '''
99 Ensure that the raid does exist
100
101 :param name: The name of the cloud that should not exist
102 '''
103
104 ret = {'name': name,
105 'changes': {},
106 'result': True,
107 'comment': 'Raid {0} presented on {1}'.format(name, hostname)}
108
109 machine = __salt__['maasng.get_machine'](hostname)
110 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200111 ret['comment'] = "State execution failed for machine {0}".format(
112 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100113 ret['result'] = False
114 ret['changes'] = machine
115 return ret
116
117 if machine["status_name"] != "Ready":
118 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
119 return ret
120
121 if __opts__['test']:
122 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200123 ret['comment'] = 'Raid {0} will be updated on {1}'.format(
124 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100125 return ret
126
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200127 # Validate that raid exists
128 # With correct devices/partition
129 # OR
130 # Create raid
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100131
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200132 ret["changes"] = __salt__['maasng.create_raid'](
133 hostname=hostname, name=name, level=level, disks=devices, partitions=partitions)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100134
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200135 # TODO partitions
136 ret["changes"].update(disk_partition_present(
137 hostname, name, partition_schema)["changes"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100138
139 if "error" in ret["changes"]:
140 ret["result"] = False
141
142 return ret
143
144
145def disk_partition_present(hostname, disk, partition_schema={}):
146 '''
147 Ensure that the disk has correct partititioning schema
148
149 :param name: The name of the cloud that should not exist
150 '''
151
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200152 # 1. Validate that disk has correct values for size and mount
153 # a. validate count of partitions
154 # b. validate size of partitions
155 # 2. If not delete all partitions on disk and recreate schema
156 # 3. Validate type exists
157 # if should not exits
158 # delete mount and unformat
159 # 4. Validate mount exists
160 # 5. if not enforce umount or mount
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100161
162 ret = {'name': hostname,
163 'changes': {},
164 'result': True,
165 'comment': 'Disk layout {0} presented'.format(disk)}
166
167 machine = __salt__['maasng.get_machine'](hostname)
168 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200169 ret['comment'] = "State execution failed for machine {0}".format(
170 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100171 ret['result'] = False
172 ret['changes'] = machine
173 return ret
174
175 if machine["status_name"] != "Ready":
176 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
177 return ret
178
179 if __opts__['test']:
180 ret['result'] = None
181 ret['comment'] = 'Partition schema will be changed on {0}'.format(disk)
182 return ret
183
184 partitions = __salt__['maasng.list_partitions'](hostname, disk)
185
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200186 # Calculate actual size in bytes from provided data
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100187 for part_name, part in partition_schema.iteritems():
188 size, unit = part["size"][:-1], part["size"][-1]
189 part["calc_size"] = int(size) * SIZE[unit]
190
191 if len(partitions) == len(partition_schema):
192
193 for part_name, part in partition_schema.iteritems():
194 LOG.info('validated {0}'.format(part["calc_size"]))
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200195 LOG.info('validated {0}'.format(
196 int(partitions[disk+"-"+part_name.split("-")[-1]]["size"])))
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100197 if part["calc_size"] == int(partitions[disk+"-"+part_name.split("-")[-1]]["size"]):
198 LOG.info('validated')
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200199 # TODO validate size (size from maas is not same as calculate?)
200 # TODO validate mount
201 # TODO validate fs type
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100202 else:
203 LOG.info('breaking')
204 break
205 return ret
206
207 #DELETE and RECREATE
208 LOG.info('delete')
209 for partition_name, partition in partitions.iteritems():
210 LOG.info(partition)
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200211 # TODO IF LVM create ERROR
212 ret["changes"] = __salt__['maasng.delete_partition_by_id'](
213 hostname, disk, partition["id"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100214
215 LOG.info('recreating')
216 for part_name, part in partition_schema.iteritems():
217 LOG.info("partitition for creation")
218 LOG.info(part)
219 if "mount" not in part:
220 part["mount"] = None
221 if "type" not in part:
222 part["type"] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200223 ret["changes"] = __salt__['maasng.create_partition'](
224 hostname, disk, part["size"], part["type"], part["mount"])
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100225
226 if "error" in ret["changes"]:
227 ret["result"] = False
228
229 return ret
230
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200231
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100232def volume_group_present(hostname, name, devices=[], partitions=[]):
233 '''
234 Ensure that the disk layout does exist
235
236 :param name: The name of the cloud that should not exist
237 '''
238 ret = {'name': hostname,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200239 'changes': {},
240 'result': True,
241 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100242
243 machine = __salt__['maasng.get_machine'](hostname)
244 if "error" in machine:
azvyagintsevf3515c82018-06-26 18:59:05 +0300245 ret['comment'] = "State execution" \
246 "failed for machine {0}".format(hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100247 ret['result'] = False
248 ret['changes'] = machine
249 return ret
250
251 if machine["status_name"] != "Ready":
252 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
253 return ret
254
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200255 # TODO validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100256 vgs = __salt__['maasng.list_volume_groups'](hostname)
257
258 if name in vgs:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200259 # TODO validation for devices and partitions
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100260 return ret
261
262 if __opts__['test']:
263 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200264 ret['comment'] = 'LVM group {0} will be updated on {1}'.format(
265 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100266 return ret
267
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200268 ret["changes"] = __salt__['maasng.create_volume_group'](
269 hostname, name, devices, partitions)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100270
271 if "error" in ret["changes"]:
272 ret["result"] = False
273
274 return ret
275
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200276
azvyagintsevf3515c82018-06-26 18:59:05 +0300277def volume_present(hostname, name, volume_group_name, size, type=None,
278 mount=None):
279 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100280 Ensure that the disk layout does exist
281
282 :param name: The name of the cloud that should not exist
azvyagintsevf3515c82018-06-26 18:59:05 +0300283 """
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100284
285 ret = {'name': hostname,
286 'changes': {},
287 'result': True,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200288 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100289
290 machine = __salt__['maasng.get_machine'](hostname)
291 if "error" in machine:
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200292 ret['comment'] = "State execution failed for machine {0}".format(
293 hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100294 ret['result'] = False
295 ret['changes'] = machine
296 return ret
297
298 if machine["status_name"] != "Ready":
299 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
300 return ret
301
302 if __opts__['test']:
303 ret['result'] = None
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200304 ret['comment'] = 'LVM volume {0} will be updated on {1}'.format(
305 name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100306
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200307 # TODO validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100308
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200309 ret["changes"] = __salt__['maasng.create_volume'](
310 hostname, name, volume_group_name, size, type, mount)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100311
312 return ret
313
314
315def select_boot_disk(hostname, name):
316 '''
317 Select disk that will be used to boot partition
318
319 :param name: The name of disk on machine
320 :param hostname: The hostname of machine
321 '''
322
323 ret = {'name': hostname,
324 'changes': {},
325 'result': True,
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200326 'comment': 'LVM group {0} presented on {1}'.format(name, hostname)}
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100327
328 machine = __salt__['maasng.get_machine'](hostname)
329 if "error" in machine:
azvyagintsevf3515c82018-06-26 18:59:05 +0300330 ret['comment'] = "State execution" \
331 "failed for machine {0}".format(hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100332 ret['result'] = False
333 ret['changes'] = machine
334 return ret
335
336 if machine["status_name"] != "Ready":
337 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
338 return ret
339
340 if __opts__['test']:
341 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300342 ret['comment'] = 'LVM volume {0}' \
343 'will be updated on {1}'.format(name, hostname)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100344
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200345 # TODO disk validation if exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100346
347 ret["changes"] = __salt__['maasng.set_boot_disk'](hostname, name)
348
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200349 return ret
350
351
Petr Ruzicka80471852018-07-13 14:08:27 +0200352def vlan_present_in_fabric(name, fabric, vlan, primary_rack, description='', dhcp_on=False, mtu=1500):
azvyagintsevf3515c82018-06-26 18:59:05 +0300353 """
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200354
355 :param name: Name of vlan
356 :param fabric: Name of fabric
azvyagintsevf3515c82018-06-26 18:59:05 +0300357 :param vlan: Vlan id
Petr Ruzicka80471852018-07-13 14:08:27 +0200358 :param mtu: MTU
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200359 :param description: Description of vlan
360 :param dhcp_on: State of dhcp
Pavel Cizinsky864a3292018-05-25 16:24:48 +0200361 :param primary_rack: primary_rack
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200362
azvyagintsevf3515c82018-06-26 18:59:05 +0300363 """
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200364
365 ret = {'name': fabric,
366 'changes': {},
367 'result': True,
368 'comment': 'Module function maasng.update_vlan executed'}
369
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200370 if __opts__['test']:
371 ret['result'] = None
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200372 ret['comment'] = 'Vlan {0} will be updated for {1}'.format(
373 vlan, fabric)
azvyagintsevf3515c82018-06-26 18:59:05 +0300374 return ret
375 # Check, that vlan already defined
376 _rez = __salt__['maasng.check_vlan_in_fabric'](fabric=fabric,
377 vlan=vlan)
378 if _rez == 'not_exist':
379 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
380 fabric=fabric,
381 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200382 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300383 description=description,
384 primary_rack=primary_rack,
385 dhcp_on=dhcp_on)
Michael Polenchukd25da792018-07-19 18:27:11 +0400386 ret['comment'] = 'Vlan {0} has ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300387 'been created for {1}'.format(name, fabric)
388 elif _rez == 'update':
389 _id = __salt__['maasng.list_vlans'](fabric)[vlan]['id']
390 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
391 fabric=fabric,
392 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200393 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300394 description=description,
395 primary_rack=primary_rack,
396 dhcp_on=dhcp_on,
397 update=True,
398 vlan_id=_id)
Michael Polenchukd25da792018-07-19 18:27:11 +0400399 ret['comment'] = 'Vlan {0} has been ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300400 'updated for {1}'.format(name, fabric)
401 ret['changes'] = changes
402
403 if "error" in changes:
404 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
405 ret['result'] = False
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200406 return ret
407
408 return ret
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300409
410
azvyagintseve2e37a12018-11-01 14:45:49 +0200411def boot_source_present(url, keyring_file='', keyring_data='',
412 delete_undefined_sources=False,
413 delete_undefined_sources_except_urls=[]):
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300414 """
415 Process maas boot-sources: link to maas-ephemeral repo
416
417
418 :param url: The URL of the BootSource.
419 :param keyring_file: The path to the keyring file for this BootSource.
420 :param keyring_data: The GPG keyring for this BootSource, base64-encoded data.
azvyagintseve2e37a12018-11-01 14:45:49 +0200421 :param delete_undefined_sources: Delete all boot-sources, except defined in reclass
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300422 """
423 ret = {'name': url,
424 'changes': {},
425 'result': True,
426 'comment': 'boot-source {0} presented'.format(url)}
427
428 if __opts__['test']:
429 ret['result'] = None
430 ret['comment'] = 'boot-source {0} will be updated'.format(url)
azvyagintseve2e37a12018-11-01 14:45:49 +0200431 maas_boot_sources = maasng('get_boot_source')
432 # TODO implement check and update for keyrings!
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300433 if url in maas_boot_sources.keys():
434 ret["result"] = True
435 ret["comment"] = 'boot-source {0} alredy exist'.format(url)
azvyagintseve2e37a12018-11-01 14:45:49 +0200436 else:
437 ret["changes"] = maasng('create_boot_source', url,
438 keyring_filename=keyring_file,
439 keyring_data=keyring_data)
440 if delete_undefined_sources:
441 ret["changes"] = merge2dicts(ret.get('changes', {}),
442 maasng('boot_sources_delete_all_others',
443 except_urls=delete_undefined_sources_except_urls))
444 # Re-import data
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300445 return ret
446
447
448def boot_sources_selections_present(bs_url, os, release, arches="*",
449 subarches="*", labels="*", wait=True):
450 """
azvyagintsevcb54d142018-06-19 16:18:32 +0300451 Process maas boot-sources selection: set of resource configurathions,
452 to be downloaded from boot-source bs_url.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300453
454 :param bs_url: Boot-source url
azvyagintsevcb54d142018-06-19 16:18:32 +0300455 :param os: The OS (e.g. ubuntu, centos) for which to import
456 resources.Required.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300457 :param release: The release for which to import resources. Required.
458 :param arches: The architecture list for which to import resources.
459 :param subarches: The subarchitecture list for which to import resources.
460 :param labels: The label lists for which to import resources.
461 :param wait: Initiate import and wait for done.
462
463 """
464 ret = {'name': bs_url,
465 'changes': {},
466 'result': True,
467 'comment': 'boot-source {0} selection present'.format(bs_url)}
468
469 if __opts__['test']:
470 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300471 ret['comment'] = 'boot-source {0}' \
472 'selection will be updated'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300473
azvyagintseve2e37a12018-11-01 14:45:49 +0200474 maas_boot_sources = maasng('get_boot_source')
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300475 if bs_url not in maas_boot_sources.keys():
476 ret["result"] = False
azvyagintsevf3515c82018-06-26 18:59:05 +0300477 ret["comment"] = 'Requested boot-source' \
478 '{0} not exist! Unable' \
479 'to proceed selection for it'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300480 return ret
481
azvyagintseve2e37a12018-11-01 14:45:49 +0200482 ret = maasng('create_boot_source_selections', bs_url, os, release,
483 arches=arches,
484 subarches=subarches,
485 labels=labels,
486 wait=wait)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300487 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200488
489
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300490def iprange_present(name, type_range, start_ip, end_ip, subnet=None,
491 comment=None):
492 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200493
494 :param name: Name of iprange
495 :param type_range: Type of iprange
496 :param start_ip: Start ip of iprange
497 :param end_ip: End ip of iprange
498 :param comment: Comment for specific iprange
499
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300500 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200501
502 ret = {'name': name,
503 'changes': {},
504 'result': True,
505 'comment': 'Module function maasng.iprange_present executed'}
506
azvyagintsevf3515c82018-06-26 18:59:05 +0300507 # Check, that range already defined
508 _rez = __salt__['maasng.get_startip'](start_ip)
509 if 'start_ip' in _rez.keys():
510 if _rez["start_ip"] == start_ip:
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200511 ret['comment'] = 'Iprange {0} already exist.'.format(name)
512 return ret
513
514 if __opts__['test']:
515 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300516 ret['comment'] = 'Ip range {0} will be ' \
517 'created with start ip: {1} ' \
518 'and end ip: {2} and ' \
519 'type {3}'.format(name, start_ip, end_ip, type_range)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200520 return ret
521
azvyagintsevf3515c82018-06-26 18:59:05 +0300522 changes = __salt__['maasng.create_iprange'](type_range=type_range,
523 start_ip=start_ip,
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200524 end_ip=end_ip, subnet=subnet, comment=comment)
azvyagintsevf3515c82018-06-26 18:59:05 +0300525 ret["changes"] = changes
526 if "error" in changes:
527 ret['comment'] = "State execution failed for iprange {0}".format(name)
528 ret['result'] = False
529 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200530 return ret
531
532
azvyagintsevf3515c82018-06-26 18:59:05 +0300533def subnet_present(cidr, name, fabric, gateway_ip, vlan):
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300534 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200535
536 :param cidr: Cidr for subnet
537 :param name: Name of subnet
538 :param fabric: Name of fabric for subnet
539 :param gateway_ip: gateway_ip
540
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300541 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200542
543 ret = {'name': name,
544 'changes': {},
545 'result': True,
546 'comment': 'Module function maasng.subnet_present executed'}
547
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200548 if __opts__['test']:
549 ret['result'] = None
550 ret['comment'] = 'Subnet {0} will be created for {1}'.format(
551 name, fabric)
552 return ret
azvyagintsevf3515c82018-06-26 18:59:05 +0300553 # Check, that subnet already defined
554 _rez = __salt__['maasng.check_subnet'](cidr, name, fabric, gateway_ip)
555 if _rez == 'not_exist':
556 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
557 fabric=fabric,
558 gateway_ip=gateway_ip,
559 vlan=vlan)
560 ret['comment'] = 'Subnet {0} ' \
561 'has been created for {1}'.format(name, fabric)
562 elif _rez == 'update':
563 _id = __salt__['maasng.list_subnets'](sort_by='cidr')[cidr]['id']
564 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
565 fabric=fabric,
566 gateway_ip=gateway_ip,
567 vlan=vlan, update=True,
568 subnet_id=_id)
569 ret['comment'] = 'Subnet {0} ' \
570 'has been updated for {1}'.format(name, fabric)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200571
azvyagintsevf3515c82018-06-26 18:59:05 +0300572 if "error" in changes:
573 ret['comment'] = "State execution failed for subnet {0}".format(name)
574 ret['result'] = False
575 ret['changes'] = changes
576 return ret
577
578 return ret
579
580
azvyagintsevf0904ac2018-07-05 18:53:26 +0300581def fabric_present(name, description=None):
azvyagintsevf3515c82018-06-26 18:59:05 +0300582 """
583
584 :param name: Name of fabric
585 :param description: Name of description
586
587 """
588
589 ret = {'name': name,
590 'changes': {},
591 'result': True,
592 'comment': 'Module function maasng.fabric_present executed'}
593
594 if __opts__['test']:
595 ret['result'] = None
azvyagintseva80fdfb2018-07-16 22:34:45 +0300596 ret['comment'] = 'fabric {0} will be updated'.format(name)
azvyagintsevf3515c82018-06-26 18:59:05 +0300597 return ret
598 # All requested subnets
599 _r_subnets = __salt__['config.get']('maas').get('region', {}).get('subnets',
600 {})
601 # Assumed subnet CIDrs, expected to be in requested fabric
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300602 _a_subnets = [_r_subnets[f]['cidr'] for f in _r_subnets.keys() if
azvyagintsevf3515c82018-06-26 18:59:05 +0300603 _r_subnets[f]['fabric'] == name]
604 _rez = __salt__['maasng.check_fabric_guess_with_cidr'](name=name,
605 cidrs=_a_subnets)
606
607 if 'not_exist' in _rez:
608 changes = __salt__['maasng.create_fabric'](name=name,
609 description=description)
610 ret['new'] = 'Fabric {0} has been created'.format(name)
611 elif 'update' in _rez:
612 f_id = _rez['update']
613 changes = __salt__['maasng.create_fabric'](name=name,
614 description=description,
615 update=True, fabric_id=f_id)
616 ret['new'] = 'Fabric {0} has been updated'.format(name)
617 ret['changes'] = changes
618
619 if "error" in changes:
620 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
621 ret['result'] = False
622 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200623
624 return ret
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200625
626
627def sshkey_present(name, sshkey):
628 """
629
630 :param name: Name of user
631 :param sshkey: SSH key for MAAS user
632
633 """
634
635 ret = {'name': name,
636 'changes': {},
637 'result': True,
638 'comment': 'Module function maasng.ssshkey_present executed'}
639
640 # Check, that subnet already defined
641 _rez = __salt__['maasng.get_sshkey'](sshkey)
642 if 'key' in _rez.keys():
643 if _rez["key"] == sshkey:
644 ret['comment'] = 'SSH key {0} already exist for user {1}.'.format(
645 sshkey, name)
646 return ret
647
648 if __opts__['test']:
649 ret['result'] = None
650 ret['comment'] = 'SSH key {0} will be add it to MAAS for user {1}'.format(
651 sshkey, name)
652
653 return ret
654
655 changes = __salt__['maasng.add_sshkey'](sshkey=sshkey)
656 ret['comment'] = 'SSH-key {0} ' \
657 'has been added for user {1}'.format(sshkey, name)
658
659 ret['changes'] = changes
660
661 if "error" in changes:
662 ret['comment'] = "State execution failed for sshkey: {0}".format(
663 sshkey)
664 ret['result'] = False
665 ret['changes'] = changes
666 return ret
667
668 return ret