blob: 0275465aba5f123edab918037939a5ff8f0b7221 [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
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200355 ret['comment'] = 'Vlan {0} will be updated for {1}'.format(
356 vlan, fabric)
azvyagintsevf3515c82018-06-26 18:59:05 +0300357 return ret
358 # Check, that vlan already defined
359 _rez = __salt__['maasng.check_vlan_in_fabric'](fabric=fabric,
360 vlan=vlan)
361 if _rez == 'not_exist':
362 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
363 fabric=fabric,
364 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200365 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300366 description=description,
367 primary_rack=primary_rack,
368 dhcp_on=dhcp_on)
Michael Polenchukd25da792018-07-19 18:27:11 +0400369 ret['comment'] = 'Vlan {0} has ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300370 'been created for {1}'.format(name, fabric)
371 elif _rez == 'update':
372 _id = __salt__['maasng.list_vlans'](fabric)[vlan]['id']
373 changes = __salt__['maasng.create_vlan_in_fabric'](name=name,
374 fabric=fabric,
375 vlan=vlan,
Petr Ruzicka80471852018-07-13 14:08:27 +0200376 mtu=mtu,
azvyagintsevf3515c82018-06-26 18:59:05 +0300377 description=description,
378 primary_rack=primary_rack,
379 dhcp_on=dhcp_on,
380 update=True,
381 vlan_id=_id)
Michael Polenchukd25da792018-07-19 18:27:11 +0400382 ret['comment'] = 'Vlan {0} has been ' \
azvyagintsevf3515c82018-06-26 18:59:05 +0300383 'updated for {1}'.format(name, fabric)
384 ret['changes'] = changes
385
386 if "error" in changes:
387 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
388 ret['result'] = False
Pavel Cizinsky0995e8f2018-05-04 17:10:37 +0200389 return ret
390
391 return ret
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300392
393
394def boot_source_present(url, keyring_file='', keyring_data=''):
395 """
396 Process maas boot-sources: link to maas-ephemeral repo
397
398
399 :param url: The URL of the BootSource.
400 :param keyring_file: The path to the keyring file for this BootSource.
401 :param keyring_data: The GPG keyring for this BootSource, base64-encoded data.
402 """
403 ret = {'name': url,
404 'changes': {},
405 'result': True,
406 'comment': 'boot-source {0} presented'.format(url)}
407
408 if __opts__['test']:
409 ret['result'] = None
410 ret['comment'] = 'boot-source {0} will be updated'.format(url)
411
412 maas_boot_sources = __salt__['maasng.get_boot_source']()
413 # TODO imlpement check and update for keyrings!
414 if url in maas_boot_sources.keys():
415 ret["result"] = True
416 ret["comment"] = 'boot-source {0} alredy exist'.format(url)
417 return ret
418 ret["changes"] = __salt__['maasng.create_boot_source'](url,
419 keyring_filename=keyring_file,
420 keyring_data=keyring_data)
421 return ret
422
423
424def boot_sources_selections_present(bs_url, os, release, arches="*",
425 subarches="*", labels="*", wait=True):
426 """
azvyagintsevcb54d142018-06-19 16:18:32 +0300427 Process maas boot-sources selection: set of resource configurathions,
428 to be downloaded from boot-source bs_url.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300429
430 :param bs_url: Boot-source url
azvyagintsevcb54d142018-06-19 16:18:32 +0300431 :param os: The OS (e.g. ubuntu, centos) for which to import
432 resources.Required.
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300433 :param release: The release for which to import resources. Required.
434 :param arches: The architecture list for which to import resources.
435 :param subarches: The subarchitecture list for which to import resources.
436 :param labels: The label lists for which to import resources.
437 :param wait: Initiate import and wait for done.
438
439 """
440 ret = {'name': bs_url,
441 'changes': {},
442 'result': True,
443 'comment': 'boot-source {0} selection present'.format(bs_url)}
444
445 if __opts__['test']:
446 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300447 ret['comment'] = 'boot-source {0}' \
448 'selection will be updated'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300449
450 maas_boot_sources = __salt__['maasng.get_boot_source']()
451 if bs_url not in maas_boot_sources.keys():
452 ret["result"] = False
azvyagintsevf3515c82018-06-26 18:59:05 +0300453 ret["comment"] = 'Requested boot-source' \
454 '{0} not exist! Unable' \
455 'to proceed selection for it'.format(bs_url)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300456 return ret
457
azvyagintsevcb54d142018-06-19 16:18:32 +0300458 ret = __salt__['maasng.create_boot_source_selections'](bs_url,
459 os,
460 release,
461 arches=arches,
462 subarches=subarches,
463 labels=labels,
464 wait=wait)
azvyagintsev3ff2ef12018-06-01 21:30:45 +0300465 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200466
467
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300468def iprange_present(name, type_range, start_ip, end_ip, subnet=None,
469 comment=None):
470 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200471
472 :param name: Name of iprange
473 :param type_range: Type of iprange
474 :param start_ip: Start ip of iprange
475 :param end_ip: End ip of iprange
476 :param comment: Comment for specific iprange
477
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300478 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200479
480 ret = {'name': name,
481 'changes': {},
482 'result': True,
483 'comment': 'Module function maasng.iprange_present executed'}
484
azvyagintsevf3515c82018-06-26 18:59:05 +0300485 # Check, that range already defined
486 _rez = __salt__['maasng.get_startip'](start_ip)
487 if 'start_ip' in _rez.keys():
488 if _rez["start_ip"] == start_ip:
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200489 ret['comment'] = 'Iprange {0} already exist.'.format(name)
490 return ret
491
492 if __opts__['test']:
493 ret['result'] = None
azvyagintsevf3515c82018-06-26 18:59:05 +0300494 ret['comment'] = 'Ip range {0} will be ' \
495 'created with start ip: {1} ' \
496 'and end ip: {2} and ' \
497 'type {3}'.format(name, start_ip, end_ip, type_range)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200498 return ret
499
azvyagintsevf3515c82018-06-26 18:59:05 +0300500 changes = __salt__['maasng.create_iprange'](type_range=type_range,
501 start_ip=start_ip,
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200502 end_ip=end_ip, subnet=subnet, comment=comment)
azvyagintsevf3515c82018-06-26 18:59:05 +0300503 ret["changes"] = changes
504 if "error" in changes:
505 ret['comment'] = "State execution failed for iprange {0}".format(name)
506 ret['result'] = False
507 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200508 return ret
509
510
azvyagintsevf3515c82018-06-26 18:59:05 +0300511def subnet_present(cidr, name, fabric, gateway_ip, vlan):
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300512 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200513
514 :param cidr: Cidr for subnet
515 :param name: Name of subnet
516 :param fabric: Name of fabric for subnet
517 :param gateway_ip: gateway_ip
518
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300519 """
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200520
521 ret = {'name': name,
522 'changes': {},
523 'result': True,
524 'comment': 'Module function maasng.subnet_present executed'}
525
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200526 if __opts__['test']:
527 ret['result'] = None
528 ret['comment'] = 'Subnet {0} will be created for {1}'.format(
529 name, fabric)
530 return ret
azvyagintsevf3515c82018-06-26 18:59:05 +0300531 # Check, that subnet already defined
532 _rez = __salt__['maasng.check_subnet'](cidr, name, fabric, gateway_ip)
533 if _rez == 'not_exist':
534 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
535 fabric=fabric,
536 gateway_ip=gateway_ip,
537 vlan=vlan)
538 ret['comment'] = 'Subnet {0} ' \
539 'has been created for {1}'.format(name, fabric)
540 elif _rez == 'update':
541 _id = __salt__['maasng.list_subnets'](sort_by='cidr')[cidr]['id']
542 changes = __salt__['maasng.create_subnet'](cidr=cidr, name=name,
543 fabric=fabric,
544 gateway_ip=gateway_ip,
545 vlan=vlan, update=True,
546 subnet_id=_id)
547 ret['comment'] = 'Subnet {0} ' \
548 'has been updated for {1}'.format(name, fabric)
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200549
azvyagintsevf3515c82018-06-26 18:59:05 +0300550 if "error" in changes:
551 ret['comment'] = "State execution failed for subnet {0}".format(name)
552 ret['result'] = False
553 ret['changes'] = changes
554 return ret
555
556 return ret
557
558
azvyagintsevf0904ac2018-07-05 18:53:26 +0300559def fabric_present(name, description=None):
azvyagintsevf3515c82018-06-26 18:59:05 +0300560 """
561
562 :param name: Name of fabric
563 :param description: Name of description
564
565 """
566
567 ret = {'name': name,
568 'changes': {},
569 'result': True,
570 'comment': 'Module function maasng.fabric_present executed'}
571
572 if __opts__['test']:
573 ret['result'] = None
azvyagintseva80fdfb2018-07-16 22:34:45 +0300574 ret['comment'] = 'fabric {0} will be updated'.format(name)
azvyagintsevf3515c82018-06-26 18:59:05 +0300575 return ret
576 # All requested subnets
577 _r_subnets = __salt__['config.get']('maas').get('region', {}).get('subnets',
578 {})
579 # Assumed subnet CIDrs, expected to be in requested fabric
azvyagintsevefb6f5d2018-07-10 14:16:19 +0300580 _a_subnets = [_r_subnets[f]['cidr'] for f in _r_subnets.keys() if
azvyagintsevf3515c82018-06-26 18:59:05 +0300581 _r_subnets[f]['fabric'] == name]
582 _rez = __salt__['maasng.check_fabric_guess_with_cidr'](name=name,
583 cidrs=_a_subnets)
584
585 if 'not_exist' in _rez:
586 changes = __salt__['maasng.create_fabric'](name=name,
587 description=description)
588 ret['new'] = 'Fabric {0} has been created'.format(name)
589 elif 'update' in _rez:
590 f_id = _rez['update']
591 changes = __salt__['maasng.create_fabric'](name=name,
592 description=description,
593 update=True, fabric_id=f_id)
594 ret['new'] = 'Fabric {0} has been updated'.format(name)
595 ret['changes'] = changes
596
597 if "error" in changes:
598 ret['comment'] = "State execution failed for fabric {0}".format(fabric)
599 ret['result'] = False
600 return ret
Pavel Cizinsky8dd85b52018-06-18 21:40:13 +0200601
602 return ret
Pavel Cizinsky8f9ba8e2018-09-10 14:31:49 +0200603
604
605def sshkey_present(name, sshkey):
606 """
607
608 :param name: Name of user
609 :param sshkey: SSH key for MAAS user
610
611 """
612
613 ret = {'name': name,
614 'changes': {},
615 'result': True,
616 'comment': 'Module function maasng.ssshkey_present executed'}
617
618 # Check, that subnet already defined
619 _rez = __salt__['maasng.get_sshkey'](sshkey)
620 if 'key' in _rez.keys():
621 if _rez["key"] == sshkey:
622 ret['comment'] = 'SSH key {0} already exist for user {1}.'.format(
623 sshkey, name)
624 return ret
625
626 if __opts__['test']:
627 ret['result'] = None
628 ret['comment'] = 'SSH key {0} will be add it to MAAS for user {1}'.format(
629 sshkey, name)
630
631 return ret
632
633 changes = __salt__['maasng.add_sshkey'](sshkey=sshkey)
634 ret['comment'] = 'SSH-key {0} ' \
635 'has been added for user {1}'.format(sshkey, name)
636
637 ret['changes'] = changes
638
639 if "error" in changes:
640 ret['comment'] = "State execution failed for sshkey: {0}".format(
641 sshkey)
642 ret['result'] = False
643 ret['changes'] = changes
644 return ret
645
646 return ret