1#!/usr/local/bin/python3.8
2
3from __future__ import absolute_import, division, print_function
4
5__metaclass__ = type
6
7import os
8import sys
9import pynetbox
10from packaging import version
11
12# NOTE: If anything depends on specific versions of NetBox, can check INTEGRATION_TESTS in env
13# os.environ["INTEGRATION_TESTS"]
14
15
16# Set nb variable to connect to Netbox and use the veriable in future calls
17nb_host = os.getenv("NETBOX_HOST", "http://localhost:32768")
18nb_token = os.getenv("NETBOX_TOKEN", "0123456789abcdef0123456789abcdef01234567")
19nb = pynetbox.api(nb_host, nb_token)
20nb_version = version.parse(nb.version)
21
22ERRORS = False
23
24
25def make_netbox_calls(endpoint, payload):
26    """Make the necessary calls to create endpoints, and pass any errors.
27
28    Args:
29        endpoint (obj): pynetbox endpoint object.
30        payload (list): List of endpoint objects.
31    """
32    try:
33        created = endpoint.create(payload)
34    except pynetbox.RequestError as e:
35        print(e.error)
36        ERRORS = True
37        return
38
39    return created
40
41
42# Create tags used in future tests
43create_tags = make_netbox_calls(
44    nb.extras.tags,
45    [
46        {"name": "First", "slug": "first"},
47        {"name": "Second", "slug": "second"},
48        {"name": "Third", "slug": "third"},
49        {"name": "Schnozzberry", "slug": "schnozzberry"},
50        {"name": "Lookup", "slug": "lookup"},
51        {"name": "Nolookup", "slug": "nolookup"},
52        {"name": "tagA", "slug": "taga"},
53        {"name": "tagB", "slug": "tagb"},
54        {"name": "tagC", "slug": "tagc"},
55        {"name": "Updated", "slug": "updated"},
56    ],
57)
58
59# ORDER OF OPERATIONS FOR THE MOST PART
60
61## Create TENANTS
62tenants = [{"name": "Test Tenant", "slug": "test-tenant"}]
63created_tenants = make_netbox_calls(nb.tenancy.tenants, tenants)
64### Test Tenant to be used later on
65test_tenant = nb.tenancy.tenants.get(slug="test-tenant")
66
67
68## Create TENANT GROUPS
69tenant_groups = [{"name": "Test Tenant Group", "slug": "test-tenant-group"}]
70created_tenant_groups = make_netbox_calls(nb.tenancy.tenant_groups, tenant_groups)
71
72
73## Create Regions
74regions = [
75    {"name": "Test Region", "slug": "test-region"},
76    {"name": "Parent Region", "slug": "parent-region"},
77    {"name": "Other Region", "slug": "other-region"},
78]
79created_regions = make_netbox_calls(nb.dcim.regions, regions)
80### Region variables to be used later on
81parent_region = nb.dcim.regions.get(slug="parent-region")
82test_region = nb.dcim.regions.get(slug="test-region")
83
84### Create relationship between regions
85test_region.parent = parent_region
86test_region.save()
87
88
89## Create SITES and register variables
90sites = [
91    {
92        "name": "Test Site",
93        "slug": "test-site",
94        "tenant": test_tenant.id,
95        "region": test_region.id,
96    },
97    {"name": "Test Site2", "slug": "test-site2"},
98]
99created_sites = make_netbox_calls(nb.dcim.sites, sites)
100### Site variables to be used later on
101test_site = nb.dcim.sites.get(slug="test-site")
102test_site2 = nb.dcim.sites.get(slug="test-site2")
103
104## Create Site Groups
105site_groups = [{"name": "Test Site Group", "slug": "test-site-group"}]
106created_site_groups = make_netbox_calls(nb.dcim.site_groups, site_groups)
107
108## Create VRFs
109vrfs = [{"name": "Test VRF", "rd": "1:1"}]
110created_vrfs = make_netbox_calls(nb.ipam.vrfs, vrfs)
111
112
113## Create PREFIXES
114prefixes = [
115    {"prefix": "192.168.100.0/24", "site": test_site2.id},
116    {"prefix": "10.10.0.0/16"},
117]
118created_prefixes = make_netbox_calls(nb.ipam.prefixes, prefixes)
119
120
121## Create VLAN GROUPS
122vlan_groups = [
123    {
124        "name": "Test Vlan Group",
125        "slug": "test-vlan-group",
126        "site": test_site.id,
127        "tenant": test_tenant.id,
128    },
129    {
130        "name": "Test Vlan Group 2",
131        "slug": "test-vlan-group-2",
132        "site": test_site.id,
133        "tenant": test_tenant.id,
134    },
135]
136if nb_version >= version.parse("2.11"):
137    for vg in vlan_groups:
138        if vg.get("site"):
139            vg["scope_type"] = "dcim.site"
140            vg["scope_id"] = vg.pop("site")
141created_vlan_groups = make_netbox_calls(nb.ipam.vlan_groups, vlan_groups)
142## VLAN Group variables to be used later on
143test_vlan_group = nb.ipam.vlan_groups.get(slug="test-vlan-group")
144
145
146## Create VLANS
147vlans = [
148    {"name": "Wireless", "vid": 100, "site": test_site.id},
149    {"name": "Data", "vid": 200, "site": test_site.id},
150    {"name": "VoIP", "vid": 300, "site": test_site.id},
151    {
152        "name": "Test VLAN",
153        "vid": 400,
154        "site": test_site.id,
155        "tenant": test_tenant.id,
156        "group": test_vlan_group.id,
157    },
158]
159created_vlans = make_netbox_calls(nb.ipam.vlans, vlans)
160
161
162## Create IPAM Roles
163ipam_roles = [{"name": "Network of care", "slug": "network-of-care"}]
164create_ipam_roles = make_netbox_calls(nb.ipam.roles, ipam_roles)
165
166
167## Create Manufacturers
168manufacturers = [
169    {"name": "Cisco", "slug": "cisco"},
170    {"name": "Arista", "slug": "arista"},
171    {"name": "Test Manufactuer", "slug": "test-manufacturer"},
172]
173created_manufacturers = make_netbox_calls(nb.dcim.manufacturers, manufacturers)
174### Manufacturer variables to be used later on
175cisco_manu = nb.dcim.manufacturers.get(slug="cisco")
176arista_manu = nb.dcim.manufacturers.get(slug="arista")
177
178
179## Create Device Types
180device_types = [
181    {"model": "Cisco Test", "slug": "cisco-test", "manufacturer": cisco_manu.id},
182    {"model": "Arista Test", "slug": "arista-test", "manufacturer": arista_manu.id},
183    {
184        "model": "Nexus Parent",
185        "slug": "nexus-parent",
186        "u_height": 0,
187        "manufacturer": cisco_manu.id,
188        "subdevice_role": "parent",
189    },
190    {
191        "model": "Nexus Child",
192        "slug": "nexus-child",
193        "u_height": 0,
194        "manufacturer": cisco_manu.id,
195        "subdevice_role": "child",
196    },
197    {"model": "1841", "slug": "1841", "manufacturer": cisco_manu.id,},
198]
199
200created_device_types = make_netbox_calls(nb.dcim.device_types, device_types)
201### Device type variables to be used later on
202cisco_test = nb.dcim.device_types.get(slug="cisco-test")
203arista_test = nb.dcim.device_types.get(slug="arista-test")
204nexus_parent = nb.dcim.device_types.get(slug="nexus-parent")
205nexus_child = nb.dcim.device_types.get(slug="nexus-child")
206
207## Create Device Roles
208device_roles = [
209    {"name": "Core Switch", "slug": "core-switch", "color": "aa1409", "vm_role": False},
210    {
211        "name": "Test VM Role",
212        "slug": "test-vm-role",
213        "color": "e91e63",
214        "vm_role": True,
215    },
216    {
217        "name": "Test VM Role 1",
218        "slug": "test-vm-role-1",
219        "color": "e91e65",
220        "vm_role": True,
221    },
222]
223created_device_roles = make_netbox_calls(nb.dcim.device_roles, device_roles)
224### Device role variables to be used later on
225core_switch = nb.dcim.device_roles.get(slug="core-switch")
226
227
228## Create Rack Groups
229rack_groups = [
230    {"name": "Test Rack Group", "slug": "test-rack-group", "site": test_site.id},
231    {"name": "Parent Rack Group", "slug": "parent-rack-group", "site": test_site.id},
232]
233if nb_version >= version.parse("2.11"):
234    created_rack_groups = make_netbox_calls(nb.dcim.locations, rack_groups)
235else:
236    created_rack_groups = make_netbox_calls(nb.dcim.rack_groups, rack_groups)
237
238### Create Rack Group Parent relationship
239created_rack_groups[0].parent = created_rack_groups[1]
240created_rack_groups[0].save()
241
242## Create Rack Roles
243rack_roles = [{"name": "Test Rack Role", "slug": "test-rack-role", "color": "4287f5"}]
244created_rack_roles = make_netbox_calls(nb.dcim.rack_roles, rack_roles)
245
246## Create Racks
247racks = [
248    {
249        "name": "Test Rack Site 2",
250        "site": test_site2.id,
251        "role": created_rack_roles[0].id,
252    },
253    {"name": "Test Rack", "site": test_site.id, "group": created_rack_groups[0].id},
254]
255
256## Use location instead of group for 2.11+
257if nb_version >= version.parse("2.11"):
258    racks[1]["location"] = created_rack_groups[0].id
259    del racks[1]["group"]
260
261created_racks = make_netbox_calls(nb.dcim.racks, racks)
262test_rack = nb.dcim.racks.get(name="Test Rack")  # racks don't have slugs
263test_rack_site2 = nb.dcim.racks.get(name="Test Rack Site 2")
264
265
266## Create Devices
267devices = [
268    {
269        "name": "test100",
270        "device_type": cisco_test.id,
271        "device_role": core_switch.id,
272        "site": test_site.id,
273        "local_context_data": {"ntp_servers": ["pool.ntp.org"]},
274    },
275    {
276        "name": "TestDeviceR1",
277        "device_type": cisco_test.id,
278        "device_role": core_switch.id,
279        "site": test_site.id,
280        "rack": test_rack.id,
281    },
282    {
283        "name": "R1-Device",
284        "device_type": cisco_test.id,
285        "device_role": core_switch.id,
286        "site": test_site2.id,
287        "rack": test_rack_site2.id,
288    },
289    {
290        "name": "Test Nexus One",
291        "device_type": nexus_parent.id,
292        "device_role": core_switch.id,
293        "site": test_site.id,
294    },
295    {
296        "name": "Test Nexus Child One",
297        "device_type": nexus_child.id,
298        "device_role": core_switch.id,
299        "site": test_site.id,
300    },
301]
302
303## Add some locations for 2.11+
304if nb_version >= version.parse("2.11"):
305    devices[0]["location"] = created_rack_groups[0].id
306    devices[1]["location"] = created_rack_groups[0].id
307    devices[3]["location"] = created_rack_groups[0].id
308
309created_devices = make_netbox_calls(nb.dcim.devices, devices)
310### Device variables to be used later on
311test100 = nb.dcim.devices.get(name="test100")
312
313# Create VC, assign member, create initial interface
314created_vcs = make_netbox_calls(nb.dcim.virtual_chassis, {"name": "VC1", "master": 4})
315nexus_child = nb.dcim.devices.get(5)
316nexus_child.update({"virtual_chassis": 1, "vc_position": 2})
317nexus = nb.dcim.devices.get(4)
318nexus.update({"vc_position": 0})
319nexus_interfaces = [
320    {"device": nexus.id, "name": "Ethernet1/1", "type": "1000base-t"},
321    {"device": nexus_child.id, "name": "Ethernet2/1", "type": "1000base-t"},
322]
323created_nexus_interfaces = make_netbox_calls(nb.dcim.interfaces, nexus_interfaces)
324
325## Create Interfaces
326dev_interfaces = [
327    {"name": "GigabitEthernet1", "device": test100.id, "type": "1000base-t"},
328    {"name": "GigabitEthernet2", "device": test100.id, "type": "1000base-t"},
329]
330created_interfaces = make_netbox_calls(nb.dcim.interfaces, dev_interfaces)
331## Interface variables to be used later on
332test100_gi1 = nb.dcim.interfaces.get(name="GigabitEthernet1", device_id=1)
333test100_gi2 = nb.dcim.interfaces.get(name="GigabitEthernet2", device_id=1)
334
335
336## Create IP Addresses
337ip_addresses = [
338    {
339        "address": "172.16.180.1/24",
340        "assigned_object_id": test100_gi1.id,
341        "assigned_object_type": "dcim.interface",
342    },
343    {
344        "address": "2001::1:1/64",
345        "assigned_object_id": test100_gi2.id,
346        "assigned_object_type": "dcim.interface",
347    },
348    {
349        "address": "172.16.180.11/24",
350        "assigned_object_id": created_nexus_interfaces[0].id,
351        "assigned_object_type": "dcim.interface",
352    },
353    {
354        "address": "172.16.180.12/24",
355        "assigned_object_id": created_nexus_interfaces[1].id,
356        "assigned_object_type": "dcim.interface",
357        "dns_name": "nexus.example.com",
358    },
359    {"address": "172.16.180.254/24"},
360]
361created_ip_addresses = make_netbox_calls(nb.ipam.ip_addresses, ip_addresses)
362
363# Assign Primary IP
364nexus.update({"primary_ip4": 4})
365
366## Create RIRs
367rirs = [{"name": "Example RIR", "slug": "example-rir"}]
368created_rirs = make_netbox_calls(nb.ipam.rirs, rirs)
369
370## Create Cluster Group
371cluster_groups = [{"name": "Test Cluster Group", "slug": "test-cluster-group"}]
372created_cluster_groups = make_netbox_calls(
373    nb.virtualization.cluster_groups, cluster_groups
374)
375test_cluster_group = nb.virtualization.cluster_groups.get(slug="test-cluster-group")
376
377## Create Cluster Type
378cluster_types = [{"name": "Test Cluster Type", "slug": "test-cluster-type"}]
379created_cluster_types = make_netbox_calls(
380    nb.virtualization.cluster_types, cluster_types
381)
382test_cluster_type = nb.virtualization.cluster_types.get(slug="test-cluster-type")
383
384## Create Cluster
385clusters = [
386    {
387        "name": "Test Cluster",
388        "type": test_cluster_type.id,
389        "group": test_cluster_group.id,
390        "site": test_site.id,
391    },
392    {"name": "Test Cluster 2", "type": test_cluster_type.id,},
393]
394created_clusters = make_netbox_calls(nb.virtualization.clusters, clusters)
395test_cluster = nb.virtualization.clusters.get(name="Test Cluster")
396test_cluster2 = nb.virtualization.clusters.get(name="Test Cluster 2")
397
398## Create Virtual Machine
399virtual_machines = [
400    {"name": "test100-vm", "cluster": test_cluster.id},
401    {"name": "test101-vm", "cluster": test_cluster.id},
402    {"name": "test102-vm", "cluster": test_cluster.id},
403    {"name": "test103-vm", "cluster": test_cluster.id},
404    {"name": "test104-vm", "cluster": test_cluster2.id},
405    {"name": "Test VM With Spaces", "cluster": test_cluster2.id},
406]
407created_virtual_machines = make_netbox_calls(
408    nb.virtualization.virtual_machines, virtual_machines
409)
410test100_vm = nb.virtualization.virtual_machines.get(name="test100-vm")
411test101_vm = nb.virtualization.virtual_machines.get(name="test101-vm")
412test_spaces_vm = nb.virtualization.virtual_machines.get(name="Test VM With Spaces")
413
414## Create Virtual Machine Interfaces
415virtual_machines_intfs = [
416    # Create test100-vm intfs
417    {"name": "Eth0", "virtual_machine": test100_vm.id},
418    {"name": "Eth1", "virtual_machine": test100_vm.id},
419    {"name": "Eth2", "virtual_machine": test100_vm.id},
420    {"name": "Eth3", "virtual_machine": test100_vm.id},
421    {"name": "Eth4", "virtual_machine": test100_vm.id},
422    # Create test101-vm intfs
423    {"name": "Eth0", "virtual_machine": test101_vm.id},
424    {"name": "Eth1", "virtual_machine": test101_vm.id},
425    {"name": "Eth2", "virtual_machine": test101_vm.id},
426    {"name": "Eth3", "virtual_machine": test101_vm.id},
427    {"name": "Eth4", "virtual_machine": test101_vm.id},
428    # Create Test VM With Spaces intfs
429    {"name": "Eth0", "virtual_machine": test_spaces_vm.id},
430    {"name": "Eth1", "virtual_machine": test_spaces_vm.id},
431]
432created_virtual_machines_intfs = make_netbox_calls(
433    nb.virtualization.interfaces, virtual_machines_intfs
434)
435
436
437## Create Services
438services = [
439    {"device": test100.id, "name": "ssh", "ports": [22], "protocol": "tcp"},
440    {
441        "device": test100.id,
442        "name": "http",
443        "ports": [80],
444        "protocol": "tcp",
445        "ipaddresses": [created_ip_addresses[0].id, created_ip_addresses[1].id],
446    },
447    {"device": nexus.id, "name": "telnet", "ports": [23], "protocol": "tcp"},
448    {
449        "virtual_machine": test_spaces_vm.id,
450        "name": "ssh",
451        "ports": [22],
452        "protocol": "tcp",
453    },
454]
455created_services = make_netbox_calls(nb.ipam.services, services)
456
457
458## Create Circuit Provider
459providers = [{"name": "Test Provider", "slug": "test-provider"}]
460created_providers = make_netbox_calls(nb.circuits.providers, providers)
461test_provider = nb.circuits.providers.get(slug="test-provider")
462
463## Create Circuit Type
464circuit_types = [{"name": "Test Circuit Type", "slug": "test-circuit-type"}]
465created_circuit_types = make_netbox_calls(nb.circuits.circuit_types, circuit_types)
466test_circuit_type = nb.circuits.circuit_types.get(slug="test-circuit-type")
467
468## Create Circuit
469circuits = [
470    {"cid": "Test Circuit", "provider": test_provider.id, "type": test_circuit_type.id},
471    {
472        "cid": "Test Circuit Two",
473        "provider": test_provider.id,
474        "type": test_circuit_type.id,
475    },
476]
477created_circuits = make_netbox_calls(nb.circuits.circuits, circuits)
478test_circuit_two = nb.circuits.circuits.get(cid="Test Circuit Two")
479
480## Create Circuit Termination
481circuit_terms = [
482    {
483        "circuit": test_circuit_two.id,
484        "term_side": "A",
485        "port_speed": 10000,
486        "site": test_site.id,
487    }
488]
489created_circuit_terms = make_netbox_calls(
490    nb.circuits.circuit_terminations, circuit_terms
491)
492
493route_targets = [
494    {"name": "4000:4000"},
495    {"name": "5000:5000"},
496    {"name": "6000:6000"},
497]
498created_route_targets = make_netbox_calls(nb.ipam.route_targets, route_targets)
499
500if ERRORS:
501    sys.exit(
502        "Errors have occurred when creating objects, and should have been printed out. Check previous output."
503    )
504