1 ##############################################################################
2 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
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 ##############################################################################
10 from django.contrib.auth.models import User
11 from django.core.files.base import ContentFile
12 from django.utils import timezone
16 from datetime import timedelta
18 from dashboard.exceptions import InvalidHostnameException
19 from booking.models import Booking
20 from account.models import UserProfile, Lab, LabStatus, VlanManager, PublicNetwork
21 from resource_inventory.models import (
34 GenericResourceBundle,
44 from resource_inventory.resource_manager import ResourceManager
47 Info for make_booking() function:
48 [topology] argument structure:
49 the [topology] argument should describe the structure of the pod
50 the top level should be a dictionary, with each key being a hostname
51 each value in the top level should be a dictionary with two keys:
52 "type" should map to a host profile instance
53 "nets" should map to a list of interfaces each with a list of
54 dictionaries each defining a network in the format
55 { "name": "netname", "tagged": True|False, "public": True|False }
56 each network is defined if a matching name is not found
58 sample argument structure:
61 "type": instanceOf HostProfile,
62 "role": instanceOf OPNFVRole
63 "image": instanceOf Image
66 0: { "name": "public", "tagged": True, "public": True },
67 1: { "name": "private", "tagged": False, "public": False },
76 def make_booking(owner=None, start=timezone.now(),
77 end=timezone.now() + timedelta(days=1),
78 lab=None, purpose="my_purpose",
79 project="my_project", collaborators=[],
80 topology={}, installer=None, scenario=None):
82 grb, host_set = make_grb(topology, owner, lab)
83 config_bundle = make_config_bundle(grb, owner, topology, host_set, installer, scenario)
84 resource = ResourceManager.getInstance().convertResourceBundle(grb, config=config_bundle)
86 raise Exception("Resource not created")
88 return Booking.objects.create(
90 config_bundle=config_bundle,
100 def make_config_bundle(grb, owner, topology={}, host_set={},
101 installer=None, scenario=None):
102 cb = ConfigBundle.objects.create(
104 name="config bundle " + str(ConfigBundle.objects.count()),
105 description="cb generated by make_config_bundle() method"
108 opnfv_config = OPNFVConfig.objects.create(
114 # generate host configurations based on topology and host set
115 for hostname, host_info in topology.items():
116 host_config = HostConfiguration.objects.create(
117 host=host_set[hostname],
118 image=host_info["image"],
120 is_head_node=host_info['role'].name.lower() == "jumphost"
122 HostOPNFVConfig.objects.create(
123 role=host_info["role"],
124 host_config=host_config,
125 opnfv_config=opnfv_config
130 def make_network(name, lab, grb, public):
131 network = Network(name=name, bundle=grb, is_public=public)
133 public_net = lab.vlan_manager.get_public_vlan()
135 raise Exception("No more public networks available")
136 lab.vlan_manager.reserve_public_vlan(public_net.vlan)
137 network.vlan_id = public_net.vlan
139 private_net = lab.vlan_manager.get_vlan()
141 raise Exception("No more generic vlans are available")
142 lab.vlan_manager.reserve_vlans([private_net])
143 network.vlan_id = private_net
149 def make_grb(topology, owner, lab):
151 grb = GenericResourceBundle.objects.create(
154 name="Generic ResourceBundle " + str(GenericResourceBundle.objects.count()),
155 description="grb generated by make_grb() method"
161 for hostname, info in topology.items():
162 host_profile = info["type"]
164 # need to construct host from hostname and type
165 generic_host = make_generic_host(grb, host_profile, hostname)
166 host_set[hostname] = generic_host
170 for interface_index, interface_profile in enumerate(host_profile.interfaceprofile.all()):
171 generic_interface = GenericInterface.objects.create(host=generic_host, profile=interface_profile)
172 netconfig = nets[interface_index]
173 for network_info in netconfig:
174 network_name = network_info["name"]
175 if network_name not in networks:
176 networks[network_name] = make_network(network_name, lab, grb, network_info['public'])
178 generic_interface.connections.add(NetworkConnection.objects.create(
179 network=networks[network_name],
180 vlan_is_tagged=network_info["tagged"]
186 def make_generic_host(grb, host_profile, hostname):
187 if not re.match(r"(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})$", hostname):
188 raise InvalidHostnameException("Hostname must comply to RFC 952 and all extensions")
189 gresource = GenericResource.objects.create(bundle=grb, name=hostname)
191 return GenericHost.objects.create(resource=gresource, profile=host_profile)
194 def make_user(is_superuser=False, username="testuser",
195 password="testpassword", email="default_email@user.com"):
196 user = User.objects.create_user(username=username, email=email, password=password)
197 user.is_superuser = is_superuser
203 def make_user_profile(user=None, email_addr="email@email.com",
204 company="company", full_name="John Doe",
205 booking_privledge=True, ssh_file=None):
206 user = user or User.objects.first() or make_user()
207 profile = UserProfile.objects.create(
208 email_addr=email_addr,
211 booking_privledge=booking_privledge,
214 profile.ssh_public_key.save("user_ssh_key", ssh_file if ssh_file else ContentFile("public key content string"))
219 def make_vlan_manager(vlans=None, block_size=20, allow_overlapping=False, reserved_vlans=None):
221 vlans = [vlan % 2 for vlan in range(4095)]
222 if not reserved_vlans:
223 reserved_vlans = [0 for i in range(4095)]
225 return VlanManager.objects.create(
226 vlans=json.dumps(vlans),
227 reserved_vlans=json.dumps(vlans),
228 block_size=block_size,
229 allow_overlapping=allow_overlapping
233 def make_lab(user=None, name="Test Lab Instance",
234 status=LabStatus.UP, vlan_manager=None,
237 vlan_manager = make_vlan_manager()
242 lab = Lab.objects.create(
245 contact_email='test_lab@test_site.org',
246 contact_phone='603 123 4567',
248 vlan_manager=vlan_manager,
249 description='test lab instantiation',
253 for i in range(pub_net_count):
254 make_public_net(vlan=i * 2 + 1, lab=lab)
260 resource_inventory instantiation section for permanent resources
264 def make_complete_host_profile(lab, name="test_hostprofile"):
265 host_profile = make_host_profile(lab, name=name)
266 make_disk_profile(host_profile, 500, name=name)
267 make_cpu_profile(host_profile)
268 make_interface_profile(host_profile, name=name)
269 make_ram_profile(host_profile)
274 def make_host_profile(lab, host_type=0, name="test hostprofile"):
275 host_profile = HostProfile.objects.create(
278 description='test hostprofile instance'
280 host_profile.labs.add(lab)
285 def make_ram_profile(host, channels=4, amount=256):
286 return RamProfile.objects.create(
293 def make_disk_profile(hostprofile, size=0, media_type="SSD",
294 name="test diskprofile", rotation=0,
296 return DiskProfile.objects.create(
299 media_type=media_type,
306 def make_cpu_profile(hostprofile,
308 architecture="x86_64",
310 return CpuProfile.objects.create(
312 architecture=architecture,
319 def make_interface_profile(hostprofile,
321 name="test interface profile",
323 return InterfaceProfile.objects.create(
331 def make_image(lab, lab_id, owner, os, host_profile,
332 public=True, name="default image", description="default image"):
333 return Image.objects.create(
337 host_type=host_profile,
340 description=description
344 def make_scenario(name="test scenario"):
345 return Scenario.objects.create(name=name)
348 def make_installer(scenarios, name="test installer"):
349 installer = Installer.objects.create(name=name)
350 for scenario in scenarios:
351 installer.sup_scenarios.add(scenario)
356 def make_os(installers, name="test OS"):
357 os = Opsys.objects.create(name=name)
358 for installer in installers:
359 os.sup_installers.add(installer)
364 def make_host(host_profile, lab, labid="test_host", name="test_host",
365 booked=False, working=True, config=None, template=None,
366 bundle=None, model="Model 1", vendor="ACME"):
367 return Host.objects.create(
369 profile=host_profile,
381 def make_opnfv_role(name="Jumphost", description="test opnfvrole"):
382 return OPNFVRole.objects.create(
384 description=description
388 def make_public_net(vlan, lab, in_use=False,
389 cidr="0.0.0.0/0", gateway="0.0.0.0"):
390 return PublicNetwork.objects.create(