558031dc497ec4b28184679b9ceef2a66c467452
[pharos-tools.git] / dashboard / src / dashboard / testing_utils.py
1 ##############################################################################
2 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 from django.contrib.auth.models import User
11 from django.core.files.base import ContentFile
12
13 import json
14 import re
15
16 from dashboard.exceptions import (
17     InvalidHostnameException
18 )
19 from booking.models import Booking
20 from account.models import UserProfile, Lab, LabStatus, VlanManager, PublicNetwork
21 from resource_inventory.models import (
22     Host,
23     HostProfile,
24     InterfaceProfile,
25     DiskProfile,
26     CpuProfile,
27     Opsys,
28     Image,
29     Scenario,
30     Installer,
31     OPNFVRole,
32     RamProfile,
33     Network,
34     Vlan,
35     GenericResourceBundle,
36     GenericResource,
37     GenericHost,
38     ConfigBundle,
39     GenericInterface,
40     HostConfiguration,
41     OPNFVConfig,
42 )
43 from resource_inventory.resource_manager import ResourceManager
44
45
46 class BookingContextData(object):
47     def prepopulate(self, *args, **kwargs):
48         self.loginuser = instantiate_user(False, username=kwargs.get("login_username", "newtestuser"), password="testpassword")
49         instantiate_userprofile(self.loginuser)
50
51         lab_user = kwargs.get("lab_user", instantiate_user(True))
52         self.lab = instantiate_lab(lab_user)
53
54         self.host_profile = make_hostprofile_set(self.lab)
55         self.scenario = instantiate_scenario()
56         self.installer = instantiate_installer([self.scenario])
57         os = instantiate_os([self.installer])
58         self.image = instantiate_image(self.lab, 1, self.loginuser, os, self.host_profile)
59         self.host = instantiate_host(self.host_profile, self.lab)
60         self.role = instantiate_opnfvrole()
61         self.pubnet = instantiate_publicnet(10, self.lab)
62
63
64 """
65 Info for instantiate_booking() function:
66 [topology] argument structure:
67     the [topology] argument should describe the structure of the pod
68     the top level should be a dictionary, with each key being a hostname
69     each value in the top level should be a dictionary with two keys:
70         "type" should map to a host profile instance
71         "nets" should map to a list of interfaces each with a list of
72             dictionaries each defining a network in the format
73             { "name": "netname", "tagged": True|False, "public": True|False }
74             each network is defined if a matching name is not found
75
76     sample argument structure:
77         topology={
78             "host1": {
79                       "type": instanceOf HostProfile,
80                       "role": instanceOf OPNFVRole
81                       "image": instanceOf Image
82                       "nets": [
83                                 0: [
84                                         0: { "name": "public", "tagged": True, "public": True },
85                                         1: { "name": "private", "tagged": False, "public": False },
86                                    ]
87                                 1: []
88                               ]
89                   }
90         }
91 """
92
93
94 def instantiate_booking(owner,
95                         start,
96                         end,
97                         booking_identifier,
98                         lab=Lab.objects.first(),
99                         purpose="purposetext",
100                         project="projecttext",
101                         collaborators=[],
102                         topology={},
103                         installer=None,
104                         scenario=None):
105     (grb, host_set) = instantiate_grb(topology, owner, lab, booking_identifier)
106     cb = instantiate_cb(grb, owner, booking_identifier, topology, host_set, installer, scenario)
107
108     resource = ResourceManager.getInstance().convertResourceBundle(grb, lab, cb)
109
110     booking = Booking()
111
112     booking.resource = resource
113     if not resource:
114         raise Exception("Resource not created")
115     booking.config_bundle = cb
116     booking.start = start
117     booking.end = end
118     booking.owner = owner
119     booking.purpose = purpose
120     booking.project = project
121     booking.lab = lab
122     booking.save()
123
124     return booking
125
126
127 def instantiate_cb(grb,
128                    owner,
129                    booking_identifier,
130                    topology={},
131                    host_set={},
132                    installer=None,
133                    scenario=None):
134     cb = ConfigBundle()
135     cb.owner = owner
136     cb.name = str(booking_identifier) + "_cb"
137     cb.description = "cb generated by instantiate_cb() method"
138     cb.save()
139
140     opnfvconfig = OPNFVConfig()
141     opnfvconfig.installer = installer
142     opnfvconfig.scenario = scenario
143     opnfvconfig.bundle = cb
144     opnfvconfig.save()
145
146     # generate host configurations based on topology and host set
147     for hostname, host_info in topology.items():
148         hconf = HostConfiguration()
149         hconf.bundle = cb
150         hconf.host = host_set[hostname]
151         hconf.image = host_info["image"]
152         hconf.opnfvRole = host_info["role"]
153         hconf.save()
154     return cb
155
156
157 def instantiate_grb(topology,
158                     owner,
159                     lab,
160                     booking_identifier):
161
162     grb = GenericResourceBundle(owner=owner, lab=lab)
163     grb.name = str(booking_identifier) + "_grb"
164     grb.description = "grb generated by instantiate_grb() method"
165     grb.save()
166
167     networks = {}
168     host_set = {}
169
170     for hostname in topology.keys():
171         info = topology[hostname]
172         host_profile = info["type"]
173
174         # need to construct host from hostname and type
175         ghost = instantiate_ghost(grb, host_profile, hostname)
176         host_set[hostname] = ghost
177
178         ghost.save()
179
180         # set up networks
181         nets = info["nets"]
182         for interface_index, interface_profile in enumerate(host_profile.interfaceprofile.all()):
183             generic_interface = GenericInterface()
184             generic_interface.host = ghost
185             generic_interface.profile = interface_profile
186             generic_interface.save()
187
188             netconfig = nets[interface_index]
189             for network_index, network_info in enumerate(netconfig):
190                 network_name = network_info["name"]
191                 network = None
192                 if network_name in networks:
193                     network = networks[network_name]
194                 else:
195                     network = Network()
196                     network.name = network_name
197                     network.vlan_id = lab.vlan_manager.get_vlan()
198                     network.save()
199                     networks[network_name] = network
200                     if network_info["public"]:
201                         public_net = lab.vlan_manager.get_public_vlan()
202                         if not public_net:
203                             raise Exception("No more public networks available")
204                         lab.vlan_manager.reserve_public_vlan(public_net.vlan)
205                         network.vlan_id = public_net.vlan
206                     else:
207                         private_net = lab.vlan_manager.get_vlan()
208                         if not private_net:
209                             raise Exception("No more generic vlans are available")
210                         lab.vlan_manager.reserve_vlans([private_net])
211                         network.vlan_id = private_net
212
213                 vlan = Vlan()
214                 vlan.vlan_id = network.vlan_id
215                 vlan.public = network_info["public"]
216                 vlan.tagged = network_info["tagged"]
217                 vlan.save()
218                 generic_interface.vlans.add(vlan)
219
220     return (grb, host_set)
221
222
223 def instantiate_ghost(grb, host_profile, hostname):
224     if not re.match(r"(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})$", hostname):
225         raise InvalidHostnameException("Hostname must comply to RFC 952 and all extensions to it until this point")
226     gresource = GenericResource(bundle=grb, name=hostname)
227     gresource.save()
228
229     ghost = GenericHost()
230     ghost.resource = gresource
231     ghost.profile = host_profile
232     ghost.save()
233
234     return ghost
235
236
237 def instantiate_user(is_superuser,
238                      username="testuser",
239                      password="testpassword",
240                      email="default_email@user.com"
241                      ):
242     user = User.objects.create_user(username=username, email=email, password=password)
243     user.is_superuser = is_superuser
244
245     user.save()
246
247     return user
248
249
250 def instantiate_userprofile(user, email_addr="email@email.com", company="company", full_name="John Doe", booking_privledge=True, ssh_file=None):
251     up = UserProfile()
252     up.email_address = email_addr
253     up.company = company
254     up.full_name = full_name
255     up.booking_privledge = booking_privledge
256     up.user = user
257     up.save()
258     up.ssh_public_key.save("user_ssh_key", ssh_file if ssh_file else ContentFile("public key content string"))
259
260     return up
261
262
263 def instantiate_vlanmanager(vlans=None,
264                             block_size=20,
265                             allow_overlapping=False,
266                             reserved_vlans=None
267                             ):
268     vlanmanager = VlanManager()
269     if not vlans:
270         vlans = []
271         for vlan in range(0, 4095):
272             vlans.append(vlan % 2)
273     vlanmanager.vlans = json.dumps(vlans)
274     if not reserved_vlans:
275         reserved_vlans = []
276         for vlan in range(0, 4095):
277             reserved_vlans.append(0)
278     vlanmanager.reserved_vlans = json.dumps(vlans)
279     vlanmanager.block_size = block_size
280     vlanmanager.allow_overlapping = allow_overlapping
281
282     vlanmanager.save()
283
284     return vlanmanager
285
286
287 def instantiate_lab(user=None,
288                     name="Test Lab Instance",
289                     status=LabStatus.UP,
290                     vlan_manager=None
291                     ):
292     if not vlan_manager:
293         vlan_manager = instantiate_vlanmanager()
294
295     if not user:
296         user = instantiate_user(True, 'test_user', 'test_pass', 'test_user@test_site.org')
297
298     lab = Lab()
299     lab.lab_user = user
300     lab.name = name
301     lab.contact_email = 'test_lab@test_site.org'
302     lab.contact_phone = '603 123 4567'
303     lab.status = status
304     lab.vlan_manager = vlan_manager
305     lab.description = 'test lab instantiation'
306     lab.api_token = '12345678'
307
308     lab.save()
309
310     return lab
311
312
313 """
314 resource_inventory instantiation section for permenant resources
315 """
316
317
318 def make_hostprofile_set(lab, name="test_hostprofile"):
319     hostprof = instantiate_hostprofile(lab, name=name)
320     instantiate_diskprofile(hostprof, 500, name=name)
321     instantiate_cpuprofile(hostprof)
322     instantiate_interfaceprofile(hostprof, name=name)
323     instantiate_ramprofile(hostprof)
324
325     return hostprof
326
327
328 def instantiate_hostprofile(lab,
329                             host_type=0,
330                             name="test hostprofile instance"
331                             ):
332     hostprof = HostProfile()
333     hostprof.host_type = host_type
334     hostprof.name = name
335     hostprof.description = 'test hostprofile instance'
336     hostprof.save()
337     hostprof.labs.add(lab)
338
339     hostprof.save()
340
341     return hostprof
342
343
344 def instantiate_ramprofile(host,
345                            channels=4,
346                            amount=256):
347     ramprof = RamProfile()
348     ramprof.host = host
349     ramprof.amount = amount
350     ramprof.channels = channels
351     ramprof.save()
352
353     return ramprof
354
355
356 def instantiate_diskprofile(hostprofile,
357                             size=0,
358                             media_type="SSD",
359                             name="test diskprofile",
360                             rotation=0,
361                             interface="sata"):
362
363     diskprof = DiskProfile()
364     diskprof.name = name
365     diskprof.size = size
366     diskprof.media_type = media_type
367     diskprof.host = hostprofile
368     diskprof.rotation = rotation
369     diskprof.interface = interface
370
371     diskprof.save()
372
373     return diskprof
374
375
376 def instantiate_cpuprofile(hostprofile,
377                            cores=4,
378                            architecture="x86_64",
379                            cpus=4,
380                            ):
381     cpuprof = CpuProfile()
382     cpuprof.cores = cores
383     cpuprof.architecture = architecture
384     cpuprof.cpus = cpus
385     cpuprof.host = hostprofile
386     cpuprof.cflags = ''
387
388     cpuprof.save()
389
390     return cpuprof
391
392
393 def instantiate_interfaceprofile(hostprofile,
394                                  speed=1000,
395                                  name="test interface profile",
396                                  nic_type="pcie"
397                                  ):
398     intprof = InterfaceProfile()
399     intprof.host = hostprofile
400     intprof.name = name
401     intprof.speed = speed
402     intprof.nic_type = nic_type
403
404     intprof.save()
405
406     return intprof
407
408
409 def instantiate_image(lab,
410                       lab_id,
411                       owner,
412                       os,
413                       host_profile,
414                       public=True,
415                       name="default image",
416                       description="default image"
417                       ):
418     image = Image()
419     image.from_lab = lab
420     image.lab_id = lab_id
421     image.os = os
422     image.host_type = host_profile
423     image.public = public
424     image.name = name
425     image.description = description
426
427     image.save()
428
429     return image
430
431
432 def instantiate_scenario(name="test scenario"):
433     scenario = Scenario()
434     scenario.name = name
435     scenario.save()
436     return scenario
437
438
439 def instantiate_installer(supported_scenarios,
440                           name="test installer"
441                           ):
442     installer = Installer()
443     installer.name = name
444     installer.save()
445     for scenario in supported_scenarios:
446         installer.sup_scenarios.add(scenario)
447
448     installer.save()
449     return installer
450
451
452 def instantiate_os(supported_installers,
453                    name="test operating system",
454                    ):
455     os = Opsys()
456     os.name = name
457     os.save()
458     for installer in supported_installers:
459         os.sup_installers.add(installer)
460     os.save()
461     return os
462
463
464 def instantiate_host(host_profile,
465                      lab,
466                      labid="test_host",
467                      name="test_host",
468                      booked=False,
469                      working=True,
470                      config=None,
471                      template=None,
472                      bundle=None,
473                      model="Model 1",
474                      vendor="ACME"):
475     host = Host()
476     host.lab = lab
477     host.profile = host_profile
478     host.name = name
479     host.booked = booked
480     host.working = working
481     host.config = config
482     host.template = template
483     host.bundle = bundle
484     host.model = model
485     host.vendor = vendor
486
487     host.save()
488
489     return host
490
491
492 def instantiate_opnfvrole(name="Jumphost",
493                           description="test opnfvrole"):
494     role = OPNFVRole()
495     role.name = name
496     role.description = description
497     role.save()
498
499     return role
500
501
502 def instantiate_publicnet(vlan,
503                           lab,
504                           in_use=False,
505                           cidr="0.0.0.0/0",
506                           gateway="0.0.0.0"):
507     pubnet = PublicNetwork()
508     pubnet.lab = lab
509     pubnet.vlan = vlan
510     pubnet.cidr = cidr
511     pubnet.gateway = gateway
512     pubnet.save()
513
514     return pubnet