Compare commits

..

745 Commits

Author SHA1 Message Date
Jeremy Stretch
e13d4ffe60 Merge pull request #3980 from netbox-community/develop
Release v2.7.2
2020-01-21 15:12:00 -05:00
Jeremy Stretch
2581a55214 Release v2.7.2 2020-01-21 15:04:09 -05:00
Jeremy Stretch
aa4b89f751 Changelog for #3965 2020-01-21 13:56:25 -05:00
Jeremy Stretch
838aaffc4b Merge pull request #3971 from hellerve/veit/fix-3965
Display occupied rack units correctly
2020-01-21 13:53:21 -05:00
Jeremy Stretch
9dfd0e5b40 Merge pull request #3957 from kobayashi/3923-validate-key-format
Fixes: #3923 validate key format
2020-01-21 13:27:35 -05:00
Jeremy Stretch
3357c050c4 Merge pull request #3959 from hSaria/3135-document-power
Fixes #3135: Documented power modelling
2020-01-21 13:15:57 -05:00
Jeremy Stretch
60c5418516 Add tests for device component filtering by region/site 2020-01-21 12:28:22 -05:00
Jeremy Stretch
48b4695ebe Fixes #3966: Fix filtering of device components by region/site 2020-01-21 12:27:52 -05:00
Jeremy Stretch
737b05d12b Changelog for #3964 2020-01-21 11:41:44 -05:00
Jeremy Stretch
1d0546b3d1 Merge pull request #3972 from hellerve/veit/fix-3964
Display borders around devices in rack elevations
2020-01-21 11:40:20 -05:00
Jeremy Stretch
a7a166a9cb Merge branch 'develop' into veit/fix-3964 2020-01-21 11:39:45 -05:00
Jeremy Stretch
74e1c08324 Changelog for #3963 2020-01-21 11:35:05 -05:00
Jeremy Stretch
007de40ada Merge pull request #3973 from hellerve/veit/fix-3963
dcim: fix tooltips in svg rack display
2020-01-21 11:33:14 -05:00
hellerve
e184eb3521 dcim: make pep happy 2020-01-21 17:01:48 +01:00
hellerve
e421c15bdd dcim: merge elevations as necessary 2020-01-21 16:56:06 +01:00
hellerve
469a088874 dcim: fix tooltips in svg rack display 2020-01-21 16:23:59 +01:00
Jeremy Stretch
63dbee16cc Changelog for #3962 2020-01-21 10:11:27 -05:00
hellerve
5f3f21215a dcim: fix #3964 by moving away from properties to inline styles 2020-01-21 16:06:15 +01:00
Jeremy Stretch
cdd7ed21ee Merge pull request #3970 from hellerve/veit/fix-3962
Display device correctly in SVG
2020-01-21 10:05:37 -05:00
hellerve
255d12309a dcim: fix #3965 by adding an option to get_rack_units 2020-01-21 15:50:38 +01:00
Jeremy Stretch
856d14aaa6 Merge pull request #3969 from kobayashi/3960-legacy-device-status
Fixes: #3960 legacy device status
2020-01-21 09:47:16 -05:00
Jeremy Stretch
134cf38a84 Merge branch 'develop' into 3960-legacy-device-status 2020-01-21 09:47:07 -05:00
Jeremy Stretch
1a56a5561c Add systemd migration doc to pages list 2020-01-21 09:41:55 -05:00
hellerve
eb7fbe4b3a dcim: fix #3962 by moving away from device.name 2020-01-21 15:33:17 +01:00
Jeremy Stretch
9d3215e806 Fixes #3967: Resolve migration of "other" interface type 2020-01-21 09:32:51 -05:00
kobayashi
9e855ac6cd 3960 legacy device status 2020-01-21 00:30:47 -05:00
Saria Hajjar
a6fde3168b Minor corrections 2020-01-20 11:37:51 +00:00
Saria Hajjar
939a7bbe50 Fixes #3135: Documented power modelling 2020-01-19 15:43:31 +00:00
kobayashi
c6d18da2eb 3923 validate key format 2020-01-19 02:19:03 -05:00
Jeremy Stretch
606f3dacbb Fixes #3721: Allow Unicode characters in tag slugs 2020-01-17 17:25:46 -05:00
Jeremy Stretch
aa73a7ad02 Closes #3954: Add device_bays filter for devices and device types 2020-01-17 16:39:31 -05:00
Jeremy Stretch
a4687be5e5 Closes #3842: Add 802.11ax interface type 2020-01-17 16:20:11 -05:00
Jeremy Stretch
302f87e108 Fixes #3937: Suppress warning messages in tests for requests expected to yield a 4XX response 2020-01-17 14:53:33 -05:00
Jeremy Stretch
439fa731ba Fixes #3953: Fix validation error when creating child devices 2020-01-17 14:22:58 -05:00
Jeremy Stretch
c6eb40daa8 #3951: Add tests for webhook queuing 2020-01-17 12:39:14 -05:00
Jeremy Stretch
f15cde0275 Fixes #3951: Fix exception in webhook worker due to missing constant 2020-01-17 11:28:50 -05:00
Jeremy Stretch
83427d5585 Closes #3949: Add tests for IPAM model methods 2020-01-17 11:15:05 -05:00
Jeremy Stretch
d3f278400e Post-release version bump 2020-01-16 23:47:38 -05:00
Jeremy Stretch
295d4f0394 Merge pull request #3946 from netbox-community/develop
Release v2.7.1
2020-01-16 23:46:40 -05:00
Jeremy Stretch
8aad11b8d2 Release v2.7.1 2020-01-16 23:43:32 -05:00
Jeremy Stretch
0a1dd64b94 Fixes #3943: Prevent rack elevation links from opening new tabs/windows 2020-01-16 23:41:52 -05:00
Jeremy Stretch
f220b3f128 Merge pull request #3942 from hSaria/3941-ip-assign-exception
Fixes #3941: AttributeError when searching on IP assign
2020-01-16 21:43:15 -05:00
Jeremy Stretch
1c0e0fec4c Merge branch 'develop' into 3941-ip-assign-exception 2020-01-16 21:42:27 -05:00
Jeremy Stretch
5369aef971 Fixes #3944: Fix AttributeError exception when viewing prefixes list 2020-01-16 21:39:46 -05:00
Saria Hajjar
9f569d4b1b Fixes #3941: AttributeError when searching on IP assign 2020-01-16 23:03:16 +00:00
Jeremy Stretch
604924231a Post-release version bump 2020-01-16 14:47:55 -05:00
Jeremy Stretch
ea91e09a1b Merge pull request #3938 from netbox-community/develop
Release v2.7.0
2020-01-16 13:03:42 -05:00
Jeremy Stretch
0f1518e4c5 Release v2.7.0 2020-01-16 12:58:17 -05:00
Jeremy Stretch
4cb1facb6a Add PyYAML as a required package 2020-01-16 12:23:36 -05:00
Jeremy Stretch
e640f413ab Revise v2.7 release notes 2020-01-16 11:28:54 -05:00
Jeremy Stretch
fecbb60c36 Use assertHttpStatus() when evaluating HTTP response status 2020-01-16 10:47:45 -05:00
Jeremy Stretch
c0f1910493 Update requriements for v2.7 release 2020-01-16 10:16:23 -05:00
Jeremy Stretch
3eb2d45e8d Merge pull request #3936 from netbox-community/develop-2.7
Merge v2.7 changes
2020-01-16 09:52:46 -05:00
Jeremy Stretch
4556eac780 Fix IPAddressTestCase 2020-01-16 09:47:46 -05:00
Jeremy Stretch
c955aeebeb Merge branch 'develop' into develop-2.7 2020-01-16 09:38:23 -05:00
Jeremy Stretch
8bd67b2c17 Add tests for browsable API endpoints 2020-01-15 17:47:55 -05:00
Jeremy Stretch
4073dedff8 Merge pull request #3932 from netbox-community/3892-contenttype-filtering
Closes #3892: Robust ContentType filtering
2020-01-15 16:37:50 -05:00
Jeremy Stretch
bc696f2e11 Make filter test logic more obvious 2020-01-15 16:25:26 -05:00
Jeremy Stretch
c28684a8b3 Remove obsolete utility function model_names_to_filter_dict() 2020-01-15 16:21:41 -05:00
Jeremy Stretch
215b4d0b3f #3892: Convert WEBHOOK_MODELS to a Q object 2020-01-15 16:18:47 -05:00
Jeremy Stretch
d9437a08f0 #3892: Convert EXPORTTEMPLATE_MODELS to a Q object 2020-01-15 16:11:44 -05:00
Jeremy Stretch
f81e7d30e2 #3892: Convert GRAPH_MODELS to a Q object 2020-01-15 16:08:19 -05:00
Jeremy Stretch
09bee75cb3 #3892: Convert CUSTOMLINK_MODELS to a Q object 2020-01-15 16:04:41 -05:00
Jeremy Stretch
9c4ab79bea #3892: Convert CUSTOMFIELD_MODELS to a Q object 2020-01-15 16:00:54 -05:00
Jeremy Stretch
f8dad1744c #3892: Convert CABLE_TERMINATION_TYPES to a Q object 2020-01-15 15:51:51 -05:00
Jeremy Stretch
b98ac64ac2 Fix reference to obsolete constant IFACE_MODE_TAGGED 2020-01-15 14:54:46 -05:00
Jeremy Stretch
88267e9d05 Move BGP_ASN_MIN and BGP_ASN_MAX to ipam.constants 2020-01-15 14:53:46 -05:00
Jeremy Stretch
caf7d02637 Remove obsolete constant CABLE_TERMINATION_TYPE_CHOICES 2020-01-15 14:49:52 -05:00
Jeremy Stretch
aefe2b4196 Move rack elevation CSS to project-static/rack_elevation.css 2020-01-15 14:05:44 -05:00
Jeremy Stretch
fdf8211e9a Fixes #3930: Fix API rendering of the family field for aggregates 2020-01-15 13:56:37 -05:00
Jeremy Stretch
73d1a2df3d Merge pull request #3929 from netbox-community/3830-api-pagination
Fixes #3830: Update model ordering parameters to ensure deterministic ordering
2020-01-15 13:29:27 -05:00
Jeremy Stretch
0893d32665 Clarify naming constraints related to rack groups 2020-01-15 13:27:46 -05:00
Jeremy Stretch
c5ec470a00 Changelog for #3830 2020-01-15 13:25:07 -05:00
Jeremy Stretch
28350d84f9 Update model ordering parameters to ensure deterministic ordering 2020-01-15 13:20:44 -05:00
Jeremy Stretch
1055faf734 Merge pull request #3920 from hSaria/3919-utilization-bar-width
Fixes #3919: Utilization graph bar bounds
2020-01-15 10:55:39 -05:00
Jeremy Stretch
351a6e005e Merge branch 'develop' into 3919-utilization-bar-width 2020-01-15 10:55:28 -05:00
Jeremy Stretch
e5ebe6cebc Fix breadcrumbs for changelog entries for deleted objects 2020-01-15 10:48:30 -05:00
Jeremy Stretch
0053aa2d2e Fix objectchange related changes panel styling 2020-01-15 10:44:31 -05:00
Jeremy Stretch
dda9a2ee1c Fixes #3927: Fix exception when deleting devices with secrets assigned 2020-01-15 10:39:23 -05:00
Jeremy Stretch
1ea820a50e Fixes #3900: Fix exception when deleting device types 2020-01-15 10:23:07 -05:00
Jeremy Stretch
c202c1325b Add test for VM interface type choices 2020-01-15 10:04:12 -05:00
Jeremy Stretch
49f027fae7 Refactor FieldChoicesViewSet; add Interface.type to virtualization _choices endpoint 2020-01-15 09:59:44 -05:00
Jeremy Stretch
deec10efe7 Rename ExportTemplateLanguageChoices to TemplateLanguageChoices 2020-01-15 09:40:05 -05:00
Jeremy Stretch
826f4d313d Move unpack_grouped_choices() to utilities.choices 2020-01-15 09:36:39 -05:00
Jeremy Stretch
685cf50268 Closes #3926: Extend upgrade script to invalidate cache data 2020-01-15 08:57:00 -05:00
Jeremy Stretch
e0ea5b0e0b Allow the Lock bot to lock existing closed issues 2020-01-15 08:49:50 -05:00
Jeremy Stretch
b538495a29 Merge pull request #3922 from netbox-community/3921-choices-tests
Closes #3921: Add tests for API _choices endpoints
2020-01-14 16:42:28 -05:00
Jeremy Stretch
8df53eac91 Add tests for dynamic choices 2020-01-14 16:38:14 -05:00
Jeremy Stretch
857e04e90b Add _choices endpoint tests for all apps 2020-01-14 16:13:11 -05:00
Jeremy Stretch
3f37cc461d Reorder operations to avoid "pending trigger events" SQL error 2020-01-14 14:37:50 -05:00
Jeremy Stretch
823e1280d2 Add guide for squashing schema migrations 2020-01-14 14:14:54 -05:00
Saria Hajjar
a9e1e7fc78 Fixes #3919: Utilization graph bar bounds 2020-01-14 18:23:31 +00:00
Jeremy Stretch
f27e06e619 Move utility functions for secrets to secrets/utils.py 2020-01-14 12:13:58 -05:00
Jeremy Stretch
c084547dca Move IPAddressManager to a separate file 2020-01-14 12:07:45 -05:00
Jeremy Stretch
6959785cd1 Define __all__ for models.py within each app 2020-01-14 12:01:23 -05:00
Jeremy Stretch
26a257b794 Don't import constants from inside a migration 2020-01-14 11:47:28 -05:00
Jeremy Stretch
2615906526 Squashed all migrations 2020-01-14 11:06:05 -05:00
Jeremy Stretch
d96f474a5f Merge pull request #3847 from kobayashi/3525
Fixes #3525: Filter muiltiple ipaddress terms
2020-01-14 09:20:39 -05:00
Jeremy Stretch
d33e10b4ce Merge branch 'develop' into 3525 2020-01-14 09:20:02 -05:00
Jeremy Stretch
e536f363f9 Merge pull request #3915 from hSaria/3914-interface-filter-no-user
Fixes #3914: Interface filter field when unauthenticated
2020-01-14 08:53:59 -05:00
Saria Hajjar
9d0da0f45a Fixes #3914: Interface filter field when unauthenticated 2020-01-14 06:08:19 +00:00
Jeremy Stretch
7b8e82f321 Fix typo in release notes 2020-01-13 17:30:16 -05:00
Jeremy Stretch
5c047faa1d Delete old squashed migrations 2020-01-13 17:01:54 -05:00
Jeremy Stretch
8f636d9636 Merge pull request #3911 from netbox-community/3801-devicetype-yaml
Closes #3801: Change DeviceType export from CSV to YAML
2020-01-13 15:43:20 -05:00
Jeremy Stretch
ce0e351d76 Changelog for #3801 2020-01-13 15:42:49 -05:00
Jeremy Stretch
f170a579de Add test for DeviceType YAML export 2020-01-13 15:35:01 -05:00
Jeremy Stretch
0dad9f8901 Change DeviceType export from CSV to YAML 2020-01-13 15:10:16 -05:00
Jeremy Stretch
473d67354f Merge branch 'develop' into develop-2.7 2020-01-13 13:49:22 -05:00
Jeremy Stretch
5d7af0fae9 Post-release version bump 2020-01-13 13:26:50 -05:00
Jeremy Stretch
946779000f Merge pull request #3908 from netbox-community/develop
Release v2.6.12
2020-01-13 13:25:21 -05:00
Jeremy Stretch
c3c3000a53 Release v2.6.12 2020-01-13 13:17:43 -05:00
Jeremy Stretch
66daeda85f Merge pull request #3887 from hSaria/3021-cable-tenant-filter
Fixes #3021: Added tenancy filter for cables
2020-01-13 12:09:53 -05:00
Jeremy Stretch
0fd0e76183 Merge pull request #3888 from hSaria/3491-webhook-error-message
Fixes #3491: Include content of webhook error response
2020-01-13 11:33:25 -05:00
Jeremy Stretch
cf480375f6 Merge pull request #3899 from hSaria/3898-cable-str-pk
Fixes #3898: Call str of cable on delete to save PK in id_string
2020-01-13 11:31:18 -05:00
hSaria
736cd709d9 Merge branch 'develop' into 3898-cable-str-pk 2020-01-13 15:40:22 +00:00
Jeremy Stretch
0f42219b4b Merge pull request #3906 from hSaria/3905-powerfeed-divide-by-zero
Fixes #3905: divide by zero on power feeds with low values
2020-01-13 10:32:59 -05:00
Jeremy Stretch
b64f4b93eb Merge pull request #3903 from hSaria/3902-relax-connect
Fixes #3902: relax non-essential required fields
2020-01-13 10:32:09 -05:00
Saria Hajjar
32ffc1b54b Fixes #3905: divide by zero on power feeds with low values 2020-01-13 15:31:35 +00:00
Saria Hajjar
608006ee77 Set the private pk after super save 2020-01-13 15:21:37 +00:00
Saria Hajjar
3d78a67343 Store a private copy of the pk during init and use that with __str__ 2020-01-13 14:57:21 +00:00
Jeremy Stretch
2f98f133bb Merge pull request #3896 from hSaria/3895-elevations-keyerror
Fixes #3895: Elevations filter regression
2020-01-13 09:44:57 -05:00
Saria Hajjar
fe0fbeab49 Fixes #3902: relax non-essential required fields 2020-01-13 12:05:06 +00:00
kobayashi
e3aacb183b optimize query 2020-01-12 16:44:15 -05:00
Saria Hajjar
49fa243b4f Added post-delete cable ID test 2020-01-12 11:21:02 +00:00
Saria Hajjar
a2308b9c99 Fixes #3898: Call str of cable on delete to save PK in id_string 2020-01-12 11:08:13 +00:00
Saria Hajjar
422c6bad5b Fixes #3895: Elevations filter regression 2020-01-11 15:36:58 +00:00
Jeremy Stretch
db57d3830f Merge pull request #3890 from netbox-community/3092-reorganize-models
Closes #3092: Refactor dcim/models.py
2020-01-10 15:44:07 -05:00
Jeremy Stretch
b7e78028ce Closes #3891: Add local_context_data filter for virtual machines 2020-01-10 15:34:38 -05:00
Jeremy Stretch
ca13045515 Closes #3092: Split DCIM models into separate files for easier management 2020-01-10 14:22:22 -05:00
kobayashi
2e9f21e222 Filter muiltiple ipaddress terms 2020-01-10 14:09:25 -05:00
Jeremy Stretch
9f627fd0d3 Merge branch 'develop' into develop-2.7 2020-01-10 13:33:51 -05:00
Jeremy Stretch
509a115f68 Extend section regarding test adaptation 2020-01-10 12:24:47 -05:00
Jeremy Stretch
69a696a8d6 Fix graph:type choices under /api/extras/_choices/ 2020-01-10 12:18:56 -05:00
Jeremy Stretch
830a51d9f5 Merge pull request #3889 from netbox-community/3520-graph-template-language
Fixes #3520: Add template_language to extras.Graph
2020-01-10 11:59:05 -05:00
Jeremy Stretch
3c247ac47d Changelog for #3520 2020-01-10 11:53:29 -05:00
Jeremy Stretch
123a58bf7d Add tests for Graph rendering 2020-01-10 11:51:14 -05:00
Saria Hajjar
f20d16f188 Fixes #3491: include content of webhook error response 2020-01-10 16:42:02 +00:00
Jeremy Stretch
9399652dd0 Add template_language field to Graph 2020-01-10 11:28:50 -05:00
Saria Hajjar
f4514034b8 Fixes #3021: Added tenancy filter to cables 2020-01-10 15:59:56 +00:00
Jeremy Stretch
6bc8f2e50b Fixes #3882: Fix filtering of devices by rack group 2020-01-10 10:21:11 -05:00
Jeremy Stretch
fc1245c49d Merge pull request #3867 from hSaria/3668-address-assign-dns-filter
Fixes #3668: use `q` to search when assigning IP
2020-01-10 10:08:31 -05:00
Jeremy Stretch
4be7ca0c78 Merge branch 'develop' into 3668-address-assign-dns-filter 2020-01-10 09:43:35 -05:00
Jeremy Stretch
cb91c9231d Merge pull request #3865 from hSaria/3623-interface-word-expansion
Fixes #3623: Word expansion for interfaces
2020-01-10 09:41:42 -05:00
Jeremy Stretch
03b22594e8 Merge pull request #3881 from netbox-community/3729-filterset-naming
Fixes #3729: Standardize FilterSet names
2020-01-10 08:58:17 -05:00
hSaria
a5413a5484 Merge branch 'develop' into 3623-interface-word-expansion 2020-01-10 11:55:27 +00:00
Saria Hajjar
71120d9899 Added tests for alphanumeric 2020-01-10 11:54:43 +00:00
Saria Hajjar
acb66c7dc0 Negative tests for expand_ipaddress_pattern 2020-01-10 11:21:37 +00:00
Saria Hajjar
2eba84dad5 Added tests for IPv6 2020-01-10 11:06:01 +00:00
Saria Hajjar
fe89982d4e Removed redundant list call 2020-01-10 10:26:46 +00:00
Jeremy Stretch
528b345f57 Move TenancyFilterSet to filters.py 2020-01-09 21:05:38 -05:00
Jeremy Stretch
e3807a8937 Update filterset naming for global search view 2020-01-09 21:02:14 -05:00
Jeremy Stretch
da0ac4ff1e Rename filter variables for utility views 2020-01-09 20:57:13 -05:00
Jeremy Stretch
49a6a36f4c Renamed virtualization FilterSets 2020-01-09 20:42:32 -05:00
Jeremy Stretch
a77fadd114 Renamed tenancy FilterSets 2020-01-09 20:40:32 -05:00
Jeremy Stretch
15e1f62919 Renamed secrets FilterSets 2020-01-09 20:38:59 -05:00
Jeremy Stretch
83c0d1ef44 Renamed ipam FilterSets 2020-01-09 20:37:26 -05:00
Jeremy Stretch
97654b7585 Renamed extras FilterSets 2020-01-09 20:35:07 -05:00
Jeremy Stretch
0767de205e Renamed dcim FilterSets 2020-01-09 20:30:40 -05:00
Jeremy Stretch
847cf9d038 Renamed circuits FilterSets 2020-01-09 20:25:33 -05:00
Jeremy Stretch
0296aa240a Clean up Stale bot config formatting 2020-01-09 20:14:31 -05:00
Jeremy Stretch
d88b3456c4 Add configuration file for GitHub Stale bot 2020-01-09 20:13:21 -05:00
Jeremy Stretch
789cf827f2 Merge pull request #3879 from hSaria/3876-asn-field-bounds
Fixes #3876: Min/max values for ASN field
2020-01-09 17:03:29 -05:00
Saria Hajjar
6c19c88e99 Replaced ASN bounds with constants 2020-01-09 21:58:38 +00:00
Jeremy Stretch
c1ed2b6068 Merge pull request #3875 from hSaria/3393-provider-circuit-paginate
Fixes #3393: Paginate circuits at the provider details view
2020-01-09 16:52:19 -05:00
Jeremy Stretch
790cfd7b5b Fix CableTable status coloring 2020-01-09 16:19:47 -05:00
Jeremy Stretch
dc5f5efcfe Fixes #3878: Fix database migration for cable status field 2020-01-09 16:16:24 -05:00
Saria Hajjar
4eacc57522 Fixes #3876: set min and max values for ASN field 2020-01-09 21:12:35 +00:00
Jeremy Stretch
0527626709 Update filter tests for v2.7 2020-01-09 16:03:41 -05:00
Jeremy Stretch
a2ead6af94 Merge branch 'develop' into develop-2.7 2020-01-09 15:27:06 -05:00
Saria Hajjar
1e740a70f7 Corrected placement of changelog 2020-01-09 20:23:16 +00:00
Saria Hajjar
94a7d8e493 Hid the provider column 2020-01-09 20:15:22 +00:00
Saria Hajjar
883655ce71 Fixes #3393: Paginate circuits at the provider details view 2020-01-09 20:10:51 +00:00
Jeremy Stretch
1d3651e255 Use ChoiceSet.values() for access to raw values 2020-01-09 14:56:33 -05:00
Jeremy Stretch
fe490d144a Fixes #3868: Fix creation of interfaces for virtual machines 2020-01-09 14:54:25 -05:00
Jeremy Stretch
40fe6666e3 Closes #3841: Add California-style power connectors 2020-01-09 14:10:37 -05:00
Jeremy Stretch
2a2bc66841 Closes #3842: Add RJ-12 console port type 2020-01-09 13:58:41 -05:00
Jeremy Stretch
6019260374 Merge pull request #3873 from hSaria/3872-limit-related-ips
Fixes #3872: Limit related IPs table
2020-01-09 13:53:59 -05:00
Jeremy Stretch
e5c5a1a101 Fixes #3849: Fix ordering of models when dumping data to JSON 2020-01-09 13:28:39 -05:00
Saria Hajjar
c13b9d8798 Added tests for IPv4 2020-01-09 18:26:10 +00:00
hSaria
03b10b6f73 Merge branch 'develop' into 3872-limit-related-ips 2020-01-09 17:18:42 +00:00
Saria Hajjar
67f4d8fab5 Replaced with pagination 2020-01-09 17:16:58 +00:00
Jeremy Stretch
7e0073d6f5 Merge pull request #3863 from hSaria/2113-napalm-settings
Fixes #2113: NAPALM driver settings
2020-01-09 11:56:32 -05:00
Jeremy Stretch
c66dca399b Merge pull request #3860 from hSaria/1982-swagger-napalm
Fixes #1982: Swagger NAPALM documentation
2020-01-09 11:53:20 -05:00
Saria Hajjar
9d085ad83a Changed NAPALM- prefix to X-NAPALM- 2020-01-09 16:48:26 +00:00
Saria Hajjar
ad565e55f1 Removed exception for empty methods
I'll create a seperate ticket for that
2020-01-09 16:40:13 +00:00
Saria Hajjar
46c712e735 Moved NAPALM parameter to decorator 2020-01-09 16:39:13 +00:00
Jeremy Stretch
989d6f5af3 Merge pull request #3871 from hSaria/3864-disallow-0-masks
Fixes #3864: Disallow /0 masks
2020-01-09 11:37:19 -05:00
Saria Hajjar
86865b91f8 Added changelog for 3009
again as I accidentally removed it while merging
2020-01-09 16:32:01 +00:00
hSaria
b53480dd6a Merge branch 'develop' into 3668-address-assign-dns-filter 2020-01-09 16:31:09 +00:00
Saria Hajjar
581ed52b24 Added changelog for 3009 2020-01-09 16:30:13 +00:00
Saria Hajjar
472486acd6 Changed to q filter 2020-01-09 16:26:11 +00:00
Jeremy Stretch
92ec4bd22f Merge pull request #3859 from hSaria/3440-total-cable-length
Fixes #3440: Total cable trace length
2020-01-09 10:55:30 -05:00
Jeremy Stretch
959a0da0ed Merge pull request #3838 from hSaria/3090-interface-filtering
Fixes #3090: Interface filtering
2020-01-09 10:05:04 -05:00
hSaria
b23eaeca54 Merge branch 'develop' into 3090-interface-filtering 2020-01-09 14:56:36 +00:00
hSaria
4f9271e9ff Merge branch 'develop' into 3440-total-cable-length 2020-01-09 14:55:34 +00:00
hSaria
094553dbe7 Merge branch 'develop' into 3623-interface-word-expansion 2020-01-09 14:54:58 +00:00
hSaria
60e4812b32 Merge branch 'develop' into 2113-napalm-settings 2020-01-09 14:54:31 +00:00
hSaria
40625d1299 Merge branch 'develop' into 3668-address-assign-dns-filter 2020-01-09 14:53:32 +00:00
Jeremy Stretch
c9ec8b71e0 Merge pull request #3821 from hSaria/2365-show-available-toggle
Fixes #2598: Toggle for showing available prefixes/ip addresses
2020-01-09 09:52:10 -05:00
Saria Hajjar
73e456495f Fixes #3872: Limit related IPs table 2020-01-09 14:48:21 +00:00
Jeremy Stretch
54227ca9c7 Fixes #3851: Allow passing initial data to custom script forms 2020-01-09 09:41:10 -05:00
hSaria
f3b323536e Merge branch 'develop' into 3864-disallow-0-masks 2020-01-09 14:35:26 +00:00
Saria Hajjar
6537f35176 Fixes #3864: Disallow /0 masks 2020-01-09 14:33:49 +00:00
Jeremy Stretch
b36d0ca3fc Merge pull request #3858 from hSaria/3857-group-custom-link
Fixes #3857: Fix group custom links rendering
2020-01-09 09:28:03 -05:00
Jeremy Stretch
99809109ab Merge pull request #3866 from netbox-community/3834-filter-tests
Add FilterSet tests for all apps
2020-01-09 08:57:27 -05:00
Saria Hajjar
1cdbfd6d60 Fixes #3668: search address by DNS name when assigning 2020-01-09 10:00:02 +00:00
Jeremy Stretch
4030e5ec24 Add filter tests for extras 2020-01-08 21:41:32 -05:00
Jeremy Stretch
4151e52802 Clean up filter imports 2020-01-08 17:20:31 -05:00
Jeremy Stretch
b1e8145ffb Standardize usage of self.filterset for test cases 2020-01-08 17:06:39 -05:00
Jeremy Stretch
c04d8ca5a7 Add tests for PowerPanel and PowerFeed filters 2020-01-08 15:56:42 -05:00
Jeremy Stretch
e312c30822 Add CableFilter test 2020-01-08 15:30:56 -05:00
Jeremy Stretch
40c30baffa Add tests for InventoryItem, VirtualChassis filters 2020-01-08 14:31:59 -05:00
Jeremy Stretch
bca7435a5a Add remaining tests for device component filters 2020-01-08 14:01:31 -05:00
Saria Hajjar
396bb28967 Added example and handled invalid ranges gracefully 2020-01-08 17:28:31 +00:00
Saria Hajjar
eb40275427 Fixes #3623: Word expansion for interfaces 2020-01-08 17:23:09 +00:00
hSaria
8519f546a6 Merge branch 'develop' into 3857-group-custom-link 2020-01-08 16:47:57 +00:00
Jeremy Stretch
e9b2ad9f5c Fix DeviceTestCase.test_cluster 2020-01-08 11:22:07 -05:00
Jeremy Stretch
39fba4f05d Fix InterfaceTestCase.test_mac_address 2020-01-08 11:19:13 -05:00
Jeremy Stretch
38c16d71b4 Merge branch 'develop' into 3834-filter-tests 2020-01-08 11:14:52 -05:00
Jeremy Stretch
8fef6edb27 Fixes #3862: Allow filtering device components by multiple device names 2020-01-08 11:12:44 -05:00
Jeremy Stretch
5cac900380 Add console port, console server port filter tests 2020-01-08 11:04:50 -05:00
Saria Hajjar
f49467bcb5 Corrected optional arg assignment 2020-01-08 16:01:18 +00:00
Saria Hajjar
98a66f7fbe NAPALM settings changelog 2020-01-08 15:55:36 +00:00
Saria Hajjar
ce8d470860 Added NAPALM documentation 2020-01-08 15:54:09 +00:00
Saria Hajjar
dc475f4755 Fixes #2113: Adjust NAPALM settings with headers 2020-01-08 15:53:48 +00:00
Jeremy Stretch
a7982bb0e1 Add device filter tests 2020-01-08 09:50:22 -05:00
Saria Hajjar
ea05b5b606 Fixes #1982: Swagger NAPALM documentation 2020-01-08 13:34:46 +00:00
Saria Hajjar
996d49de67 Fixes #3440: Total cable trace length 2020-01-08 10:49:58 +00:00
Saria Hajjar
74997a18a5 Fixes #3857: Fix group custom links rendering 2020-01-08 10:14:48 +00:00
Jeremy Stretch
832fd49339 Add DeviceType filter tests 2020-01-07 17:13:05 -05:00
Jeremy Stretch
acb2f32304 Add tests for DCIM filters 2020-01-07 13:53:26 -05:00
Saria Hajjar
32f39e10c9 Changed default to showing available 2020-01-07 17:58:30 +00:00
hSaria
190e683654 Removed cookie-based storage; now based on request 2020-01-07 17:18:36 +00:00
Jeremy Stretch
770f4c962c Fixes #3856: Allow filtering VM interfaces by multiple MAC addresses 2020-01-07 10:31:44 -05:00
Jeremy Stretch
227921e0a0 Add tests for virtualization filters 2020-01-07 10:19:21 -05:00
Jeremy Stretch
39d0261d8a Add tests for tenancy filters 2020-01-07 09:41:43 -05:00
Jeremy Stretch
f267a532f6 Add filter tests for secrets 2020-01-07 09:35:22 -05:00
Jeremy Stretch
e7ee4486a5 Fixes #3853: Fix device role link on config context view 2020-01-07 09:08:31 -05:00
Saria Hajjar
6a3cd83efc Moved regex note to tooltip 2020-01-07 11:09:39 +00:00
Saria Hajjar
a7ec0c14f7 Move toggles js code to static 2020-01-07 11:09:31 +00:00
Jeremy Stretch
05bfe94d3e Add remaining IPAM filter tests 2020-01-06 21:35:34 -05:00
Jeremy Stretch
8d0aaa4ec1 Add IPAM filter tests (WIP) 2020-01-06 17:42:17 -05:00
Jeremy Stretch
4b5c4b7be5 Initial work on filter tests 2020-01-06 15:39:02 -05:00
Saria Hajjar
18333973aa Merge branch '3090-interface-filtering' of https://github.com/hSaria/netbox into 3090-interface-filtering 2020-01-06 20:05:25 +00:00
Saria Hajjar
07a1baef13 Limit toggle selector to visible input fields 2020-01-06 20:05:07 +00:00
Jeremy Stretch
15545b70d6 Merge pull request #3814 from hSaria/3589-interface-tagged-vlans
Fixes #3589: Interface VLAN filtering
2020-01-06 13:20:14 -05:00
hSaria
cfb8b3cf56 Merge branch 'develop' into 3090-interface-filtering 2020-01-06 15:19:46 +00:00
hSaria
206732eb62 Merge branch 'develop' into 2365-show-available-toggle 2020-01-06 15:18:57 +00:00
Jeremy Stretch
258cc4b50e Merge pull request #3846 from hSaria/2050-image-preview
Fixes #2050: Image preview
2020-01-06 10:18:18 -05:00
hSaria
d1f81783ef Merge branch 'develop' into 3589-interface-tagged-vlans 2020-01-06 15:18:06 +00:00
Jeremy Stretch
9bd2af48a3 Merge branch 'develop' into 2050-image-preview 2020-01-06 10:12:13 -05:00
Jeremy Stretch
d4df965f46 Merge pull request #3845 from hSaria/3187-elevation-rack-filter
Fixes #3187: Elevation rack filter
2020-01-06 10:06:20 -05:00
Saria Hajjar
7dddd4734c Updated changelog 2020-01-05 09:11:58 +00:00
Saria Hajjar
c45daca5f2 Removed changes that will be covered in #3840 2020-01-05 09:10:46 +00:00
Saria Hajjar
067af26892 Changelog (may conflict with other merges) 2020-01-04 18:19:05 +00:00
Saria Hajjar
792f38334a Fixes #2050: Image preview for attachments 2020-01-04 18:17:41 +00:00
Saria Hajjar
dba40cd6bc Changelog (may conflict because adding headers) 2020-01-04 13:32:07 +00:00
Saria Hajjar
4b19073b8b Fixed #3187: Rack multi-selection field 2020-01-04 13:30:31 +00:00
Saria Hajjar
28eca9a026 Forgot le seperator 2020-01-03 20:12:21 +00:00
Saria Hajjar
3556051d14 Height was a touch off 2020-01-03 19:58:41 +00:00
Saria Hajjar
e1d1f522ff Closes #3090: Filter field for interface 2020-01-03 19:38:51 +00:00
Saria Hajjar
04f3e58ab4 Line seperator 2020-01-03 19:27:02 +00:00
Jeremy Stretch
1f175031bd #3455: Make ClusterFilterForm a TenancyFilterForm 2020-01-03 14:26:53 -05:00
Saria Hajjar
e1c61c5019 Changelog 2020-01-03 19:25:33 +00:00
Saria Hajjar
1c0de0093b Merge remote-tracking branch 'netbox-community/develop' into 2365-show-available-toggle 2020-01-03 19:24:44 +00:00
Saria Hajjar
9d8ab81e3a Removed changelog (temporarily while merging) 2020-01-03 19:24:39 +00:00
Jeremy Stretch
6e49a0ba6e Merge branch 'develop' into develop-2.7 2020-01-03 14:21:53 -05:00
Saria Hajjar
fa55571503 Merge remote-tracking branch 'netbox-community/develop' into 3589-interface-tagged-vlans 2020-01-03 19:19:12 +00:00
Jeremy Stretch
feb04f0401 Post-release version bump 2020-01-03 14:01:10 -05:00
Jeremy Stretch
5c07b6dc1d Merge pull request #3837 from netbox-community/develop
Release v2.6.11
2020-01-03 14:00:10 -05:00
Jeremy Stretch
e3b448b7ad Release v2.6.11 2020-01-03 13:55:43 -05:00
Jeremy Stretch
57f199f899 Fixes #3833: Add region and region_id filters where missing (#3836) 2020-01-03 13:52:50 -05:00
Jeremy Stretch
b38bb64c81 Fixes #3831: Fix API-driven filter field rendering (#3812 regression) 2020-01-03 11:25:22 -05:00
Jeremy Stretch
1d63a30b7a Merge branch 'develop' into develop-2.7 2020-01-02 17:21:15 -05:00
Jeremy Stretch
c2dc243c7c Post-release version bump 2020-01-02 17:08:04 -05:00
Jeremy Stretch
25c3c1b431 Merge pull request #3829 from netbox-community/develop
Fix v2.6.10 release date
2020-01-02 17:05:21 -05:00
Jeremy Stretch
156fbae7d3 Fix v2.6.10 release date 2020-01-02 17:04:20 -05:00
Jeremy Stretch
a0ae7a227d Merge pull request #3828 from netbox-community/develop
Release v2.6.10
2020-01-02 17:02:52 -05:00
Jeremy Stretch
9ef3e68479 Release v2.6.10 2020-01-02 17:01:05 -05:00
Jeremy Stretch
435d248645 #3122: Allow multiple selections 2020-01-02 16:56:14 -05:00
Jeremy Stretch
53db5090c1 #3827: Fix erroneous filter class 2020-01-02 16:55:36 -05:00
Jeremy Stretch
caa062c8ba Merge pull request #3826 from hSaria/3122-connection-device-select2
Fixes #3122: Select2 for device field
2020-01-02 16:39:50 -05:00
Saria Hajjar
240bbc2944 Select2 site widget 2020-01-02 21:28:06 +00:00
Saria Hajjar
a3861ed492 Update device filters to use IDs 2020-01-02 21:21:52 +00:00
Saria Hajjar
82c70302fd Merge branch 'develop' into 3122-connection-device-select2 2020-01-02 20:40:19 +00:00
Jeremy Stretch
80d1f80b61 Fixes #3827: Allow filtering console/power/interface connections by device ID 2020-01-02 13:44:18 -05:00
hSaria
d3c6caf8a8 Limit tagged validation to tagged interfaces
Co-Authored-By: Jeremy Stretch <jeremy.stretch@networktocode.com>
2020-01-02 17:52:22 +00:00
Saria Hajjar
a707204f98 Select2 for device field 2020-01-02 17:46:37 +00:00
Jeremy Stretch
523a1388db Correct release notes 2020-01-02 11:56:29 -05:00
Jeremy Stretch
970586b07b Merge pull request #3818 from hSaria/2233-move-inventoryitem
Closes #2233: Ability to move inventory items between devices
2020-01-02 11:55:18 -05:00
Saria Hajjar
28ae6849b4 Templatized show_available toggle 2020-01-02 16:29:11 +00:00
Saria Hajjar
8e3a371688 Added default to cookie 2020-01-02 16:19:12 +00:00
Saria Hajjar
2a219eff23 is not None not needed as the value 'false' is a string 2020-01-02 16:13:47 +00:00
Saria Hajjar
f81641ae96 Corrected ticket number 2020-01-02 15:48:30 +00:00
Jeremy Stretch
4f0d3e6b32 Merge pull request #3820 from hSaria/3819-cf-boolean-select2
Select2 for custom fields
2020-01-02 10:11:32 -05:00
Jeremy Stretch
77d1ac8b07 Merge pull request #3817 from hSaria/2988-group-create-warn
Closes #2988
2020-01-02 10:10:11 -05:00
Jeremy Stretch
5d0ac02704 Merge pull request #3816 from hSaria/3815-select2-width
Fixes #3815: Select2 width handling via theme
2020-01-02 10:08:56 -05:00
Jeremy Stretch
fc5d07bb13 Merge pull request #3813 from hSaria/3812-optimize-select-api
Fixes #3812: Only preload selected options for API-based select
2020-01-02 10:05:06 -05:00
Jeremy Stretch
395f23e1d3 Fix for #3822 2020-01-02 09:47:02 -05:00
Jeremy Stretch
dd85448451 Fixes #3822: Fix exception when editing a device bay (regression from #3596) 2020-01-02 09:26:38 -05:00
hSaria
6a7af22dea Merge branch 'develop' into 2365-show-available-toggle 2020-01-02 09:18:53 +00:00
Saria Hajjar
37bc17d3a2 Fixes #2365: Toggle for showing available prefixes/ip addresses 2020-01-02 09:16:18 +00:00
Saria Hajjar
ca131e5b2a Select2 for custom fields 2020-01-01 23:46:51 +00:00
Saria Hajjar
c75795ceda Ability to move inventory items between devices 2020-01-01 23:28:20 +00:00
Saria Hajjar
7dc0591e3e Note about the group existance 2020-01-01 22:38:02 +00:00
Saria Hajjar
cfa078c929 Added theme to select2 of tags 2020-01-01 21:14:38 +00:00
Saria Hajjar
57ea73db46 Turn off Select2 static width calculation 2020-01-01 21:01:08 +00:00
Saria Hajjar
7ad9e8a2fb More informative error message 2020-01-01 19:53:13 +00:00
Saria Hajjar
1a57120b78 3589 changelog 2020-01-01 17:43:39 +00:00
Saria Hajjar
d267aeb621 Filter VLANs to only those in the current site or global 2020-01-01 17:34:26 +00:00
Saria Hajjar
a110b0badb Removed no-longer-used choices (now handled via API-based select) 2020-01-01 16:43:21 +00:00
Saria Hajjar
242ae9eb91 Comment clarification 2020-01-01 16:04:08 +00:00
Saria Hajjar
53625e0dea Fixes #3812: Only preload selected options for API-based select 2020-01-01 15:54:00 +00:00
Saria Hajjar
aa4f73ffbf Removed trailing space 2020-01-01 12:09:51 +00:00
Jeremy Stretch
8c7b0cf670 Close #2892: Extend admin UI to allow deleting old report results 2019-12-31 16:11:47 -05:00
Saria Hajjar
05570ae4ad Clean tagged VLANs 2019-12-31 20:47:13 +00:00
Jeremy Stretch
0cf94cff16 Closes #3062: Add assigned_to_interface filter for IP addresses 2019-12-31 15:24:00 -05:00
Jeremy Stretch
b5455ed882 Closes #3461: Fail gracefully on custom link rendering exception 2019-12-31 15:04:56 -05:00
Jeremy Stretch
8a4293a4cc Introduce render_jinja2() convenience function 2019-12-31 14:00:55 -05:00
Jeremy Stretch
f649b9f04f Fixes #3106: Restrict queryset of chained fields when form validation fails 2019-12-31 12:41:02 -05:00
Jeremy Stretch
5caa04ef2b Fixes #3811: Fix filtering of racks by group on device list 2019-12-31 11:35:18 -05:00
Jeremy Stretch
f2c49063f8 Fixes #3809: Filter platform by manufacturer when editing devices 2019-12-31 11:25:42 -05:00
Jeremy Stretch
ea2351e902 Merge pull request #3804 from hSaria/3803-svg-logo
Fixes 3803
2019-12-30 14:12:44 -05:00
hSaria
8effb54c89 Converted text to path 2019-12-30 18:28:39 +00:00
hSaria
66c99acb9e Converted text to path 2019-12-30 18:28:12 +00:00
Jeremy Stretch
2e5a326315 Merge pull request #3802 from hSaria/3762-datetime-selectors
Fixes 3762
2019-12-30 12:32:08 -05:00
Jeremy Stretch
b5177c608d Merge branch 'develop' into 3762-datetime-selectors 2019-12-30 12:31:50 -05:00
Jeremy Stretch
be7d5a2310 Merge pull request #3807 from hSaria/3712-scroll-offset
Fixes 3712
2019-12-30 11:40:43 -05:00
Jeremy Stretch
65444899af Merge pull request #3798 from steffann/3797-802.1q-vlan-fields
Fix values of mode field
2019-12-30 11:26:15 -05:00
Jeremy Stretch
5230127fde Merge pull request #3800 from kobayashi/3788
implement 3788
2019-12-30 11:23:51 -05:00
Saria Hajjar
405320d8ab Changelog 2019-12-29 21:22:14 +00:00
Saria Hajjar
2f2e193cf9 Account for the header when hash-scrolling 2019-12-29 21:20:02 +00:00
Saria Hajjar
1fc206b9c5 Replace doc logo with svg 2019-12-29 14:10:31 +00:00
Saria Hajjar
44e1a477f2 Fixed Y-coordinate off by 10 2019-12-29 14:06:41 +00:00
Saria Hajjar
e62302c979 Fixes #3803 2019-12-29 13:41:00 +00:00
Saria Hajjar
51b0fe4596 Changelog for 3762 2019-12-29 08:50:08 +00:00
Saria Hajjar
7399aa0c5e Add datetime widgets 2019-12-28 22:55:00 +00:00
Saria Hajjar
aa4588f9ba Load flatpickr using selectors (classes) 2019-12-28 21:33:07 +00:00
Saria Hajjar
4c2e2e0fa3 Include Flatpickr library globally 2019-12-28 21:32:40 +00:00
Saria Hajjar
6dea8ddbce Flatpickr library statics 2019-12-28 21:31:21 +00:00
kobayashi
e6623a6ca8 implement 3788 2019-12-27 16:17:17 -05:00
Sander Steffann
020e485196 Fix values of mode field 2019-12-27 20:42:16 +01:00
Jeremy Stretch
0c5f535689 Merge pull request #3793 from struppinet/develop
Closes #3663: add Filter Tests
2019-12-27 14:14:55 -05:00
Jeremy Stretch
ae9d0d894a Fixes #3695: Include A/Z termination sites for circuits in global search 2019-12-27 14:04:03 -05:00
Jeremy Stretch
14401c30b6 Update contributing guide to reference the issue intake policy 2019-12-27 13:48:41 -05:00
struppi
fbb93c72d0 Closes #3663: improve tests 2019-12-26 22:21:05 +01:00
Jeremy Stretch
280f31955a Merge branch 'master' into develop-2.7 2019-12-26 10:39:07 -05:00
Jeremy Stretch
5fedcd1f4e Fixes #3789: Typo 2019-12-26 10:19:32 -05:00
Jeremy Stretch
adeee0bf5c Docs & changelog for #3705 2019-12-26 10:16:53 -05:00
Jeremy Stretch
84a2b726f5 Merge pull request #3775 from steffann/3705-make-current-user-available-in-custom-scripts
Add request to Custom Script run, if receiver supports it
2019-12-26 10:04:07 -05:00
struppi
407a60dcc4 Closes #3663: fix PEP errors 2019-12-26 12:26:41 +01:00
struppi
d31507985b Closes #3663: add Filter Tests 2019-12-25 18:41:59 +01:00
Sander Steffann
0174c9747b Implement request passing as a property of Script 2019-12-19 23:35:18 +01:00
Jeremy Stretch
55b503da5b Fixes #3780: Fix AttributeError exception in API docs 2019-12-19 14:04:18 -05:00
Jeremy Stretch
aff4ad0f97 Post-release version bump 2019-12-16 16:33:31 -05:00
Jeremy Stretch
50df3acd26 Merge pull request #3774 from netbox-community/develop
Release v2.6.9
2019-12-16 16:32:00 -05:00
Jeremy Stretch
e53e1e31de Release v2.6.9 2019-12-16 16:30:20 -05:00
Daniel Sheppard
70b09446b6 Merge pull request #3768 from markkuleinio/gunicorn-conf
Change gunicorn.conf remains to gunicorn.py
2019-12-15 21:46:21 -06:00
Markku Leiniö
3a18d1df8c Fix gunicorn.conf remains to gunicorn.py 2019-12-14 21:14:48 +02:00
Jeremy Stretch
01883f92d9 Merge pull request #3765 from netbox-community/3760-template-buttons
Introduce clone, edit, and delete button templatetags
2019-12-13 15:59:33 -05:00
Jeremy Stretch
1acdf58a4b Merge pull request #3764 from kobayashi/3679
fix 3757
2019-12-13 15:57:13 -05:00
Jeremy Stretch
8acd3d0a72 Introduced clone, edit, and delete buttons 2019-12-13 15:54:50 -05:00
kobayashi
1d1cb867cd fix 3679 2019-12-13 14:42:10 -05:00
Jeremy Stretch
b46bfaebc1 Merge pull request #3763 from hSaria/3761-token-copy-button
Fixes #3761: copy button for tokens
2019-12-13 14:16:41 -05:00
Jeremy Stretch
a22c7c1539 Fixes #2358: Respect custom field default values when creating objects via the REST API 2019-12-13 14:15:48 -05:00
hSaria
ea51aa97b7 Update version-2.6.md 2019-12-13 18:08:34 +00:00
hSaria
6a6959d041 Fixes #3761: copy button for tokens 2019-12-13 18:06:14 +00:00
Jeremy Stretch
462cede863 Fixes #2170: Prevent the deletion of a virtual chassis when a cross-member LAG is present 2019-12-13 11:36:31 -05:00
Jeremy Stretch
85c11bbd83 Closes #3441: Move virtual machine results near devices in global search 2019-12-13 10:37:58 -05:00
Jeremy Stretch
77e0564d13 Closes #3152: Include direct link to rack elevations on site view 2019-12-13 10:12:46 -05:00
Jeremy Stretch
85563e21db Remove obsolete initial_data fixtures (no longer maintained) 2019-12-12 14:30:43 -05:00
Jeremy Stretch
9352867cec Fix up the installation docs 2019-12-12 14:27:12 -05:00
Jeremy Stretch
93837c5b9e Merge pull request #3756 from netbox-community/csv-import-tests
CSV import tests
2019-12-12 12:09:31 -05:00
Jeremy Stretch
aaf5523378 Add view tests for device components 2019-12-12 11:58:57 -05:00
Jeremy Stretch
8a22f83bc0 Add virtualization CSV import tests 2019-12-12 11:34:02 -05:00
Jeremy Stretch
7550d53d02 Add tenancy CSV import tests 2019-12-12 11:29:41 -05:00
Jeremy Stretch
821cd58825 Add secrets CSV import tests 2019-12-12 11:26:48 -05:00
Jeremy Stretch
526412a1ba Add IPAM CSV import tests 2019-12-12 10:51:17 -05:00
Jeremy Stretch
fae2469dd7 Add DCIM CSV import tests 2019-12-12 10:30:15 -05:00
Jeremy Stretch
27fd351fc2 Add CSV import tests for circuits 2019-12-12 10:08:49 -05:00
John Anderson
ea5c9df095 fixed svg gradient scaling and css flickering issue 2019-12-12 00:30:22 -05:00
Jeremy Stretch
5aa17bc42a Closes #3706: Increase available_power maximum value on PowerFeed 2019-12-11 21:12:18 -05:00
Jeremy Stretch
7bbd9be389 Tweak elevation font 2019-12-11 21:03:24 -05:00
Jeremy Stretch
dbf9a2b452 Fix bug with rendering devices taller than 1U 2019-12-11 20:19:01 -05:00
Jeremy Stretch
e4b8ea8905 Change render_format to render 2019-12-11 20:05:16 -05:00
Jeremy Stretch
fd8913f09b Fix bug in migration 2019-12-11 20:01:10 -05:00
John Anderson
645383509b change render_format to render for svg elevations 2019-12-11 17:33:58 -05:00
Jeremy Stretch
77a5f6ef81 Touched up the release notes 2019-12-11 17:22:41 -05:00
Jeremy Stretch
2ec7259a69 Rack elevation endpoint should return JSON by default; fix typo 2019-12-11 17:17:20 -05:00
Jeremy Stretch
b6f8c248de Addressed lingering TODOs 2019-12-11 17:07:56 -05:00
Jeremy Stretch
b16be577e3 CSVChoiceField should default to a blank string instead of None 2019-12-11 17:04:48 -05:00
Jeremy Stretch
590bbbce7f Fix bug left over from work on #3569 2019-12-11 16:16:14 -05:00
Jeremy Stretch
577b4593de Changelog for #3664 2019-12-11 16:14:41 -05:00
Jeremy Stretch
44e5a63a2a Merge pull request #3755 from netbox-community/3664-configcontext-tags
3664 configcontext tags
2019-12-11 16:10:48 -05:00
Jeremy Stretch
19363add30 Represent and assign ConfigContext tags by their slugs 2019-12-11 16:04:43 -05:00
Jeremy Stretch
fd88ba65b2 Cleanup for #3664 2019-12-11 15:55:33 -05:00
Jeremy Stretch
ce4a5a38a3 Introduce is_taggable utility function for identifying taggable models 2019-12-11 15:52:35 -05:00
John Anderson
05938d60f0 Merge pull request #3754 from netbox-community/2248-svg-rack-elevations
2248 svg rack elevations
2019-12-11 14:26:32 -05:00
Jeremy Stretch
8b189abd58 Merge pull request #3752 from kobayashi/3664
implement 3664
2019-12-11 14:14:48 -05:00
John Anderson
7f788eaa06 review updates to svg rendering 2019-12-11 13:39:10 -05:00
Jeremy Stretch
9f204f72ef Changelog and documentation for #1814 2019-12-11 11:01:31 -05:00
Jeremy Stretch
e02ac133eb Added import error handling and config vlaidation warning for store config 2019-12-11 10:51:32 -05:00
John Anderson
c09aefd509 updated changelog with deprecation notice of rack units endpoint 2019-12-11 10:39:46 -05:00
John Anderson
e0c81fd837 changelog for #2248 2019-12-11 10:34:44 -05:00
Jeremy Stretch
9a8c8012be Merge pull request #3666 from steffann/1814-Ability_to_use_object_store_for_images
Add support for S3 storage for media
2019-12-11 10:20:09 -05:00
Sander Steffann
f1e75b0fbb Implement storage configuration as suggested by @jeremystretch 2019-12-11 16:09:32 +01:00
John Anderson
b4d724b5ae drf-yasg updates for rack elevations 2019-12-11 09:45:08 -05:00
Sander Steffann
f7a1595ce5 Merge branch '1814-Ability_to_use_object_store_for_images' of github.com:steffann/netbox into 1814-Ability_to_use_object_store_for_images 2019-12-11 15:23:47 +01:00
Sander Steffann
378883df2b Fix code for PEP8 2019-12-11 15:19:32 +01:00
Sander Steffann
dafa2513e3 Add support for S3 storage for media 2019-12-11 15:19:32 +01:00
Jeremy Stretch
3b03d68ac7 Merge pull request #3751 from hSaria/3749-attribute-error
Fixes 3749 attribute error
2019-12-11 08:50:09 -05:00
kobayashi
5710f297f1 implement 3664 2019-12-11 04:58:42 -05:00
hSaria
b57d64c72d Changelog for #3751 2019-12-11 07:24:44 +00:00
hSaria
3b76e0203a Fixes 3749 attribute error 2019-12-11 07:03:39 +00:00
Jeremy Stretch
0d8fd45587 Updated static resources 2019-12-10 15:56:52 -05:00
Jeremy Stretch
01b6e73f9b Update dependency versions for DRF & drf_yasg 2019-12-10 15:39:57 -05:00
Jeremy Stretch
b0fb474aa2 Update dependency versions for v2.7 2019-12-10 15:16:20 -05:00
Jeremy Stretch
0787713298 Add deprecation warning for Python 3.5 2019-12-10 13:44:45 -05:00
Jeremy Stretch
6221bc8f43 Merge pull request #3750 from netbox-community/3655-role-descriptions
Add description field to organizational role models
2019-12-10 13:29:44 -05:00
Jeremy Stretch
a6904dc5d5 Add description field to CircuitType (#3655) 2019-12-10 13:25:14 -05:00
Jeremy Stretch
3d5fb2491a Chnagelog for #3655 2019-12-10 13:09:41 -05:00
Jeremy Stretch
24bdd10b4f Add description field to SecretRole model (#3655) 2019-12-10 13:03:09 -05:00
Jeremy Stretch
7845d9b25f Add description field to Role model (#3655) 2019-12-10 12:59:10 -05:00
Jeremy Stretch
1f288175e4 Add description field to RackRole and DeviceRole models (#3655) 2019-12-10 12:53:28 -05:00
Jeremy Stretch
f0a6c881bc Fix inclusion of legacy IDs on choice fields 2019-12-10 12:07:54 -05:00
Jeremy Stretch
9452cebc6a Merge branch 'develop' into develop-2.7 2019-12-10 11:51:10 -05:00
Jeremy Stretch
3c36bec298 Post-release version bump 2019-12-10 10:50:46 -05:00
Jeremy Stretch
425670f52a Merge pull request #3745 from netbox-community/develop
Release v2.6.8
2019-12-10 10:47:48 -05:00
Jeremy Stretch
6a2651991a Release v2.6.8 2019-12-10 10:42:48 -05:00
Jeremy Stretch
12657ebd7c Cable.status to slug (#3569) 2019-12-10 09:55:10 -05:00
John Anderson
d8dd5f00c1 removed rack elevations viewset 2019-12-10 03:19:26 -05:00
John Anderson
1ec191db92 initial cleanup of rack elevations 2019-12-10 03:18:10 -05:00
John Anderson
20c8abe8da Merge branch 'develop-2.7' into 2248-svg-rack-elevations 2019-12-10 02:59:04 -05:00
Jeremy Stretch
086813fc3e Changelog for #2669 2019-12-09 17:28:21 -05:00
Jeremy Stretch
606a73a547 Merge pull request #3740 from netbox-community/2669-device-vm-names
Allow non-unique device and VM names
2019-12-09 17:26:32 -05:00
Jeremy Stretch
f25e2a1922 Fixes #3644: Fix exception when connecting a cable to a RearPort with no corresponding FrontPort 2019-12-09 15:42:04 -05:00
Jeremy Stretch
740cc8b601 Remove deprecated context parameter from from_db_value 2019-12-09 12:32:51 -05:00
Jeremy Stretch
5ac4a3ba79 Omit default uniqueness validator from VirtualMachineSerializer, which implies required fields 2019-12-09 12:11:42 -05:00
Jeremy Stretch
2e37b19e9f #2269: Allow non-unique VirtualMachine names 2019-12-09 11:59:30 -05:00
Jeremy Stretch
a8dd060e32 #2269: Allow non-unique Device names 2019-12-09 11:41:03 -05:00
Jeremy Stretch
95edec5448 #3722: Tweak ordering of permitted characters to avoid creating a regex range 2019-12-09 10:02:56 -05:00
John Anderson
b0adce998b Merge pull request #3702 from hellerve/rack-elevations-api
Rack elevations API
2019-12-09 01:02:40 -05:00
John Anderson
6fe1b9b37c update openapi field type for choice field value fields to string 2019-12-09 00:41:43 -05:00
hellerve
44b042e3fc dcim api: fix face default value in rackviewset 2019-12-08 18:24:13 +01:00
hellerve
e5b49e25b9 dcim api: add feedback from @jeremystretch to rack elevations api 2019-12-08 18:14:59 +01:00
hellerve
b54a05d255 dcim: make linter happy 2019-12-08 17:59:40 +01:00
hellerve
66b6f586f1 tests: update to reflect absence of utility functions 2019-12-08 17:59:40 +01:00
hellerve
82819d5429 dcim: remove elevation getters 2019-12-08 17:59:38 +01:00
hellerve
bc859c6139 css: purge outdated rack styling 2019-12-08 17:58:36 +01:00
hellerve
e1fdc7773a requirements: fix svgwrite version 2019-12-08 17:58:35 +01:00
hellerve
5d5b7e0dd9 dcim: refactor reservations and make them resizable 2019-12-08 17:58:21 +01:00
hellerve
77890ad775 dcim: add inline stylesheet to rack elevation api view 2019-12-08 17:58:21 +01:00
hellerve
1a9b9f50d8 dcim: fix fonts & texts in svg 2019-12-08 17:58:21 +01:00
hellerve
808f5c95e3 dcim: make front and rear work (references #2248) 2019-12-08 17:58:21 +01:00
hellerve
d11de6d021 dcim: add rack-elevations api endpoint (references #2248) 2019-12-08 17:58:20 +01:00
Jeremy Stretch
88c7d95b08 ClusterForm should inherit from TenancyForm 2019-12-06 16:47:29 -05:00
Jeremy Stretch
2956eff051 Closes #648: Pre-populate forms when selecting "create and add another" 2019-12-06 16:40:39 -05:00
Jeremy Stretch
b05566e96f Implement tag replication for #33 2019-12-06 16:22:56 -05:00
Jeremy Stretch
446acbdf82 Closes #33: Add ability to clone objects (pre-populate form fields) 2019-12-06 16:13:52 -05:00
Jeremy Stretch
f2076c9572 Fixed git commit hook 2019-12-06 12:54:13 -05:00
Jeremy Stretch
d71e6698f4 Extend git commit hook to check for missing schema migrations 2019-12-06 12:42:59 -05:00
Jeremy Stretch
9b26225fdd #3720: Update migration to add powerfeeds to termination_type limit list (does not impact database) 2019-12-06 12:29:31 -05:00
Jeremy Stretch
f8c5ca942a #3722: Update migration with new validator (does not impact database) 2019-12-06 12:19:29 -05:00
Jeremy Stretch
47fefbec07 Default to localhost in example Redis configs (needed for CI to work) 2019-12-06 12:00:51 -05:00
Jeremy Stretch
45917f8014 Closes #3408: Remove WEBHOOKS_ENABLE configuration setting 2019-12-06 11:52:28 -05:00
Jeremy Stretch
dd3e7397a4 Add ITA plug/outlet types (#792) 2019-12-06 11:26:44 -05:00
Jeremy Stretch
7518174374 Closes #3731: Change Graph.type to a ContentType foreign key field 2019-12-06 10:32:59 -05:00
Sander Steffann
02a009b7a7 Don't redefine exception but split the code 2019-12-06 16:32:18 +01:00
Jeremy Stretch
16353ce63c Correct stalebot config file name 2019-12-05 21:43:22 -05:00
Jeremy Stretch
7a4b202064 Fixes #3725: Enforce client validation for minimum service port number 2019-12-05 21:22:34 -05:00
Jeremy Stretch
a97ebc6d4c Fixes #3722: Allow the underscore character in IPAddress DNS names 2019-12-05 21:14:29 -05:00
Jeremy Stretch
9e765b1704 Fixes #3730: Add link to docs page for custom links 2019-12-05 21:07:43 -05:00
Jeremy Stretch
ec9443edb8 Changelog updates 2019-12-05 20:52:30 -05:00
Jeremy Stretch
dcb2c4722c Merge pull request #3732 from netbox-community/3569-api-choice-slugs
Replace API integer API choice values with slugs
2019-12-05 17:53:47 -05:00
Jeremy Stretch
b0c0adf6e7 Adapt device component import forms from #3711 2019-12-05 17:49:44 -05:00
Jeremy Stretch
17898a4c57 Merge branch 'develop-2.7' into 3569-api-choice-slugs 2019-12-05 17:43:11 -05:00
Jeremy Stretch
edbf562803 Annotate all migration operation lists 2019-12-05 17:42:33 -05:00
Jeremy Stretch
5d772d7055 Webhook.http_content_type to slug (#3569) 2019-12-05 17:11:59 -05:00
Daniel Sheppard
8cbd2f5c2d Add list view for device components (#3719)
* Initial Work on #3564

* #3564 - Fixup issue with filter on interface

* #3564 - Fix PEP8 errors

* #3564 - Finalize fields, readjust order, reduce repetition

* #3564 - Update Changelog

* #3564 - Fix extra space

* #3564 - Change interface table ordering

* #3564 - Minor cleanup

* #3564 - Add Import Links

* Fix PEP8
2019-12-05 17:10:49 -05:00
Jeremy Stretch
89e720cb77 ExportTemplate.template_language to slug (#3569) 2019-12-05 17:01:00 -05:00
Jeremy Stretch
2583823e5f Delete obsolete user action types 2019-12-05 16:50:44 -05:00
Jeremy Stretch
33890e6b97 Remain consistent with original action strings (e.g. 'created' instead of 'create') 2019-12-05 16:42:10 -05:00
Jeremy Stretch
a2b0da2608 Fix changelog table action labels 2019-12-05 16:37:22 -05:00
Jeremy Stretch
2bcbcd3458 ObjectChange.action to slug (#3569) 2019-12-05 16:30:15 -05:00
Jeremy Stretch
8efde811e9 Fix PowerFeed field defaults 2019-12-05 16:05:45 -05:00
Jeremy Stretch
4e1ee270cf Extend CustomField migration to update CustomFieldChoice.field.limit_choices_to 2019-12-05 16:02:52 -05:00
Jeremy Stretch
7a3c725f51 Convert BUTTON_CLASS_CHOICES to a ChoiceSet 2019-12-05 15:59:16 -05:00
Jeremy Stretch
fe2c682dc3 Changelog updates 2019-12-05 15:54:29 -05:00
Sander Steffann
adb25fd7d7 822 bulk import of device components (#3711)
Closes #822: CSV import for device components

* Implement CSV import for netbox-community#822

* Comment out default_return_url until there is a proper target

* Fix the default value of `enabled` when not included in the import

* rear_port is definitely required here

* Power Ports don't have a type (yet)

* Add import for console-ports and console-server-ports

* Add import for device-bays
2019-12-05 15:36:11 -05:00
Jeremy Stretch
bfea77baa5 CustomField.filter_logic to slug 2019-12-04 21:09:02 -05:00
Jeremy Stretch
3ff22bea56 CustomField.type to slug 2019-12-04 21:01:50 -05:00
Jeremy Stretch
ca11b9a2f5 VirtualMachine.status to slug 2019-12-04 20:40:18 -05:00
John Anderson
1048d3909b fixes #3724 - allow filtering interfaces by more than one device name 2019-12-04 02:00:08 -05:00
Jeremy Stretch
4ecbfc4e5e Service.protocol to slug (#3569) 2019-11-27 22:27:06 -05:00
Jeremy Stretch
213bd1555a VLAN.status to slug (#3569) 2019-11-27 22:15:59 -05:00
Jeremy Stretch
14a7a33cc2 IPAddress.role to slug (#3569) 2019-11-27 22:09:16 -05:00
Jeremy Stretch
ba8f324b12 IPAddress.status to slug (#3569) 2019-11-27 21:54:01 -05:00
Jeremy Stretch
929c0648d0 Prefix.status to slug (#3569) 2019-11-27 21:46:53 -05:00
Jeremy Stretch
21fe5902a8 PowerOutlet.feed_leg to slug (#3569) 2019-11-27 21:30:11 -05:00
Jeremy Stretch
b2caaa6733 Fixes #3312: Fix validation error when editing power cables in bulk 2019-11-27 09:19:34 -05:00
Jeremy Stretch
15722c1871 Fixes #3720: Correctly indicate power feed terminations on cable list 2019-11-26 16:56:11 -05:00
Jeremy Stretch
1d18948307 Fixes #3709: Prevent exception when importing an invalid cable definition 2019-11-26 16:46:51 -05:00
Jeremy Stretch
8c7f6c62b0 PowerFeed.status to slug (#3569) 2019-11-25 21:22:14 -05:00
Jeremy Stretch
2dc07ca30d PowerFeed.phase to slug (#3569) 2019-11-25 21:14:04 -05:00
Jeremy Stretch
bb8b012397 PowerFeed.supply to slug (#3569) 2019-11-25 21:08:34 -05:00
Jeremy Stretch
62494f295e PowerFeed.type to slug (#3569) 2019-11-25 21:03:11 -05:00
Jeremy Stretch
9872a46583 Rack.outer_unit to slug (#3569) 2019-11-25 20:54:24 -05:00
Jeremy Stretch
4846557d61 Cable.length_unit to slug (#3569) 2019-11-25 20:40:29 -05:00
Jeremy Stretch
79a40e22c9 Cable.type to slug (#3569) 2019-11-25 19:57:13 -05:00
Jeremy Stretch
dead5b42be Front/RearPort.type to slug (#3569) 2019-11-25 19:39:25 -05:00
Jeremy Stretch
bcc34f6099 Device.face to slug (#3569) 2019-11-25 19:23:43 -05:00
Jeremy Stretch
6a451e0c0e Merge pull request #3701 from hSaria/3697-custom-scripts-example-typo
Fixes #3697: Correct field_order attribute name
2019-11-22 08:45:21 -05:00
Jeremy Stretch
5c95927a43 Site.status to slug (#3569) 2019-11-21 22:54:01 -05:00
Jeremy Stretch
3fa4ceadb0 Interface.mode to slug (#3569) 2019-11-21 22:50:01 -05:00
Jeremy Stretch
f93cd17fee Consolidate #3569 field migrations by model 2019-11-21 22:26:35 -05:00
Jeremy Stretch
5f5081f719 Interface.type to slug (#3569) 2019-11-21 22:11:02 -05:00
Jeremy Stretch
180d3d0029 Resolved migration discrepancies when dealing with NULL values 2019-11-21 21:44:30 -05:00
Jeremy Stretch
4e2863e4ec Move CircuitTermination.term_side choices to a ChoiceSet 2019-11-21 21:28:59 -05:00
hSaria
b46e52eccc Fixed #3697: Correct field_order attribute name 2019-11-20 17:03:12 +00:00
Jeremy Stretch
f3a41df395 #3455: Correct related_name on Cluster.tenant 2019-11-18 22:12:29 -05:00
Jeremy Stretch
afd82fd9d3 DeviceType.subdevice_role to slug (#3569) 2019-11-18 22:08:33 -05:00
Jeremy Stretch
fbd12e1887 Create a separate migration for each field 2019-11-18 21:41:04 -05:00
Jeremy Stretch
4f0d82ac16 Standardize migration names for #3569 2019-11-18 21:04:12 -05:00
Jeremy Stretch
88b8cf3360 Tweak migrations to handle NULL values 2019-11-18 20:56:22 -05:00
Jeremy Stretch
a8db07e0a8 Device.face to slug (#3569) 2019-11-16 21:46:07 -05:00
Jeremy Stretch
c79c29e769 Rack.status to slug (#3569) 2019-11-15 22:03:41 -05:00
Jeremy Stretch
e1e09bff9b Correct Rack.type migration logic 2019-11-15 21:50:33 -05:00
Jeremy Stretch
07aa036fe8 Convert RACK_WIDTH_CHOICES to ChoiceSet 2019-11-15 21:33:56 -05:00
Jeremy Stretch
8d27b62114 Rack.status to slug (#3569) 2019-11-15 21:31:57 -05:00
Jeremy Stretch
62b45494b6 Convert all DCIM choice classes to ChoiceSets 2019-11-15 21:17:01 -05:00
Jeremy Stretch
de986ec392 Merge pull request #3687 from kobayashi/3679
fix url expressions
2019-11-14 22:03:03 -05:00
Jeremy Stretch
4b415caad2 Changelog for #3663 2019-11-14 22:01:37 -05:00
Jeremy Stretch
bfede60f3d Rename CreatedUpdatedFilter to CreatedUpdatedFilterSet 2019-11-14 22:00:12 -05:00
Jeremy Stretch
03b8759597 'base_name' deprecated in DRF v3.9.0 2019-11-14 21:58:37 -05:00
Jeremy Stretch
bdd623f82c Merge pull request #3680 from struppinet/develop
Closes #3663: API filter by created, last_updated
2019-11-14 21:57:26 -05:00
kobayashi
3c8083ed7f fix url expressions 2019-11-13 00:48:47 -05:00
kobayashi
5904f1f8ee Changelog for #3329 2019-11-12 09:47:31 -05:00
kobayashi
cc848a3f01 Merge pull request #3684 from bbock/docs-remove-p3p
Docs: Remove obsolete P3P policy
2019-11-12 09:38:46 -05:00
Bernhard Bock
1aaa101fb5 Docs: Remove obsolete P3P policy
P3P is obsolete (https://www.w3.org/TR/P3P11/), therefore the HTTP header
should be removed from the recommended config in the installation docs.
2019-11-08 15:13:32 +01:00
struppi
0319450643 Closes #3663: rename filter class 2019-11-07 22:41:09 +01:00
struppi
099774d667 Closes #3663: PEP8 fixes 2019-11-07 22:38:51 +01:00
Jeremy Stretch
e09ad6915f Circuit.status (#3569) 2019-11-07 11:11:10 -05:00
Jeremy Stretch
a2a6b754be Introduce ChoiceSet class for field choices 2019-11-07 10:33:10 -05:00
Jeremy Stretch
d392982fe7 Extend DeviceType import test with power port/outlet types 2019-11-06 16:59:01 -05:00
Jeremy Stretch
8cb7eb0382 Convert console port types to slugs (#3569) 2019-11-06 16:56:46 -05:00
Jeremy Stretch
48dcd2d2b9 Merge pull request #3675 from netbox-community/792-power-types
Introduce power port and outlet types
2019-11-06 16:12:37 -05:00
Jeremy Stretch
6ccaa0d9bd Initial work on #792 2019-11-06 15:30:54 -05:00
Jeremy Stretch
b1761f7856 #3139: Add a message indicating why the user is redirected 2019-11-06 10:01:42 -05:00
Jeremy Stretch
1bc38f66ae Changelog entries for #3139 and #3457 2019-11-06 09:58:30 -05:00
Jeremy Stretch
b4433a8471 Merge pull request #3667 from steffann/3139-disable-user-password-change-if-come-in-with-ldap-auth
Hide password change page when user is logged in using LDAP
2019-11-06 09:57:25 -05:00
Jeremy Stretch
053f49c76a Merge pull request #3673 from ananace/cable-color-display
3457 Display cable colors in device interface list
2019-11-06 09:53:59 -05:00
Jeremy Stretch
fbde6187ea Fixes #3669: Include weight field in prefix/VLAN role form 2019-11-06 09:39:21 -05:00
Jeremy Stretch
5eb5c4bac5 Fixes #3674: Include comments on PowerFeed view 2019-11-06 09:26:49 -05:00
Jeremy Stretch
fb4283ed53 Move alternative installations to the GitHub wiki 2019-11-06 09:05:12 -05:00
Alexander Olofsson
bbd65988f9 3457 Display cable colors in device interface list 2019-11-06 10:15:55 +01:00
struppi
a11fa44170 Closes #3663: fix inheritance error 2019-11-04 21:00:44 +01:00
struppi
99a542e4e4 Closes #3663: API filter by created, last_updated 2019-11-04 20:51:56 +01:00
Sander Steffann
a6f2d5b414 Fix code for PEP8 2019-11-03 16:12:39 +03:00
Sander Steffann
7f779e3942 Hide password change page when user is logged in using LDAP 2019-11-03 16:05:53 +03:00
Sander Steffann
7306d56902 Add support for S3 storage for media 2019-11-03 14:16:12 +03:00
Jeremy Stretch
b8f1585976 Merge branch 'develop' into develop-2.7 2019-11-01 16:19:36 -04:00
Jeremy Stretch
a2a83a4a4c Post-release version bump 2019-11-01 15:54:17 -04:00
Jeremy Stretch
9f7313e492 Merge pull request #3661 from netbox-community/develop
Release v2.6.7
2019-11-01 15:43:38 -04:00
Jeremy Stretch
f6fbf66c8c Merge branch 'master' into develop 2019-11-01 15:39:24 -04:00
Jeremy Stretch
3deedfd177 Release v2.6.7 2019-11-01 15:37:05 -04:00
Jeremy Stretch
e9d5ff095c Suppress migration messages during tests; fix typo 2019-11-01 15:08:59 -04:00
Jeremy Stretch
43d6bfa15f Corrected test 2019-11-01 15:08:20 -04:00
Jeremy Stretch
875e09013c Move TreeNodeMultipleChoiceFilter tests to utilities (follow-up to #3616) 2019-11-01 15:01:24 -04:00
Jeremy Stretch
ee854eff2c Changelog for #3357 2019-11-01 14:31:03 -04:00
Jeremy Stretch
b176e0fafd Merge pull request #3616 from kobayashi/3357
allow null region filtering
2019-11-01 14:29:32 -04:00
Jeremy Stretch
fb24a4d420 Merge pull request #3660 from tyler-8/gunicorn_options
Add max_requests details to example config
2019-11-01 12:32:39 -04:00
Jeremy Stretch
391c42300e Closes #3659: Add filtering for objects in admin UI 2019-11-01 12:22:39 -04:00
Tyler Bigler
2a8fa01a57 Increase request counts for max_requests 2019-11-01 12:09:44 -04:00
Jeremy Stretch
bd4b496d14 Tweak PR template to indicate placement of issue number 2019-11-01 11:52:43 -04:00
Jeremy Stretch
cf5c24ee2d Add new Interface type from #3619 2019-11-01 11:49:17 -04:00
Jeremy Stretch
66f4aac0e8 Changelog for #3619 2019-11-01 11:45:22 -04:00
Jeremy Stretch
267caa348e Merge pull request #3657 from Netnod/3619-new-400G-osfp-interface-type
3619 new 400 g osfp interface type
2019-11-01 11:43:43 -04:00
Tyler Bigler
7bf09a3085 Remove redundant word 2019-11-01 10:26:53 -04:00
Tyler Bigler
a0de0696c5 Add max_requests details to example config 2019-11-01 10:23:25 -04:00
Jeremy Stretch
a63383dc08 Reorganized navigation menu 2019-10-30 16:39:32 -04:00
Jeremy Stretch
0ad19081ac Move slug-based choices to choices.py 2019-10-30 16:31:04 -04:00
Emil Palm
aa6b2b8407 Merge remote-tracking branch 'upstream/develop' into 3619-new-400G-osfp-interface-type 2019-10-30 14:31:17 -05:00
Emil Palm
3e6726ff97 Add IFACE_TYPE_400GE_OSPF 2019-10-30 14:30:23 -05:00
Jeremy Stretch
bb30f64252 Closes #1865: Add console port and console server port types 2019-10-30 14:25:55 -04:00
Jeremy Stretch
c4dd76a748 Updated v2.7 release notes 2019-10-30 10:34:26 -04:00
Jeremy Stretch
56a248e601 Merge pull request #3654 from netbox-community/3538-scripts-api
3538: Add custom script API endpoints
2019-10-30 09:35:22 -04:00
Jeremy Stretch
0f65cf23a5 Only use module.name for human-facing display 2019-10-30 09:13:26 -04:00
Jeremy Stretch
fd3f718a0a Add tests for custom script API 2019-10-29 16:54:27 -04:00
Jeremy Stretch
93d28e6a72 Improve script output serialization 2019-10-29 16:17:59 -04:00
Jeremy Stretch
60ec3fde9d Closes #3652: Limit next/previous rack by assigned rack group 2019-10-29 15:17:00 -04:00
Jeremy Stretch
1cfb8aea23 Initial work on #3538: script execution API 2019-10-28 15:02:21 -04:00
Jeremy Stretch
846acf7e9d Changelog for #3629 2019-10-28 13:19:01 -04:00
kobayashi
fb9279cc74 Merge pull request #3645 from BegBlev/llpd-port-id
Retrieve port-id in LLDP tab
2019-10-28 12:19:10 -04:00
kobayashi
d2aa9b8e79 filtering multiple regions with null 2019-10-28 02:24:44 -04:00
Tyler Bigler
eaeb52de20 Add CONN_MAX_AGE to documentation (#3642)
* Add CONN_MAX_AGE to sample configurations

* Correct alignment

* Restore ghost space

* Correct alignment.

* Use stable docs url
2019-10-25 13:11:48 -04:00
Jeremy Stretch
fdbf41e9fd Fixes #3643: Update all Django documentation links to 'stable' version 2019-10-25 11:09:30 -04:00
Jeremy Stretch
092346c819 Changelog for #3309 2019-10-25 09:57:17 -04:00
Jeremy Stretch
5a5f51fe48 Merge pull request #3632 from netbox-community/3309-changelog-middleware
Rewrite change logging middleware
2019-10-25 09:47:32 -04:00
Jeremy Stretch
800df1ebbe Fixes #3636: Add missing rack_group field to PowerFeed CSV export 2019-10-25 09:27:33 -04:00
John Anderson
8eec67e73a #3635 changelog 2019-10-24 23:31:06 -04:00
John Anderson
33b420652d Merge pull request #3639 from sdktr/patch-1
Fix #3635 - cache circuits.*
2019-10-24 21:16:28 -04:00
Stefan de Kooter
42b679d9a3 Fix #3635 - cache circuits.*
Enable caching for items under the circuits app
2019-10-25 00:46:05 +02:00
Jeremy Stretch
ae4f17264f Fixes #3460: Extend upgrade script to validate Python dependencies 2019-10-23 17:12:32 -04:00
Jeremy Stretch
c7d8083ac6 Closes #3594: Add ChoiceVar for custom scripts 2019-10-23 15:59:27 -04:00
Jeremy Stretch
95fec1a87c Merge pull request #3627 from bdlamprecht/pg_dump-documentation
Adding note on invalidating cache
2019-10-23 12:24:27 -04:00
Jeremy Stretch
657a7aef42 Changelog for #3455 2019-10-23 11:55:45 -04:00
Jeremy Stretch
ea0d232169 Merge pull request #3572 from frelon/cluster-tenant
Add tenancy to cluster
2019-10-23 11:53:22 -04:00
Jeremy Stretch
7467347af1 Fixes #3596: Prevent server error when reassigning a device to a new device bay 2019-10-23 09:28:00 -04:00
Jeremy Stretch
0ebc2e4ac0 Fix reporting of custom fields in webhook data on object deletion 2019-10-22 16:12:25 -04:00
Jeremy Stretch
ccb9f7bfe2 Rewrote ObjectChangeMiddleware to remove the curried handle_deleted_object() function 2019-10-22 15:10:49 -04:00
kobayashi
766b5dff24 allow null region filtering 2019-10-22 00:41:49 -04:00
Vincent Catros
68e0329c1b Retrieve port-id in LLDP tab 2019-10-21 11:57:23 +02:00
Brady Lamprecht
fd99994fdb Adding note on invalidating cache 2019-10-18 14:59:55 -06:00
Jeremy Stretch
f21a63382c Changelog for #3340 2019-10-18 09:08:56 -04:00
Jeremy Stretch
6f0581598b Merge pull request #3613 from kobayashi/3340
modified front port connection type list
2019-10-18 09:07:22 -04:00
kobayashi
244e85e836 modify patch panel port connection type list 2019-10-18 00:01:21 -04:00
Jeremy Stretch
1df6713ad5 Minor improvements pertaining to CII best practices 2019-10-17 20:56:37 -04:00
Jeremy Stretch
c6893731ad Merge pull request #3621 from netbox-community/451-devicetype-import
Enable YAML/JSON-based DeviceType import
2019-10-17 16:43:15 -04:00
Jeremy Stretch
2ffbced47e Rework InterfaceTypes and PortTypes classes 2019-10-17 16:38:31 -04:00
Jeremy Stretch
bfce177a07 Merge pull request #3604 from netbox-community/3282-seperate-redis-config
implements #3282 - seperate webhooks and caching redis configs
2019-10-17 16:03:26 -04:00
Jeremy Stretch
8ca182571c Rebase schema migrations 2019-10-17 15:53:10 -04:00
Jeremy Stretch
801dd384d8 Merge branch 'develop' into develop-2.7 2019-10-17 15:51:33 -04:00
Jeremy Stretch
adc96702db Deleted errant import of graphviz 2019-10-17 15:43:49 -04:00
Jeremy Stretch
af73ce75ce Merge pull request #3607 from netbox-community/3606-stale-bot
implemented #3606 - added stale bot config
2019-10-17 14:32:40 -04:00
Jeremy Stretch
f08968da49 Exempt issues tagged with "status: blocked" 2019-10-17 14:28:27 -04:00
Fredrik Lönnegren
18e0bd8937 Fix typo 2019-10-16 08:22:06 +02:00
John Anderson
24344ccfaf Merge pull request #3615 from markkuleinio/develop
Update examples in webhooks.md
2019-10-15 14:27:20 -04:00
Markku Leiniö
91f045a2e4 Update examples in webhooks.md 2019-10-15 20:51:57 +03:00
Jeremy Stretch
050dfb279d Merge pull request #3597 from dgarros/patch-1
Update pillow version to 6.2.0
2019-10-15 11:54:44 -04:00
Jeremy Stretch
f9b7f18be6 Merge pull request #3609 from ScanPlusGmbH/missing-variable
Add SCRIPTS_ROOT to configuration.example.py
2019-10-14 11:58:28 -04:00
Tobias Genannt
a7380ba353 Add SCRIPTS_ROOT to configuration.example.py
Fixes #3608 by adding the new variable to the example configuration.
2019-10-14 09:29:04 +02:00
John Anderson
b8feba1070 implemented #3606 - added stale bot config 2019-10-13 04:12:58 -04:00
John Anderson
64575fec42 Merge pull request #3605 from netbox-community/3445-webhooks-additional-headers
implemented #3445 - Add support for additional user defined headers t…
2019-10-13 03:15:43 -04:00
John Anderson
c7d9bf839e implemented #3445 - Add support for additional user defined headers to be added to webhook requests 2019-10-13 03:09:58 -04:00
John Anderson
0d15ac15ae implements #3282 - seperate webhooks and caching redis configs 2019-10-13 02:49:54 -04:00
John Anderson
b013a60b12 Merge branch 'develop' into develop-2.7 2019-10-13 02:03:16 -04:00
John Anderson
8480c0da53 Merge pull request #3603 from netbox-community/3499-webhooks-ca-filepath
implemented #3499 - Add  to Webhook model to support user supplied CA certificate verification of webhook requests
2019-10-13 01:50:10 -04:00
John Anderson
5e88313276 typo in change log 2019-10-13 01:45:20 -04:00
John Anderson
09d7d38b04 implemented #3499 - Add to Webhook model to support user supplied CA certificate verrification of webhook requests 2019-10-13 01:43:08 -04:00
Damien Garros
4cc29729f9 Update pillow version to 6.2.0
A new CVE just got reporter regarding Pillow 
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16865
it's affecting all version prior to 6.2.0
2019-10-11 13:45:37 -04:00
Jeremy Stretch
d787c353f3 Added slug choices for interface and port types 2019-10-10 23:24:44 -04:00
Jeremy Stretch
553fe0fe97 Merge branch 'develop' into 451-devicetype-import 2019-10-10 13:50:57 -04:00
Jeremy Stretch
aeeb49a6a7 Merge branch 'develop' into develop-2.7 2019-10-10 13:41:10 -04:00
Jeremy Stretch
b25faec159 Post-release version bump 2019-10-10 12:42:57 -04:00
Jeremy Stretch
c2b1556d68 Correct version number 2019-10-10 12:41:02 -04:00
Jeremy Stretch
81acf57518 Merge pull request #3591 from netbox-community/develop
Release v2.6.6
2019-10-10 09:34:17 -07:00
Jeremy Stretch
abbc44a7d1 #3259: Add site and rack fields to cables filter form 2019-10-10 12:28:17 -04:00
Jeremy Stretch
74c259af2e Tweak release notes for v2.6.6 2019-10-10 12:21:40 -04:00
Jeremy Stretch
465304588e Release v2.6.6 2019-10-10 12:18:18 -04:00
Jeremy Stretch
70ad705380 Provide index link to most recent version for release note 2019-10-10 12:10:35 -04:00
Jeremy Stretch
4e6b60b0f4 Rearranged release notes 2019-10-10 12:02:53 -04:00
Jeremy Stretch
d849a49842 Fixes #3588: Enforce object-form JSON for local context data on devices and VMs 2019-10-10 10:41:08 -04:00
Jeremy Stretch
4c7c40a09d Merge pull request #3587 from netbox-community/reorganized-changelog
Reorganized CHANGELOG into release notes based on minor version number
2019-10-10 06:17:42 -07:00
Jeremy Stretch
521d6941fa Merge branch 'develop' into reorganized-changelog 2019-10-10 09:15:57 -04:00
kobayashi
e223c88548 Merge pull request #3553 from chambersh1129/develop
Replace all instances of .extra() in QuerySets with annotations #3117
2019-10-09 21:54:16 -04:00
chambersh1129
52e9369af4 PEP 8 E121 continuation line under-indented for hanging indent fix 2019-10-09 20:11:02 -04:00
chambersh1129
bdb3838d71 Replace all instances of .extra() in QuerySets with annotations, including references in docstrings 2019-10-09 20:11:02 -04:00
Jeremy Stretch
0a921d37f8 Fixes #3582: Enforce view permissions on global search results 2019-10-09 16:45:33 -04:00
Jeremy Stretch
896d58fc3f Fixes #3458: Prevent primary IP address for a device/VM from being reassigned 2019-10-09 16:22:06 -04:00
Jeremy Stretch
c770b13903 Fixes #3474: Fix device status page loading when NAPALM call fails 2019-10-09 15:44:32 -04:00
Jeremy Stretch
6cdeb0ed95 Fixes #3463: Correct CSV headers for exported power feeds 2019-10-09 15:25:31 -04:00
Jeremy Stretch
99f7cfcbd3 Closes #3581: Introduce commit_default custom script attribute to not commit changes by default 2019-10-09 15:16:50 -04:00
Jeremy Stretch
d402b6c3e5 Closes #3545: Add MultiObjectVar for custom scripts 2019-10-09 15:06:00 -04:00
Jeremy Stretch
738368a6a1 Closes #3471: Disallow raw HTML in Markdown-rendered fields 2019-10-09 14:47:40 -04:00
Jeremy Stretch
3dbf94146a Reorganized CHANGELOG into release notes based on minor version number 2019-10-09 13:54:05 -04:00
Jeremy Stretch
7a65930361 Merge pull request #3561 from netbox-community/3560-drf-bootstrap-css
Override DRF's builtin Bootstrap with NetBox's own more recent copy
2019-10-09 08:53:13 -07:00
Jeremy Stretch
6068b1a275 Closes #3580: Render text and URL fields as textareas in the custom link form 2019-10-09 09:40:24 -04:00
Jeremy Stretch
4c677e7fe6 Force checkbox table columns to narrow width 2019-10-07 17:22:35 -04:00
Jeremy Stretch
c668b990e1 Closes #3563: Enable editing of individual DeviceType components 2019-10-07 17:08:51 -04:00
Jeremy Stretch
a9d3d38a41 Changelog for #1941 2019-10-07 15:03:10 -04:00
Jeremy Stretch
f04c321aab Merge pull request #3565 from ananace/add-infiniband
Added InfiniBand interface form factor
2019-10-07 12:02:06 -07:00
Jeremy Stretch
ed785098a6 Fixes #3571: Prevent erroneous redirects when editing tags 2019-10-07 14:27:02 -04:00
Jeremy Stretch
9198d6924e Fixes #3573: Ensure consistent display of changelog retention period 2019-10-07 14:12:16 -04:00
Jeremy Stretch
4ab6aca2ec Fixes #3575: Restore label for comments field when bulk editing circuits 2019-10-07 14:06:41 -04:00
Fredrik Lönnegren
3262805938 Add tenancy to cluster
fix pep8
2019-10-07 16:20:14 +02:00
dansheps
04d9889127 Fixes #3574 - Change device to parent in interface edit form vlan filtering logic 2019-10-07 08:54:39 -05:00
Jeremy Stretch
a3b9bdaff1 Miscellaneous cleanup 2019-10-04 12:59:10 -04:00
Jeremy Stretch
6f83fca216 Delete obsolete IFACE_ORDERING constants 2019-10-03 19:53:32 -04:00
Jeremy Stretch
9f52cdeee9 Closes #3568: Update jQuery library to v3.4.1 2019-10-03 18:53:00 -04:00
Jeremy Stretch
26071903c1 Add stdout progress logging to cable migration 2019-10-03 18:49:56 -04:00
Jeremy Stretch
8a5ee6f8ea Merge pull request #3552 from kobayashi/develop
fixed broken links
2019-10-03 14:33:15 -04:00
Saria Hajjar
0ec8476b4d Added InfiniBand interface form factor 2019-10-03 09:22:19 +02:00
Jeremy Stretch
807d849657 PEP8 fix 2019-10-01 17:07:17 -04:00
Jeremy Stretch
6892b79366 Enforce object creation permissions 2019-10-01 16:54:10 -04:00
Jeremy Stretch
88d61db384 Fix YAMLLoadWarning 2019-10-01 16:39:11 -04:00
Jeremy Stretch
ee4e68b082 Rewrote test for DeviceType import 2019-10-01 16:36:31 -04:00
Jeremy Stretch
63ad93afd0 Merge pull request #3550 from netbox-community/3259-cable-filters
3259 cable filters
2019-10-01 14:25:20 -04:00
Jeremy Stretch
60e03eb841 Override DRF's builtin Bootstrap with NetBox's own more recent copy 2019-10-01 10:11:23 -04:00
kobayashi
b2ac81a78f fixed broken links 2019-09-28 00:41:09 -04:00
Jeremy Stretch
edc1b52f65 Adopted a different approach to importing related objects 2019-09-27 16:51:12 -04:00
Jeremy Stretch
aa9d034b5d Filter by site slug rather than by name 2019-09-27 15:12:16 -04:00
Jeremy Stretch
4889c8ff9b Closes #3259: Add rack and site filters for cables 2019-09-27 12:18:53 -04:00
Jeremy Stretch
d2ab41abfb Cache A/B termination devices on the Cable model 2019-09-26 17:17:12 -04:00
Jeremy Stretch
56ddf79ae7 Update Travis-CI badges in README 2019-09-26 15:03:20 -04:00
Jeremy Stretch
36d4f0d259 Fix typo 2019-09-25 16:39:04 -04:00
Jeremy Stretch
5f3528cf74 Capture MultiObjectField default form field values 2019-09-25 16:19:22 -04:00
Jeremy Stretch
47f1febfc9 Capture import form field default values 2019-09-25 16:06:09 -04:00
Jeremy Stretch
93154abb31 Merge branch 'develop' into 451-devicetype-import 2019-09-25 13:44:48 -04:00
Jeremy Stretch
778e5bed3c Merge branch 'develop' into develop-2.7 2019-09-25 13:44:29 -04:00
Jeremy Stretch
ef1fa55902 Post-release version bump 2019-09-25 13:29:22 -04:00
Jeremy Stretch
963991e246 Merge pull request #3544 from netbox-community/develop
Release v2.6.5
2019-09-25 13:28:17 -04:00
Jeremy Stretch
3e4cd59fc0 Releae v2.6.5 2019-09-25 13:24:28 -04:00
Jeremy Stretch
874247c7ab Merge pull request #3508 from mohahmed13/develop
Adding a reference to deploying NetBox via Kubernetes manifests
2019-09-25 12:11:08 -04:00
Jeremy Stretch
b7b04045de Closes #3515: Enable export templates for inventory items 2019-09-25 12:07:41 -04:00
Daniel Sheppard
a84dbbf482 Fixes: #3543 - Adds inline vlan editing to virtual machine interfaces 2019-09-25 10:49:08 -05:00
Jeremy Stretch
f54774f6a1 Closes #3297: Include reserved units when calculating rack utilization 2019-09-25 10:54:08 -04:00
Daniel Sheppard
a359d88897 Update changelog 2019-09-25 09:29:54 -05:00
Daniel Sheppard
458251683c Fixes: #3540 - Changed interface edit to use new inline vlan edit fields 2019-09-25 09:28:23 -05:00
Jeremy Stretch
eeb3434349 Closes #3347: Extend upgrade script to automatically remove stale content types 2019-09-25 10:22:02 -04:00
Jeremy Stretch
d183a9e7b5 Closes #3352: Enable filtering changelog API by changed_object_id 2019-09-25 10:11:41 -04:00
Jeremy Stretch
86cef1c502 Fixes #3435: Change IP/prefix CSV export to reference VRF name instead of RD 2019-09-25 09:39:03 -04:00
Jeremy Stretch
b8d8cb33ff Closes #3529: Enable filtering circuits list by region 2019-09-25 09:21:21 -04:00
Jeremy Stretch
0615d368f2 Force validation of individual objects within a MultiObjectField 2019-09-24 16:51:59 -04:00
Jeremy Stretch
30ee232654 Move JSON/YAML data valdiation to ImportForm 2019-09-24 16:13:52 -04:00
Daniel Sheppard
a4690ec5ce Fix ordering for rack positioning 2019-09-24 15:08:57 -05:00
Jeremy Stretch
2621f17cde Remove legacy CSV-based DeviceType import 2019-09-24 16:03:10 -04:00
Jeremy Stretch
15b2a7eab0 Fix form rendering; enable toggling of redirect to imported object 2019-09-24 15:58:23 -04:00
Daniel Sheppard
d0597cd289 Fix ordering for Rack Positioning 2019-09-24 14:36:41 -05:00
Jeremy Stretch
fe85dc1186 Closes #3524: Enable bulk editing of power outlet/power port associations 2019-09-24 15:27:47 -04:00
Jeremy Stretch
51baaab74b Changelog for #3464 2019-09-24 15:14:22 -04:00
Jeremy Stretch
35fc0d6847 Merge pull request #3536 from DanSheps/develop
Fixes: #3464 - Change color picker to dynamic coloring from static CSS
2019-09-24 15:13:11 -04:00
Jeremy Stretch
ffc6eec483 Fixes #3519: Prevent cables from being terminated to virtual/wireless interfaces 2019-09-24 15:07:54 -04:00
Daniel Sheppard
17ec9aa170 Fixes: #3464 - Change color picker to dynamic coloring from static CSS 2019-09-24 09:39:06 -05:00
Daniel Sheppard
6fdd35785e Fixes: #3531 - Fix FG Color for Rack Role 2019-09-24 08:50:23 -05:00
Daniel Sheppard
fb34507def Fixes: #3532 - add device to graph type for documentation 2019-09-24 08:45:31 -05:00
Daniel Sheppard
8996c530c9 Fixes: #3534 - Add none option for untagged vlan field 2019-09-24 08:39:41 -05:00
Jeremy Stretch
b0724dfd14 Add developer guidance 2019-09-23 14:57:01 -04:00
Daniel Sheppard
a17060c060 Update CHANGELOG.md 2019-09-23 13:04:13 -05:00
Jeremy Stretch
f8e10f66e1 Remove extraneous demo scripts 2019-09-23 09:21:38 -04:00
Jeremy Stretch
5049c6c0a1 Add test for DeviceType import 2019-09-20 15:57:44 -04:00
Jeremy Stretch
60b70b6c7b Add RearPortTemplate power_port field 2019-09-20 15:16:14 -04:00
Jeremy Stretch
5266fc67c9 Extend DeviceType import to include related objects 2019-09-20 14:02:14 -04:00
Jeremy Stretch
0798533201 Add docs link for custom scripts; arrange links alphabetically 2019-09-20 09:10:32 -04:00
Jeremy Stretch
56dcadb69b Merged v2.6.4 2019-09-20 08:35:14 -04:00
Daniel Sheppard
a1216fc1b7 Fixed thrown error in parseURL 2019-09-19 10:32:47 -05:00
Jeremy Stretch
353195850f Post-release version bump 2019-09-19 09:36:23 -04:00
Moh Ahmed
0903362334 Adding a reference to deploying NetBox via Kubernetes manifests 2019-09-17 15:51:29 -04:00
Jeremy Stretch
f8fdca4968 Initial work on JSON/YAML-based DeviceType import 2019-09-13 16:18:29 -04:00
Daniel Sheppard
9e258dd31e Fixes: #2902 - Implements systemd (#3017)
* Closes #2902 - Migrate to systemd from supervisord
* Closes #2902 - Migrate to systemd from supervisord

* Update systemd unit and environment file
* Add gunicorn.conf
* Update documentation and CHANGELOG.  Moved parameters around on service file
* Update Gitignore
2019-09-06 11:46:35 -05:00
Jeremy Stretch
480db83f39 Renumber remove_topology_maps migration 2019-09-05 10:25:44 -04:00
Jeremy Stretch
cc0f0c4843 Merge v2.6.3 2019-09-04 16:45:33 -04:00
John Anderson
a6511632ad closes #3407 - Added code coverage reporting to the CI pipeline 2019-08-14 20:28:23 -04:00
Jeremy Stretch
15b55f5e62 Remove deprecated form_factor accessor on Interface and InterfaceTemplate 2019-08-08 21:35:59 -04:00
Jeremy Stretch
dccda62f2d Closes #2745: Remove topology maps 2019-08-08 21:33:20 -04:00
Jeremy Stretch
ef432754ee Started 2.7 branch 2019-08-08 21:19:14 -04:00
1119 changed files with 106311 additions and 9868 deletions

View File

@@ -9,8 +9,7 @@
IF YOUR PULL REQUEST DOES NOT REFERENCE AN ACCEPTED BUG REPORT OR
FEATURE REQUEST, IT WILL BE MARKED AS INVALID AND CLOSED.
-->
### Fixes:
### Fixes: <ISSUE NUMBER GOES HERE>
<!--
Please include a summary of the proposed changes below.
-->

23
.github/lock.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
# Configuration for Lock (https://github.com/apps/lock)
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 90
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels: []
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: false
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: true
# Limit to only `issues` or `pulls`
# only: issues

30
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
# Configuration for Stale (https://github.com/apps/stale)
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 14
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "status: accepted"
- "status: gathering feedback"
- "status: blocked"
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. NetBox
is governed by a small group of core maintainers which means not all opened
issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
This issue has been automatically closed due to lack of activity. In an
effort to reduce noise, please do not comment any further. Note that the
core maintainers may elect to reopen this issue at a later date if deemed
necessary.

4
.gitignore vendored
View File

@@ -12,5 +12,9 @@
fabfile.py
*.swp
gunicorn_config.py
gunicorn.py
netbox.log
netbox.pid
.DS_Store
.vscode
.coverage

View File

@@ -10,6 +10,7 @@ python:
install:
- pip install -r requirements.txt
- pip install pycodestyle
- pip install coverage
before_script:
- psql --version
- psql -U postgres -c 'SELECT version();'

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ For real-time discussion, you can join the #netbox Slack channel on [NetworkToCo
## Reporting Bugs
* First, ensure that you've installed the [latest stable version](https://github.com/netbox-community/netbox/releases)
* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases)
of NetBox. If you're running an older version, it's possible that the bug has
already been fixed.
@@ -24,31 +24,30 @@ already been fixed.
to see if the bug you've found has already been reported. If you think you may
be experiencing a reported issue that hasn't already been resolved, please
click "add a reaction" in the top right corner of the issue and add a thumbs
up (+1). You mightalso want to add a comment describing how it's affecting your
up (+1). You might also want to add a comment describing how it's affecting your
installation. This will allow us to prioritize bugs based on how many users are
affected.
* If you haven't found an existing issue that describes your suspected bug,
please inquire about it on the mailing list. **Do not** file an issue until you
have received confirmation that it is in fact a bug. Invalid issues are very
distracting and slow the pace at which NetBox is developed.
* When submitting an issue, please be as descriptive as possible. Be sure to
include:
provide all information request in the issue template, including:
* The environment in which NetBox is running
* The exact steps that can be taken to reproduce the issue (if applicable)
* The exact steps that can be taken to reproduce the issue
* Expected and observed behavior
* Any error messages generated
* Screenshots (if applicable)
* Please avoid prepending any sort of tag (e.g. "[Bug]") to the issue title.
The issue will be reviewed by a moderator after submission and the appropriate
The issue will be reviewed by a maintainer after submission and the appropriate
labels will be applied for categorization.
* Keep in mind that we prioritize bugs based on their severity and how much
work is required to resolve them. It may take some time for someone to address
your issue.
* For more information on how bug reports are handled, please see our [issue
intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy).
## Feature Requests
* First, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues)
@@ -61,10 +60,10 @@ free to add a comment with any additional justification for the feature.
(However, note that comments with no substance other than a "+1" will be
deleted. Please use GitHub's reactions feature to indicate your support.)
* Due to an excessive backlog of feature requests, we are not currently
accepting any proposals which substantially extend NetBox's functionality
beyond its current feature set. This includes the introduction of any new views
or models which have not already been proposed in an existing feature request.
* Due to a large backlog of feature requests, we are not currently accepting
any proposals which substantially extend NetBox's functionality beyond its
current feature set. This includes the introduction of any new views or models
which have not already been proposed in an existing feature request.
* Before filing a new feature request, consider raising your idea on the
mailing list first. Feedback you receive there will help validate and shape the
@@ -75,8 +74,8 @@ describe the functionality and data model(s) being proposed. The more effort
you put into writing a feature request, the better its chance is of being
implemented. Overly broad feature requests will be closed.
* When submitting a feature request on GitHub, be sure to include the
following:
* When submitting a feature request on GitHub, be sure to include all
information requested by the issue template, including:
* A detailed description of the proposed functionality
* A use case for the feature; who would use it and what value it would add
@@ -89,6 +88,9 @@ following:
title. The issue will be reviewed by a moderator after submission and the
appropriate labels will be applied for categorization.
* For more information on how feature requests are handled, please see our
[issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy).
## Submitting Pull Requests
* Be sure to open an issue **before** starting work on a pull request, and
@@ -99,9 +101,11 @@ any work that's already in progress.
* Any pull request which does _not_ relate to an accepted issue will be closed.
* All major new functionality must include relevant tests where applicable.
* When submitting a pull request, please be sure to work off of the `develop`
branch, rather than `master`. The `develop` branch is used for ongoing
development, while `master` is used for tagging new stable releases.
development, while `master` is used for tagging stable releases.
* All code submissions should meet the following criteria (CI will enforce
these checks):
@@ -117,3 +121,48 @@ Only comment on an issue if you are sharing a relevant idea or constructive
feedback. **Do not** comment on an issue just to show your support (give the
top post a :+1: instead) or ask for an ETA. These comments will be deleted to
reduce noise in the discussion.
## Issue Lifecycle
New issues are handled according to our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy).
Maintainers will assign label(s) and/or close new issues as the policy
dictates. This helps ensure a productive development environment and avoid
accumulating a large backlog of work.
The core maintainers group has chosen to make use of GitHub's [Stale bot](https://github.com/apps/stale)
to aid in issue management.
* Issues will be marked as stale after 14 days of no activity.
* Then after 7 more days of inactivity, the issue will be closed.
* Any issue bearing one of the following labels will be exempt from all Stale
bot actions:
* `status: accepted`
* `status: gathering feedback`
* `status: blocked`
It is natural that some new issues get more attention than others. Often this
is a metric of an issues's overall value to the project. In other cases in
which issues merely get lost in the shuffle, notifications from Stale bot can
bring renewed attention to potentially meaningful issues.
## Maintainer Guidance
* Maintainers are expected to contribute at least four hours per week to the
project on average. This can be employer-sponsored or individual time, with
the understanding that all contributions are submitted under the Apache 2.0
license and that your employer may not make claim to any contributions.
Contributions include code work, issue management, and community support. All
development must be in accordance with our [development guidance](https://netbox.readthedocs.io/en/stable/development/).
* Maintainers are expected to attend (where feasible) our biweekly ~30-minute
sync to review agenda items. This meeting provides opportunity to present and
discuss pressing topics. Meetings are held as virtual audio/video conferences.
* Official channels for communication include:
* GitHub issues/pull requests
* The [netbox-discuss](https://groups.google.com/forum/#!forum/netbox-discuss) mailing list
* The **#netbox** channel on [NetworkToCode Slack](https://networktocode.slack.com/)
* Maintainers with no substantial recorded activity in a 60-day period will be
removed from the project.

View File

@@ -1,9 +1,10 @@
![NetBox](docs/netbox_logo.png "NetBox logo")
![NetBox](docs/netbox_logo.svg "NetBox logo")
NetBox is an IP address management (IPAM) and data center infrastructure
management (DCIM) tool. Initially conceived by the network engineering team at
[DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically
to address the needs of network and infrastructure engineers.
to address the needs of network and infrastructure engineers. It is intended to
function as a domain-specific source of truth for network operations.
NetBox runs as a web application atop the [Django](https://www.djangoproject.com/)
Python framework with a [PostgreSQL](http://www.postgresql.org/) database. For a
@@ -18,8 +19,8 @@ or join us in the #netbox Slack channel on [NetworkToCode](https://networktocode
| | status |
|-------------|------------|
| **master** | [![Build Status](https://travis-ci.org/digitalocean/netbox.svg?branch=master)](https://travis-ci.org/digitalocean/netbox) |
| **develop** | [![Build Status](https://travis-ci.org/digitalocean/netbox.svg?branch=develop)](https://travis-ci.org/digitalocean/netbox) |
| **master** | [![Build Status](https://travis-ci.org/netbox-community/netbox.svg?branch=master)](https://travis-ci.com/netbox-community/netbox/) |
| **develop** | [![Build Status](https://travis-ci.org/netbox-community/netbox.svg?branch=develop)](https://travis-ci.com/netbox-community/netbox/) |
## Screenshots
@@ -35,11 +36,14 @@ Please see [the documentation](http://netbox.readthedocs.io/en/stable/) for
instructions on installing NetBox. To upgrade NetBox, please download the [latest release](https://github.com/netbox-community/netbox/releases)
and run `upgrade.sh`.
## Alternative Installations
# Providing Feedback
* [Docker container](https://github.com/netbox-community/netbox-docker) (via [@cimnine](https://github.com/cimnine))
* [Vagrant deployment](https://github.com/ryanmerolle/netbox-vagrant) (via [@ryanmerolle](https://github.com/ryanmerolle))
* [Ansible deployment](https://github.com/lae/ansible-role-netbox) (via [@lae](https://github.com/lae))
Feature requests and bug reports must be submitted as GiHub issues. (Please be
sure to use the [appropriate template](https://github.com/netbox-community/netbox/issues/new/choose).)
For general discussion, please consider joining our [mailing list](https://groups.google.com/forum/#!forum/netbox-discuss).
If you are interested in contributing to the development of NetBox, please read
our [contributing guide](CONTRIBUTING.md) prior to beginning any work.
# Related projects

View File

@@ -22,14 +22,14 @@ django-filter
# https://github.com/django-mptt/django-mptt
django-mptt
# Django integration for RQ (Reqis queuing)
# https://github.com/rq/django-rq
django-rq
# Prometheus metrics library for Django
# https://github.com/korfuri/django-prometheus
django-prometheus
# Django integration for RQ (Reqis queuing)
# https://github.com/rq/django-rq
django-rq
# Abstraction models for rendering and paginating HTML tables
# https://github.com/jieter/django-tables2
django-tables2
@@ -54,9 +54,9 @@ djangorestframework
# https://github.com/axnsan12/drf-yasg
drf-yasg[validation]
# Python interface to the graphviz graph rendering utility
# https://github.com/xflr6/graphviz
graphviz
# Platform-agnostic template rendering engine
# https://github.com/pallets/jinja
Jinja2
# Simple markup language for rendering HTML
# https://github.com/Python-Markdown/markdown
@@ -82,3 +82,15 @@ py-gfm
# Extensive cryptographic library (fork of pycrypto)
# https://github.com/Legrandin/pycryptodome
pycryptodome
# YAML rendering library
# https://github.com/yaml/pyyaml
PyYAML
# In-memory key/value store used for caching and queuing
# https://github.com/andymccurdy/redis-py
redis
# SVG image rendering (used for rack elevations)
# https://github.com/mozman/svgwrite
svgwrite

16
contrib/gunicorn.py Normal file
View File

@@ -0,0 +1,16 @@
# The IP address (typically localhost) and port that the Netbox WSGI process should listen on
bind = '127.0.0.1:8001'
# Number of gunicorn workers to spawn. This should typically be 2n+1, where
# n is the number of CPU cores present.
workers = 5
# Number of threads per worker process
threads = 3
# Timeout (in seconds) for a request to complete
timeout = 120
# The maximum number of requests a worker can handle before being respawned
max_requests = 5000
max_requests_jitter = 500

22
contrib/netbox-rq.service Normal file
View File

@@ -0,0 +1,22 @@
[Unit]
Description=NetBox Request Queue Worker
Documentation=https://netbox.readthedocs.io/en/stable/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/netbox
ExecStart=/usr/bin/python3 /opt/netbox/netbox/manage.py rqworker
Restart=on-failure
RestartSec=30
PrivateTmp=true
[Install]
WantedBy=multi-user.target

22
contrib/netbox.service Normal file
View File

@@ -0,0 +1,22 @@
[Unit]
Description=NetBox WSGI Service
Documentation=https://netbox.readthedocs.io/en/stable/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
Group=www-data
PIDFile=/var/tmp/netbox.pid
WorkingDirectory=/opt/netbox
ExecStart=/usr/local/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/netbox --config /opt/netbox/gunicorn.py netbox.wsgi
Restart=on-failure
RestartSec=30
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View File

@@ -63,6 +63,26 @@ A list of field names indicating the order in which the form fields should appea
field_order = ['var1', 'var2', 'var3']
```
### `commit_default`
The checkbox to commit database changes when executing a script is checked by default. Set `commit_default` to False under the script's Meta class to leave this option unchecked by default.
```
commit_default = False
```
## Accessing Request Data
Details of the current HTTP request (the one being made to execute the script) are available as the instance attribute `self.request`. This can be used to infer, for example, the user executing the script and the client IP address:
```python
username = self.request.user.username
ip_address = self.request.META.get('HTTP_X_FORWARDED_FOR') or self.request.META.get('REMOTE_ADDR')
self.log_info("Running as user {} (IP: {})...".format(username, ip_address))
```
For a complete list of available request parameters, please see the [Django documentation](https://docs.djangoproject.com/en/stable/ref/request-response/).
## Reading Data from Files
The Script class provides two convenience methods for reading data from files:
@@ -111,6 +131,23 @@ Stored a numeric integer. Options include:
A true/false flag. This field has no options beyond the defaults.
### ChoiceVar
A set of choices from which the user can select one.
* `choices` - A list of `(value, label)` tuples representing the available choices. For example:
```python
CHOICES = (
('n', 'North'),
('s', 'South'),
('e', 'East'),
('w', 'West')
)
direction = ChoiceVar(choices=CHOICES)
```
### ObjectVar
A NetBox object. The list of available objects is defined by the queryset parameter. Each instance of this variable is limited to a single object type.
@@ -157,7 +194,7 @@ class NewBranchScript(Script):
class Meta:
name = "New Branch"
description = "Provision a new branch site"
fields = ['site_name', 'switch_count', 'switch_model']
field_order = ['site_name', 'switch_count', 'switch_model']
site_name = StringVar(
description="Name of the new site"

View File

@@ -4,7 +4,7 @@ NetBox allows users to define custom templates that can be used when exporting o
Each export template is associated with a certain type of object. For instance, if you create an export template for VLANs, your custom template will appear under the "Export" button on the VLANs list.
Export templates are written in [Django's template language](https://docs.djangoproject.com/en/1.9/ref/templates/language/), which is very similar to Jinja2. The list of objects returned from the database is stored in the `queryset` variable, which you'll typically want to iterate through using a `for` loop. Object properties can be access by name. For example:
Export templates are written in [Django's template language](https://docs.djangoproject.com/en/stable/ref/templates/language/), which is very similar to Jinja2. The list of objects returned from the database is stored in the `queryset` variable, which you'll typically want to iterate through using a `for` loop. Object properties can be access by name. For example:
```
{% for rack in queryset %}

View File

@@ -2,12 +2,17 @@
NetBox does not have the ability to generate graphs natively, but this feature allows you to embed contextual graphs from an external resources (such as a monitoring system) inside the site, provider, and interface views. Each embedded graph must be defined with the following parameters:
* **Type:** Site, provider, or interface. This determines in which view the graph will be displayed.
* **Type:** Site, device, provider, or interface. This determines in which view the graph will be displayed.
* **Weight:** Determines the order in which graphs are displayed (lower weights are displayed first). Graphs with equal weights will be ordered alphabetically by name.
* **Name:** The title to display above the graph.
* **Source URL:** The source of the image to be embedded. The associated object will be available as a template variable named `obj`.
* **Link URL (optional):** A URL to which the graph will be linked. The associated object will be available as a template variable named `obj`.
Graph names and links can be rendered using the Django or Jinja2 template languages.
!!! warning
Support for the Django templating language will be removed in NetBox v2.8. Jinja2 is recommended.
## Examples
You only need to define one graph object for each graph you want to include when viewing an object. For example, if you want to include a graph of traffic through an interface over the past five minutes, your graph source might looks like this:

View File

@@ -0,0 +1,65 @@
# NAPALM
NetBox supports integration with the [NAPALM automation](https://napalm-automation.net/) library. NAPALM allows NetBox to fetch live data from devices and return it to a requester via its REST API.
!!! info
To enable the integration, the NAPALM library must be installed. See [installation steps](../../installation/2-netbox/#napalm-automation-optional) for more information.
```
GET /api/dcim/devices/1/napalm/?method=get_environment
{
"get_environment": {
...
}
}
```
## Authentication
By default, the [`NAPALM_USERNAME`](../../configuration/optional-settings/#napalm_username) and [`NAPALM_PASSWORD`](../../configuration/optional-settings/#napalm_password) are used for NAPALM authentication. They can be overridden for an individual API call through the `X-NAPALM-Username` and `X-NAPALM-Password` headers.
```
$ curl "http://localhost/api/dcim/devices/1/napalm/?method=get_environment" \
-H "Authorization: Token f4b378553dacfcfd44c5a0b9ae49b57e29c552b5" \
-H "Content-Type: application/json" \
-H "Accept: application/json; indent=4" \
-H "X-NAPALM-Username: foo" \
-H "X-NAPALM-Password: bar"
```
## Method Support
The list of supported NAPALM methods depends on the [NAPALM driver](https://napalm.readthedocs.io/en/latest/support/index.html#general-support-matrix) configured for the platform of a device. NetBox only supports [get](https://napalm.readthedocs.io/en/latest/support/index.html#getters-support-matrix) methods.
## Multiple Methods
More than one method in an API call can be invoked by adding multiple `method` parameters. For example:
```
GET /api/dcim/devices/1/napalm/?method=get_ntp_servers&method=get_ntp_peers
{
"get_ntp_servers": {
...
},
"get_ntp_peers": {
...
}
}
```
## Optional Arguments
The behavior of NAPALM drivers can be adjusted according to the [optional arguments](https://napalm.readthedocs.io/en/latest/support/index.html#optional-arguments). NetBox exposes those arguments using headers prefixed with `X-NAPALM-`.
For instance, the SSH port is changed to 2222 in this API call:
```
$ curl "http://localhost/api/dcim/devices/1/napalm/?method=get_environment" \
-H "Authorization: Token f4b378553dacfcfd44c5a0b9ae49b57e29c552b5" \
-H "Content-Type: application/json" \
-H "Accept: application/json; indent=4" \
-H "X-NAPALM-port: 2222"
```

View File

@@ -12,7 +12,7 @@ A NetBox report is a mechanism for validating the integrity of data within NetBo
## Writing Reports
Reports must be saved as files in the [`REPORTS_ROOT`](../configuration/optional-settings/#reports_root) path (which defaults to `netbox/reports/`). Each file created within this path is considered a separate module. Each module holds one or more reports (Python classes), each of which performs a certain function. The logic of each report is broken into discrete test methods, each of which applies a small portion of the logic comprising the overall test.
Reports must be saved as files in the [`REPORTS_ROOT`](../../configuration/optional-settings/#reports_root) path (which defaults to `netbox/reports/`). Each file created within this path is considered a separate module. Each module holds one or more reports (Python classes), each of which performs a certain function. The logic of each report is broken into discrete test methods, each of which applies a small portion of the logic comprising the overall test.
!!! warning
The reports path includes a file named `__init__.py`, which registers the path as a Python module. Do not delete this file.

View File

@@ -1,17 +0,0 @@
# Topology Maps
NetBox can generate simple topology maps from the physical network connections recorded in its database. First, you'll need to create a topology map definition under the admin UI at Extras > Topology Maps.
Each topology map is associated with a site. A site can have multiple topology maps, which might each illustrate a different aspect of its infrastructure (for example, production versus backend infrastructure).
To define the scope of a topology map, decide which devices you want to include. The map will only include interface connections with both points terminated on an included device. Specify the devices to include in the **device patterns** field by entering a list of [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) matching device names. For example, if you wanted to include "mgmt-switch1" through "mgmt-switch99", you might use the regex `mgmt-switch\d+`.
Each line of the **device patterns** field represents a hierarchical layer within the topology map. For example, you might map a traditional network with core, distribution, and access tiers like this:
```
core-switch-[abcd]
dist-switch\d
access-switch\d+;oob-switch\d+
```
Note that you can combine multiple regexes onto one line using semicolons. The order in which regexes are listed on a line is significant: devices matching the first regex will be rendered first, and subsequent groups will be rendered to the right of those.

View File

@@ -11,8 +11,10 @@ The webhook POST request is structured as so (assuming `application/json` as the
```no-highlight
{
"event": "created",
"signal_received_timestamp": 1508769597,
"model": "Site"
"timestamp": "2019-10-12 12:51:29.746944",
"username": "admin",
"model": "site",
"request_id": "43d8e212-94c7-4f67-b544-0dcde4fc0f43",
"data": {
...
}
@@ -24,8 +26,10 @@ The webhook POST request is structured as so (assuming `application/json` as the
```no-highlight
{
"event": "deleted",
"signal_received_timestamp": 1508781858.544069,
"model": "Site",
"timestamp": "2019-10-12 12:55:44.030750",
"username": "johnsmith",
"model": "site",
"request_id": "e9bb83b2-ebe4-4346-b13f-07144b1a00b4",
"data": {
"asn": None,
"comments": "",

View File

@@ -4,7 +4,7 @@ NetBox includes a Python shell within which objects can be directly queried, cre
./manage.py nbshell
```
This will launch a customized version of [the built-in Django shell](https://docs.djangoproject.com/en/dev/ref/django-admin/#shell) with all relevant NetBox models pre-loaded. (If desired, the stock Django shell is also available by executing `./manage.py shell`.)
This will launch a customized version of [the built-in Django shell](https://docs.djangoproject.com/en/stable/ref/django-admin/#shell) with all relevant NetBox models pre-loaded. (If desired, the stock Django shell is also available by executing `./manage.py shell`.)
```
$ ./manage.py nbshell
@@ -28,7 +28,7 @@ DCIM:
## Querying Objects
Objects are retrieved by forming a [Django queryset](https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-objects). The base queryset for an object takes the form `<model>.objects.all()`, which will return a (truncated) list of all objects of that type.
Objects are retrieved by forming a [Django queryset](https://docs.djangoproject.com/en/stable/topics/db/queries/#retrieving-objects). The base queryset for an object takes the form `<model>.objects.all()`, which will return a (truncated) list of all objects of that type.
```
>>> Device.objects.all()
@@ -99,7 +99,7 @@ This approach can span multiple levels of relations. For example, the following
```
!!! note
While the above query is functional, it is very inefficient. There are ways to optimize such requests, however they are out of the scope of this document. For more information, see the [Django queryset method reference](https://docs.djangoproject.com/en/dev/ref/models/querysets/) documentation.
While the above query is functional, it is very inefficient. There are ways to optimize such requests, however they are out of the scope of this document. For more information, see the [Django queryset method reference](https://docs.djangoproject.com/en/stable/ref/models/querysets/) documentation.
Reverse relationships can be traversed as well. For example, the following will find all devices with an interface named "em0":
@@ -137,7 +137,7 @@ To return the inverse of a filtered queryset, use `exclude()` instead of `filter
```
!!! info
The examples above are intended only to provide a cursory introduction to queryset filtering. For an exhaustive list of the available filters, please consult the [Django queryset API docs](https://docs.djangoproject.com/en/dev/ref/models/querysets/).
The examples above are intended only to provide a cursory introduction to queryset filtering. For an exhaustive list of the available filters, please consult the [Django queryset API docs](https://docs.djangoproject.com/en/stable/ref/models/querysets/).
## Creating and Updating Objects

View File

@@ -39,6 +39,11 @@ If you want to export only the database schema, and not the data itself (e.g. fo
```no-highlight
pg_dump -s netbox > netbox_schema.sql
```
If you are migrating your instance of NetBox to a different machine, please make sure you invalidate the cache by performing this command:
```no-highlight
python3 manage.py invalidate all
```
---

View File

@@ -27,7 +27,7 @@ $ curl -H "Accept: application/json; indent=4" http://localhost/api/dcim/sites/
}
```
However, if the [`LOGIN_REQUIRED`](../configuration/optional-settings/#login_required) configuration setting has been set to `True`, all requests must be authenticated.
However, if the [`LOGIN_REQUIRED`](../../configuration/optional-settings/#login_required) configuration setting has been set to `True`, all requests must be authenticated.
```
$ curl -H "Accept: application/json; indent=4" http://localhost/api/dcim/sites/

View File

@@ -246,7 +246,7 @@ Vary: Accept
}
```
The default page size derives from the [`PAGINATE_COUNT`](../configuration/optional-settings/#paginate_count) configuration setting, which defaults to 50. However, this can be overridden per request by specifying the desired `offset` and `limit` query parameters. For example, if you wish to retrieve a hundred devices at a time, you would make a request for:
The default page size derives from the [`PAGINATE_COUNT`](../../configuration/optional-settings/#paginate_count) configuration setting, which defaults to 50. However, this can be overridden per request by specifying the desired `offset` and `limit` query parameters. For example, if you wish to retrieve a hundred devices at a time, you would make a request for:
```
http://localhost:8000/api/dcim/devices/?limit=100
@@ -263,7 +263,7 @@ The response will return devices 1 through 100. The URL provided in the `next` a
}
```
The maximum number of objects that can be returned is limited by the [`MAX_PAGE_SIZE`](../configuration/optional-settings/#max_page_size) setting, which is 1000 by default. Setting this to `0` or `None` will remove the maximum limit. An API consumer can then pass `?limit=0` to retrieve _all_ matching objects with a single request.
The maximum number of objects that can be returned is limited by the [`MAX_PAGE_SIZE`](../../configuration/optional-settings/#max_page_size) setting, which is 1000 by default. Setting this to `0` or `None` will remove the maximum limit. An API consumer can then pass `?limit=0` to retrieve _all_ matching objects with a single request.
!!! warning
Disabling the page size limit introduces a potential for very resource-intensive requests, since one API request can effectively retrieve an entire table from the database.

View File

@@ -2,7 +2,7 @@ As with most other objects, the NetBox API can be used to create, modify, and de
# Generating a Session Key
In order to encrypt or decrypt secret data, a session key must be attached to the API request. To generate a session key, send an authenticated request to the `/api/secrets/get-session-key/` endpoint with the private RSA key which matches your [UserKey](../data-model/secrets/#user-keys). The private key must be POSTed with the name `private_key`.
In order to encrypt or decrypt secret data, a session key must be attached to the API request. To generate a session key, send an authenticated request to the `/api/secrets/get-session-key/` endpoint with the private RSA key which matches your [UserKey](../../core-functionality/secrets/#user-keys). The private key must be POSTed with the name `private_key`.
```
$ curl -X POST http://localhost:8000/api/secrets/get-session-key/ \

View File

@@ -139,7 +139,7 @@ Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce uni
By default, all messages of INFO severity or higher will be logged to the console. Additionally, if `DEBUG` is False and email access has been configured, ERROR and CRITICAL messages will be emailed to the users defined in `ADMINS`.
The Django framework on which NetBox runs allows for the customization of logging, e.g. to write logs to file. Please consult the [Django logging documentation](https://docs.djangoproject.com/en/1.11/topics/logging/) for more information on configuring this setting. Below is an example which will write all INFO and higher messages to a file:
The Django framework on which NetBox runs allows for the customization of logging, e.g. to write logs to file. Please consult the [Django logging documentation](https://docs.djangoproject.com/en/stable/topics/logging/) for more information on configuring this setting. Below is an example which will write all INFO and higher messages to a file:
```
LOGGING = {
@@ -207,7 +207,7 @@ The file path to the location where media files (such as image attachments) are
Default: False
Toggle exposing Prometheus metrics at `/metrics`. See the [Prometheus Metrics](../additional-features/prometheus-metrics/) documentation for more details.
Toggle exposing Prometheus metrics at `/metrics`. See the [Prometheus Metrics](../../additional-features/prometheus-metrics/) documentation for more details.
---
@@ -293,6 +293,26 @@ Session data is used to track authenticated users when they access NetBox. By de
---
## STORAGE_BACKEND
Default: None (local storage)
The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) package, which provides backends for several popular file storage services. If not configured, local filesystem storage will be used.
The configuration parameters for the specified storage backend are defined under the `STORAGE_CONFIG` setting.
---
## STORAGE_CONFIG
Default: Empty
A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the [`django-storages` documentation](https://django-storages.readthedocs.io/en/stable/) for more detail.
If `STORAGE_BACKEND` is not defined, this setting will be ignored.
---
## TIME_ZONE
Default: UTC
@@ -301,17 +321,9 @@ The time zone NetBox will use when dealing with dates and times. It is recommend
---
## WEBHOOKS_ENABLED
Default: False
Enable this option to run the webhook backend. See the docs section on the webhook backend [here](../additional-features/webhooks/) for more information on setup and use.
---
## Date and Time Formatting
You may define custom formatting for date and times. For detailed instructions on writing format strings, please see [the Django documentation](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date).
You may define custom formatting for date and times. For detailed instructions on writing format strings, please see [the Django documentation](https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date).
Defaults:

View File

@@ -2,7 +2,7 @@
## ALLOWED_HOSTS
This is a list of valid fully-qualified domain names (FQDNs) that is used to reach the NetBox service. Usually this is the same as the hostname for the NetBox server, but can also be different (e.g. when using a reverse proxy serving the NetBox website under a different FQDN than the hostname of the NetBox server). NetBox will not permit access to the server via any other hostnames (or IPs). The value of this option is also used to set `CSRF_TRUSTED_ORIGINS`, which restricts `HTTP POST` to the same set of hosts (more about this [here](https://docs.djangoproject.com/en/1.9/ref/settings/#std:setting-CSRF_TRUSTED_ORIGINS)). Keep in mind that NetBox, by default, has `USE_X_FORWARDED_HOST = True` (in `netbox/netbox/settings.py`) which means that if you're using a reverse proxy, it's the FQDN used to reach that reverse proxy which needs to be in this list (more about this [here](https://docs.djangoproject.com/en/1.9/ref/settings/#allowed-hosts)).
This is a list of valid fully-qualified domain names (FQDNs) that is used to reach the NetBox service. Usually this is the same as the hostname for the NetBox server, but can also be different (e.g. when using a reverse proxy serving the NetBox website under a different FQDN than the hostname of the NetBox server). NetBox will not permit access to the server via any other hostnames (or IPs). The value of this option is also used to set `CSRF_TRUSTED_ORIGINS`, which restricts `HTTP POST` to the same set of hosts (more about this [here](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-CSRF_TRUSTED_ORIGINS)). Keep in mind that NetBox, by default, has `USE_X_FORWARDED_HOST = True` (in `netbox/netbox/settings.py`) which means that if you're using a reverse proxy, it's the FQDN used to reach that reverse proxy which needs to be in this list (more about this [here](https://docs.djangoproject.com/en/stable/ref/settings/#allowed-hosts)).
Example:
@@ -21,16 +21,18 @@ NetBox requires access to a PostgreSQL database service to store data. This serv
* `PASSWORD` - PostgreSQL password
* `HOST` - Name or IP address of the database server (use `localhost` if running locally)
* `PORT` - TCP port of the PostgreSQL service; leave blank for default port (5432)
* `CONN_MAX_AGE` - Number in seconds for Netbox to keep database connections open. 150-300 seconds is typically a good starting point ([more info](https://docs.djangoproject.com/en/stable/ref/databases/#persistent-connections)).
Example:
```
```python
DATABASE = {
'NAME': 'netbox', # Database name
'USER': 'netbox', # PostgreSQL username
'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password
'HOST': 'localhost', # Database server
'PORT': '', # Database port (leave blank for default)
'CONN_MAX_AGE': 300, # Max database connection age
}
```
@@ -40,40 +42,48 @@ DATABASE = {
[Redis](https://redis.io/) is an in-memory data store similar to memcached. While Redis has been an optional component of
NetBox since the introduction of webhooks in version 2.4, it is required starting in 2.6 to support NetBox's caching
functionality (as well as other planned features).
functionality (as well as other planned features). In 2.7, the connection settings were broken down into two sections for
webhooks and caching, allowing the user to connect to different Redis instances/databases per feature.
Redis is configured using a configuration setting similar to `DATABASE`:
Redis is configured using a configuration setting similar to `DATABASE` and these settings are the same for both of the `webhooks` and `caching` subsections:
* `HOST` - Name or IP address of the Redis server (use `localhost` if running locally)
* `PORT` - TCP port of the Redis service; leave blank for default port (6379)
* `PASSWORD` - Redis password (if set)
* `DATABASE` - Numeric database ID for webhooks
* `CACHE_DATABASE` - Numeric database ID for caching
* `DATABASE` - Numeric database ID
* `DEFAULT_TIMEOUT` - Connection timeout in seconds
* `SSL` - Use SSL connection to Redis
Example:
```
```python
REDIS = {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 0,
'CACHE_DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
'webhooks': {
'HOST': 'redis.example.com',
'PORT': 1234,
'PASSWORD': 'foobar',
'DATABASE': 0,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
}
```
!!! note:
If you were using these settings in a prior release with webhooks, the `DATABASE` setting remains the same but
an additional `CACHE_DATABASE` setting has been added with a default value of 1 to support the caching backend. The
`DATABASE` setting will be renamed in a future release of NetBox to better relay the meaning of the setting.
If you are upgrading from a version prior to v2.7, please note that the Redis connection configuration settings have
changed. Manual modification to bring the `REDIS` section inline with the above specification is necessary
!!! warning:
It is highly recommended to keep the webhook and cache databases seperate. Using the same database number for both may result in webhook
processing data being lost in cache flushing events.
It is highly recommended to keep the webhook and cache databases separate. Using the same database number on the
same Redis instance for both may result in webhook processing data being lost during cache flushing events.
---

View File

@@ -0,0 +1,58 @@
# Power Panel
A power panel represents the distribution board where power circuits and their circuit breakers terminate on. If you have multiple power panels in your data center, you should model them as such in NetBox to assist you in determining the redundancy of your power allocation.
# Power Feed
A power feed identifies the power outlet/drop that goes to a rack and is terminated to a power panel. Power feeds have a supply type (AC/DC), voltage, amperage, and phase type (single/three).
Power feeds are optionally assigned to a rack. In addition, a power port and only one can connect to a power feed; in the context of a PDU, the power feed is analogous to the power outlet that a PDU's power port/inlet connects to.
!!! info
The power usage of a rack is calculated when a power feed (or multiple) is assigned to that rack and connected to a power port.
# Power Outlet
Power outlets represent the ports on a PDU that supply power to other devices. Power outlets are downstream-facing towards power ports. A power outlet can be associated with a power port on the same device and a feed leg (i.e. in a case of a three-phase supply). This indicates which power port supplies power to a power outlet.
# Power Port
A power port is the inlet of a device where it draws its power. Power ports are upstream-facing towards power outlets. Alternatively, a power port can connect to a power feed as mentioned in the power feed section to indicate the power source of a PDU's inlet.
!!! info
If the draw of a power port is left empty, it will be dynamically calculated based on the power outlets associated with that power port. This is usually the case on the power ports of devices that supply power, like a PDU.
# Example
Below is a simple diagram demonstrating how power is modelled in NetBox.
!!! note
The power feeds are connected to the same power panel for illustrative purposes; usually, you would have such feeds diversely connected to panels to avoid the single point of failure.
```
+---------------+
| Power panel 1 |
+---------------+
| |
| |
+--------------+ +--------------+
| Power feed 1 | | Power feed 2 |
+--------------+ +--------------+
| |
| |
| | <-- Power ports
+---------+ +---------+
| PDU 1 | | PDU 2 |
+---------+ +---------+
| \ / | <-- Power outlets
| \ / |
| \ / |
| X |
| / \ |
| / \ |
| / \ | <-- Power ports
+--------+ +--------+
| Server | | Router |
+--------+ +--------+
```

View File

@@ -24,6 +24,20 @@ Each user within NetBox can associate his or her account with an RSA public key.
User keys may be created by users individually, however they are of no use until they have been activated by a user who already possesses an active user key.
## Supported Key Format
Public key formats supported
- PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
- X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
- **OpenSSH line format is not supported.**
Private key formats supported (unencrypted)
- PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY)
- PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY)
## Creating the First User Key
When NetBox is first installed, it contains no encryption keys. Before it can store secrets, a user (typically the superuser) must create a user key. This can be done by navigating to Profile > User Key.

View File

@@ -40,6 +40,8 @@ Racks can be arranged into groups. As with sites, how you choose to designate ra
Each rack group must be assigned to a parent site. Hierarchical recursion of rack groups is not currently supported.
The name and facility ID of each rack within a group must be unique. (Racks not assigned to the same rack group may have identical names and/or facility IDs.)
## Rack Roles
Each rack can optionally be assigned a functional role. For example, you might designate a rack for compute or storage resources, or to house colocated customer devices. Rack roles are fully customizable.

View File

@@ -69,6 +69,14 @@ If the new field will be included in the object list view, add a column to the m
Edit the object's view template to display the new field. There may also be a custom add/edit form template that needs to be updated.
### 11. Adjust API and model tests
### 11. Create/extend test cases
Extend the model and/or API tests to verify that the new field and any accompanying validation logic perform as expected. This is especially important for relational fields.
Create or extend the relevant test cases to verify that the new field and any accompanying validation logic perform as expected. This is especially important for relational fields. NetBox incorporates various test suites, including:
* API serializer/view tests
* Filter tests
* Form tests
* Model tests
* View tests
Be diligent to ensure all of the relevant test suites are adapted or extended as necessary to test any new functionality.

View File

@@ -33,6 +33,14 @@ Update the following static libraries to their most recent stable release:
* jQuery
* jQuery UI
## Squash Schema Migrations
Database schema migrations should be squashed for each new minor release. See the [squashing guide](squashing-migrations.md) for the detailed process.
## Create a new Release Notes Page
Create a file at `/docs/release-notes/X.Y.md` to establish the release notes for the new release. Add the file to the table of contents within `mkdocs.yml`.
## Manually Perform a New Install
Create a new installation of NetBox by following [the current documentation](http://netbox.readthedocs.io/en/latest/). This should be a manual process, so that issues with the documentation can be identified and corrected.
@@ -51,7 +59,7 @@ Ensure that continuous integration testing on the `develop` branch is completing
## Update Version and Changelog
Update the `VERSION` constant in `settings.py` to the new release version and add the current date to the release notes in `CHANGELOG.md`.
Update the `VERSION` constant in `settings.py` to the new release version and annotate the current data in the release notes for the new version.
## Submit a Pull Request

View File

@@ -0,0 +1,168 @@
# Squashing Database Schema Migrations
## What are Squashed Migrations?
The Django framework on which NetBox is built utilizes [migration files](https://docs.djangoproject.com/en/stable/topics/migrations/) to keep track of changes to the PostgreSQL database schema. Each time a model is altered, the resulting schema change is captured in a migration file, which can then be applied to effect the new schema.
As changes are made over time, more and more migration files are created. Although not necessarily problematic, it can be beneficial to merge and compress these files occasionally to reduce the total number of migrations that need to be applied upon installation of NetBox. This merging process is called _squashing_ in Django vernacular, and results in two parallel migration paths: individual and squashed.
Below is an example showing both individual and squashed migration files within an app:
| Individual | Squashed |
|------------|----------|
| 0001_initial | 0001_initial_squashed_0004_add_field |
| 0002_alter_field | . |
| 0003_remove_field | . |
| 0004_add_field | . |
| 0005_another_field | 0005_another_field |
In the example above, a new installation can leverage the squashed migrations to apply only two migrations:
* `0001_initial_squashed_0004_add_field`
* `0005_another_field`
This is because the squash file contains all of the operations performed by files `0001` through `0004`.
However, an existing installation that has already applied some of the individual migrations contained within the squash file must continue applying individual migrations. For instance, an installation which currently has up to `0002_alter_field` applied must apply the following migrations to become current:
* `0003_remove_field`
* `0004_add_field`
* `0005_another_field`
Squashed migrations are opportunistic: They are used only if applicable to the current environment. Django will fall back to using individual migrations if the squashed migrations do not agree with the current database schema at any point.
## Squashing Migrations
During every minor (i.e. 2.x) release, migrations should be squashed to help simplify the migration process for new installations. The process below describes how to squash migrations efficiently and with minimal room for error.
### 1. Create a New Branch
Create a new branch off of the `develop-2.x` branch. (Migrations should be squashed _only_ in preparation for a new minor release.)
```
git checkout -B squash-migrations
```
### 2. Delete Existing Squash Files
Delete the most recent squash file within each NetBox app. This allows us to extend squash files where the opportunity exists. For example, we might be able to replace `0005_to_0008` with `0005_to_0011`.
### 3. Generate the Current Migration Plan
Use Django's `showmigrations` utility to display the order in which all migrations would be applied for a new installation.
```
manage.py showmigrations --plan
```
From the resulting output, delete all lines which reference an external migration. Any migrations imposed by Django itself on an external package are not relevant.
### 4. Create Squash Files
Begin iterating through the migration plan, looking for successive sets of migrations within an app. These are candidates for squashing. For example:
```
[X] extras.0014_configcontexts
[X] extras.0015_remove_useraction
[X] extras.0016_exporttemplate_add_cable
[X] extras.0017_exporttemplate_mime_type_length
[ ] extras.0018_exporttemplate_add_jinja2
[ ] extras.0019_tag_taggeditem
[X] dcim.0062_interface_mtu
[X] dcim.0063_device_local_context_data
[X] dcim.0064_remove_platform_rpc_client
[ ] dcim.0065_front_rear_ports
[X] circuits.0001_initial_squashed_0010_circuit_status
[ ] dcim.0066_cables
...
```
Migrations `0014` through `0019` in `extras` can be squashed, as can migrations `0062` through `0065` in `dcim`. Migration `0066` cannot be included in the same squash file, because the `circuits` migration must be applied before it. (Note that whether or not each migration is currently applied to the database does not matter.)
Squash files are created using Django's `squashmigrations` utility:
```
manage.py squashmigrations <app> <start> <end>
```
For example, our first step in the example would be to run `manage.py squashmigrations extras 0014 0019`.
!!! note
Specifying a migration file's numeric index is enough to uniquely identify it within an app. There is no need to specify the full filename.
This will create a new squash file within the app's `migrations` directory, named as a concatenation of its beginning and ending migration. Some manual editing is necessary for each new squash file for housekeeping purposes:
* Remove the "automatically generated" comment at top (to indicate that a human has reviewed the file).
* Reorder `import` statements as necessary per PEP8.
* It may be necessary to copy over custom functions from the original migration files (this will be indicated by a comment near the top of the squash file). It is safe to remove any functions that exist solely to accomodate reverse migrations (which we no longer support).
Repeat this process for each candidate set of migrations until you reach the end of the migration plan.
### 5. Check for Missing Migrations
If everything went well, at this point we should have a completed squashed path. Perform a dry run to check for any missing migrations:
```
manage.py migrate --dry-run
```
### 5. Run Migrations
Next, we'll apply the entire migration path to an empty database. Begin by dropping and creating your development database.
!!! warning
Obviously, first back up any data you don't want to lose.
```
sudo -u postgres psql -c 'drop database netbox'
sudo -u postgres psql -c 'create database netbox'
```
Apply the migrations with the `migrate` management command. It is not necessary to specify a particular migration path; Django will detect and use the squashed migrations automatically. You can verify the exact migrations being applied by enabling verboes output with `-v 2`.
```
manage.py migrate -v 2
```
### 6. Commit the New Migrations
If everything is successful to this point, commit your changes to the `squash-migrations` branch.
### 7. Validate Resulting Schema
To ensure our new squashed migrations do not result in a deviation from the original schema, we'll compare the two. With the new migration file safely commit, check out the `develop-2.x` branch, which still contains only the individual migrations.
```
git checkout develop-2.x
```
Temporarily install the [django-extensions](https://django-extensions.readthedocs.io/) package, which provides the `sqldiff utility`:
```
pip install django-extensions
```
Also add `django_extensions` to `INSTALLED_APPS` in `netbox/netbox/settings.py`.
At this point, our database schema has been defined by using the squashed migrations. We can run `sqldiff` to see if it differs any from what the current (non-squashed) migrations would generate. `sqldiff` accepts a list of apps against which to run:
```
manage.py sqldiff circuits dcim extras ipam secrets tenancy users virtualization
```
It is safe to ignore errors indicating an "unknown database type" for the following fields:
* `dcim_interface.mac_address`
* `ipam_aggregate.prefix`
* `ipam_prefix.prefix`
It is also safe to ignore the message "Table missing: extras_script".
Resolve any differences by correcting migration files in the `squash-migrations` branch.
!!! warning
Don't forget to remove `django_extension` from `INSTALLED_APPS` before committing your changes.
### 8. Merge the Squashed Migrations
Once all squashed migrations have been validated and all tests run successfully, merge the `squash-migrations` branch into `develop-2.x`. This completes the squashing process.

View File

@@ -1,6 +1,6 @@
# Style Guide
NetBox generally follows the [Django style guide](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/), which is itself based on [PEP 8](https://www.python.org/dev/peps/pep-0008/). [Pycodestyle](https://github.com/pycqa/pycodestyle) is used to validate code formatting, ignoring certain violations. See `scripts/cibuild.sh`.
NetBox generally follows the [Django style guide](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/coding-style/), which is itself based on [PEP 8](https://www.python.org/dev/peps/pep-0008/). [Pycodestyle](https://github.com/pycqa/pycodestyle) is used to validate code formatting, ignoring certain violations. See `scripts/cibuild.sh`.
## PEP 8 Exceptions

View File

@@ -1,4 +1,4 @@
![NetBox](netbox_logo.png "NetBox logo")
![NetBox](netbox_logo.svg "NetBox logo")
# What is NetBox?

View File

@@ -4,7 +4,7 @@ NetBox requires a PostgreSQL database to store data. This can be hosted locally
The installation instructions provided here have been tested to work on Ubuntu 18.04 and CentOS 7.5. The particular commands needed to install dependencies on other distributions may vary significantly. Unfortunately, this is outside the control of the NetBox maintainers. Please consult your distribution's documentation for assistance with any errors.
!!! warning
NetBox v2.2 and later requires PostgreSQL 9.4 or higher.
NetBox requires PostgreSQL 9.4 or higher.
# Installation

View File

@@ -5,16 +5,16 @@ This section of the documentation discusses installing and configuring the NetBo
**Ubuntu**
```no-highlight
# apt-get install -y python3 python3-pip python3-dev build-essential libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev redis-server zlib1g-dev
# apt-get install -y python3 python3-pip python3-dev build-essential libxml2-dev libxslt1-dev libffi-dev libpq-dev libssl-dev redis-server zlib1g-dev
```
**CentOS**
```no-highlight
# yum install -y epel-release
# yum install -y gcc python36 python36-devel python36-setuptools libxml2-devel libxslt-devel libffi-devel graphviz openssl-devel redhat-rpm-config redis
# yum install -y gcc python36 python36-devel python36-setuptools libxml2-devel libxslt-devel libffi-devel openssl-devel redhat-rpm-config redis
# easy_install-3.6 pip
# ln -s /usr/bin/python36 /usr/bin/python3
# ln -s /usr/bin/python3.6 /usr/bin/python3
```
You may opt to install NetBox either from a numbered release or by cloning the master branch of its repository on GitHub.
@@ -90,6 +90,14 @@ NetBox supports integration with the [NAPALM automation](https://napalm-automati
# pip3 install napalm
```
## Remote File Storage (Optional)
By default, NetBox will use the local filesystem to storage uploaded files. To use a remote filesystem, install the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) library and configure your [desired backend](../../configuration/optional-settings/#storage_backend) in `configuration.py`.
```no-highlight
# pip3 install django-storages
```
# Configuration
Move into the NetBox configuration directory and make a copy of `configuration.example.py` named `configuration.py`.
@@ -118,7 +126,7 @@ ALLOWED_HOSTS = ['netbox.example.com', '192.0.2.123']
## DATABASE
This parameter holds the database configuration details. You must define the username and password used when you configured PostgreSQL. If the service is running on a remote host, replace `localhost` with its address. See the [configuration documentation](../configuration/required-settings/#database) for more detail on individual parameters.
This parameter holds the database configuration details. You must define the username and password used when you configured PostgreSQL. If the service is running on a remote host, replace `localhost` with its address. See the [configuration documentation](../../configuration/required-settings/#database) for more detail on individual parameters.
Example:
@@ -129,22 +137,32 @@ DATABASE = {
'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password
'HOST': 'localhost', # Database server
'PORT': '', # Database port (leave blank for default)
'CONN_MAX_AGE': 300, # Max database connection age
}
```
## REDIS
Redis is a in-memory key-value store required as part of the NetBox installation. It is used for features such as webhooks and caching. Redis typically requires minimal configuration; the values below should suffice for most installations. See the [configuration documentation](../configuration/required-settings/#redis) for more detail on individual parameters.
Redis is a in-memory key-value store required as part of the NetBox installation. It is used for features such as webhooks and caching. Redis typically requires minimal configuration; the values below should suffice for most installations. See the [configuration documentation](../../configuration/required-settings/#redis) for more detail on individual parameters.
```python
REDIS = {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 0,
'CACHE_DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
'webhooks': {
'HOST': 'redis.example.com',
'PORT': 1234,
'PASSWORD': 'foobar',
'DATABASE': 0,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
}
```
@@ -194,27 +212,7 @@ Superuser created successfully.
```no-highlight
# python3 manage.py collectstatic --no-input
You have requested to collect static files at the destination
location as specified in your settings:
/opt/netbox/netbox/static
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes
```
# Load Initial Data (Optional)
NetBox ships with some initial data to help you get started: RIR definitions, common devices roles, etc. You can delete any seed data that you don't want to keep.
!!! note
This step is optional. It's perfectly fine to start using NetBox without using this initial data if you'd rather create everything from scratch.
```no-highlight
# python3 manage.py loaddata initial_data
Installed 43 object(s) from 4 fixture(s)
959 static files copied to '/opt/netbox/netbox/static'.
```
# Test the Application
@@ -236,3 +234,11 @@ Next, connect to the name or IP of the server (as defined in `ALLOWED_HOSTS`) on
!!! warning
If the test service does not run, or you cannot reach the NetBox home page, something has gone wrong. Do not proceed with the rest of this guide until the installation has been corrected.
Note that the initial UI will be locked down for non-authenticated users.
![NetBox UI as seen by a non-authenticated user](../media/installation/netbox_ui_guest.png)
After logging in as the superuser you created earlier, all areas of the UI will be available.
![NetBox UI as seen by an administrator](../media/installation/netbox_ui_admin.png)

View File

@@ -1,4 +1,4 @@
We'll set up a simple WSGI front end using [gunicorn](http://gunicorn.org/) for the purposes of this guide. For web servers, we provide example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/2.4). (You are of course free to use whichever combination of HTTP and WSGI services you'd like.) We'll also use [supervisord](http://supervisord.org/) to enable service persistence.
We'll set up a simple WSGI front end using [gunicorn](http://gunicorn.org/) for the purposes of this guide. For web servers, we provide example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/2.4). (You are of course free to use whichever combination of HTTP and WSGI services you'd like.) We'll use systemd to enable service persistence.
!!! info
For the sake of brevity, only Ubuntu 18.04 instructions are provided here, but this sort of web server and WSGI configuration is not unique to NetBox. Please consult your distribution's documentation for assistance if needed.
@@ -32,7 +32,6 @@ server {
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
```
@@ -108,45 +107,53 @@ Install gunicorn:
# pip3 install gunicorn
```
Save the following configuration in the root netbox installation path as `gunicorn_config.py` (e.g. `/opt/netbox/gunicorn_config.py` per our example installation). Be sure to verify the location of the gunicorn executable on your server (e.g. `which gunicorn`) and to update the `pythonpath` variable if needed. If using CentOS/RHEL, change the username from `www-data` to `nginx` or `apache`.
Copy `contrib/gunicorn.py` to `/opt/netbox/gunicorn.py`. We make a copy of this file to ensure that any changes to it do not get overwritten by a future upgrade.
```no-highlight
command = '/usr/bin/gunicorn'
pythonpath = '/opt/netbox/netbox'
bind = '127.0.0.1:8001'
workers = 3
user = 'www-data'
# cp contrib/gunicorn.py /opt/netbox/gunicorn.py
```
# supervisord Installation
You may wish to edit this file to change the bound IP address or port number, or to make performance-related adjustments.
Install supervisor:
# systemd configuration
We'll use systemd to control the daemonization of NetBox services. First, copy `contrib/netbox.service` and `contrib/netbox-rq.service` to the `/etc/systemd/system/` directory:
```no-highlight
# apt-get install -y supervisor
# cp contrib/*.service /etc/systemd/system/
```
Save the following as `/etc/supervisor/conf.d/netbox.conf`. Update the `command` and `directory` paths as needed. If using CentOS/RHEL, change the username from `www-data` to `nginx` or `apache`.
!!! note
These service files assume that gunicorn is installed at `/usr/local/bin/gunicorn`. If the output of `which gunicorn` indicates a different path, you'll need to correct the `ExecStart` path in both files.
Then, start the `netbox` and `netbox-rq` services and enable them to initiate at boot time:
```no-highlight
[program:netbox]
command = gunicorn -c /opt/netbox/gunicorn_config.py netbox.wsgi
directory = /opt/netbox/netbox/
user = www-data
[program:netbox-rqworker]
command = python3 /opt/netbox/netbox/manage.py rqworker
directory = /opt/netbox/netbox/
user = www-data
# systemctl daemon-reload
# systemctl start netbox.service
# systemctl start netbox-rq.service
# systemctl enable netbox.service
# systemctl enable netbox-rq.service
```
Then, restart the supervisor service to detect and run the gunicorn service:
You can use the command `systemctl status netbox` to verify that the WSGI service is running:
```no-highlight
# service supervisor restart
```
# systemctl status netbox.service
● netbox.service - NetBox WSGI Service
Loaded: loaded (/etc/systemd/system/netbox.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-12-12 19:23:40 UTC; 25s ago
Docs: https://netbox.readthedocs.io/en/stable/
Main PID: 11993 (gunicorn)
Tasks: 6 (limit: 2362)
CGroup: /system.slice/netbox.service
├─11993 /usr/bin/python3 /usr/local/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/...
├─12015 /usr/bin/python3 /usr/local/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/...
├─12016 /usr/bin/python3 /usr/local/bin/gunicorn --pid /var/tmp/netbox.pid --pythonpath /opt/netbox/...
...
```
At this point, you should be able to connect to the nginx HTTP service at the server name or IP address you provided. If you are unable to connect, check that the nginx service is running and properly configured. If you receive a 502 (bad gateway) error, this indicates that gunicorn is misconfigured or not running.
At this point, you should be able to connect to the HTTP service at the server name or IP address you provided. If you are unable to connect, check that the nginx service is running and properly configured. If you receive a 502 (bad gateway) error, this indicates that gunicorn is misconfigured or not running.
!!! info
Please keep in mind that the configurations provided here are bare minimums required to get NetBox up and running. You will almost certainly want to make some changes to better suit your production environment.
Please keep in mind that the configurations provided here are bare minimums required to get NetBox up and running. You may want to make adjustments to better suit your production environment.

View File

@@ -80,6 +80,7 @@ AUTH_LDAP_USER_ATTR_MAP = {
```
# User Groups for Permissions
!!! info
When using Microsoft Active Directory, support for nested groups can be activated by using `NestedGroupOfNamesType()` instead of `GroupOfNamesType()` for `AUTH_LDAP_GROUP_TYPE`. You will also need to modify the import line to use `NestedGroupOfNamesType` instead of `GroupOfNamesType` .
@@ -117,6 +118,9 @@ AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
* `is_staff` - Users mapped to this group are enabled for access to the administration tools; this is the equivalent of checking the "staff status" box on a manually created user. This doesn't grant any specific permissions.
* `is_superuser` - Users mapped to this group will be granted superuser status. Superusers are implicitly granted all permissions.
!!! warning
Authentication will fail if the groups (the distinguished names) do not exist in the LDAP directory.
# Troubleshooting LDAP
`supervisorctl restart netbox` restarts the Netbox service, and initiates any changes made to `ldap_config.py`. If there are syntax errors present, the NetBox process will not spawn an instance, and errors should be logged to `/var/log/supervisor/`.

View File

@@ -12,3 +12,5 @@ The following sections detail how to set up a new instance of NetBox:
If you are upgrading from an existing installation, please consult the [upgrading guide](upgrading.md).
NetBox v2.5 and later requires Python 3.5 or higher. Please see the instructions for [migrating to Python 3](migrating-to-python3.md) if you are still using Python 2.
Netbox v2.5.9 and later moved to using systemd instead of supervisord. Please see the instructions for [migrating to systemd](migrating-to-systemd.md) if you are still using supervisord.

View File

@@ -0,0 +1,100 @@
# Migration
Migration is not required, as supervisord will still continue to function.
## Ubuntu
### Remove supervisord:
```no-highlight
# apt-get remove -y supervisord
```
### systemd configuration:
Copy or link contrib/netbox.service and contrib/netbox-rq.service to /etc/systemd/system/netbox.service and /etc/systemd/system/netbox-rq.service
```no-highlight
# cp contrib/netbox.service /etc/systemd/system/netbox.service
# cp contrib/netbox-rq.service /etc/systemd/system/netbox-rq.service
```
Edit /etc/systemd/system/netbox.service and /etc/systemd/system/netbox-rq.service. Be sure to verify the location of the gunicorn executable on your server (e.g. `which gunicorn`). If using CentOS/RHEL. Change the username from `www-data` to `nginx` or `apache`:
```no-highlight
/usr/local/bin/gunicorn --pid ${PidPath} --pythonpath ${WorkingDirectory}/netbox --config ${ConfigPath} netbox.wsgi
```
```no-highlight
User=www-data
Group=www-data
```
Copy contrib/netbox.env to /etc/sysconfig/netbox.env
```no-highlight
# cp contrib/netbox.env /etc/sysconfig/netbox.env
```
Edit /etc/sysconfig/netbox.env and change the settings as required. Update the `WorkingDirectory` variable if needed.
```no-highlight
# Name is the Process Name
#
Name = 'Netbox'
# ConfigPath is the path to the gunicorn config file.
#
ConfigPath=/opt/netbox/gunicorn.conf
# WorkingDirectory is the Working Directory for Netbox.
#
WorkingDirectory=/opt/netbox/
# PidPath is the path to the pid for the netbox WSGI
#
PidPath=/var/run/netbox.pid
```
Copy contrib/gunicorn.conf to gunicorn.conf
```no-highlight
# cp contrib/gunicorn.conf to gunicorn.conf
```
Edit gunicorn.conf and change the settings as required.
```
# Bind is the ip and port that the Netbox WSGI should bind to
#
bind='127.0.0.1:8001'
# Workers is the number of workers that GUnicorn should spawn.
# Workers should be: cores * 2 + 1. So if you have 8 cores, it would be 17.
#
workers=3
# Threads
# The number of threads for handling requests
#
threads=3
# Timeout is the timeout between gunicorn receiving a request and returning a response (or failing with a 500 error)
#
timeout=120
# ErrorLog
# ErrorLog is the logfile for the ErrorLog
#
errorlog='/opt/netbox/netbox.log'
```
Finally, start the `netbox` and `netbox-rq` services and enable them to initiate at boot time:
```no-highlight
# systemctl daemon-reload
# systemctl start netbox.service
# systemctl start netbox-rq.service
# systemctl enable netbox.service
# systemctl enable netbox-rq.service
```

View File

@@ -1,3 +1,7 @@
# Review the Release Notes
Prior to upgrading your NetBox instance, be sure to carefully review all [release notes](../../release-notes/) that have been published since your current version was released. Although the upgrade process typically does not involve additional work, certain releases may introduce breaking or backward-incompatible changes. These are called out in the release notes under the version in which the change went into effect.
# Install the Latest Code
As with the initial installation, you can upgrade NetBox by either downloading the latest release package or by cloning the `master` branch of the git repository.
@@ -80,14 +84,12 @@ This script:
# Restart the WSGI Service
Finally, restart the WSGI service to run the new code. If you followed this guide for the initial installation, this is done using `supervisorctl`:
Finally, restart the WSGI services to run the new code. If you followed this guide for the initial installation, this is done using `systemctl:
```no-highlight
# sudo supervisorctl restart netbox
# sudo systemctl restart netbox
# sudo systemctl restart netbox-rqworker
```
If using webhooks, also restart the Redis worker:
```no-highlight
# sudo supervisorctl restart netbox-rqworker
```
!!! note
It's possible you are still using supervisord instead of the linux native systemd. If you are still using supervisord you can restart the services by either restarting supervisord or by using supervisorctl to restart netbox.

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

21
docs/netbox_logo.svg Normal file
View File

@@ -0,0 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 320">
<g fill="#9cc8f8" stroke="#9cc8f8">
<circle cx="37" cy="284" r="23"/>
<circle cx="101" cy="37" r="23"/>
<circle cx="101" cy="220" r="23"/>
<circle cx="284" cy="220" r="23"/>
<rect x="93" y="37" width="16" height="180"/>
<rect x="101" y="212" width="180" height="16"/>
<rect x="93" y="212" width="16" height="90" transform="rotate(45 101 220)"/>
</g>
<g fill="#1685fc" stroke="#1685fc">
<circle cx="284" cy="37" r="23"/>
<circle cx="37" cy="101" r="23"/>
<circle cx="220" cy="101" r="23"/>
<circle cx="220" cy="284" r="23"/>
<rect x="37" y="93" width="180" height="16"/>
<rect x="212" y="101" width="16" height="180"/>
<rect x="212" y="93" width="16" height="90" transform="rotate(225 220 101)"/>
<path transform="translate(380, 8)" d="M13.60 200L13.60 104L36.40 104L36.40 119.40L36.80 119.40Q40.20 112.20 47.20 106.90Q54.20 101.60 66.20 101.60L66.20 101.60Q75.80 101.60 82.50 104.80Q89.20 108 93.40 113.20Q97.60 118.40 99.40 125.20Q101.20 132 101.20 139.40L101.20 139.40L101.20 200L77.20 200L77.20 151.40Q77.20 147.40 76.80 142.50Q76.40 137.60 74.70 133.30Q73 129 69.40 126.10Q65.80 123.20 59.60 123.20L59.60 123.20Q53.60 123.20 49.50 125.20Q45.40 127.20 42.70 130.60Q40 134 38.80 138.40Q37.60 142.80 37.60 147.60L37.60 147.60L37.60 200L13.60 200ZM224.80 160.40L151.60 160.40Q152.80 171.20 160 177.20Q167.20 183.20 177.40 183.20L177.40 183.20Q186.40 183.20 192.50 179.50Q198.60 175.80 203.20 170.20L203.20 170.20L220.40 183.20Q212 193.60 201.60 198Q191.20 202.40 179.80 202.40L179.80 202.40Q169 202.40 159.40 198.80Q149.80 195.20 142.80 188.60Q135.80 182 131.70 172.70Q127.60 163.40 127.60 152L127.60 152Q127.60 140.60 131.70 131.30Q135.80 122 142.80 115.40Q149.80 108.80 159.40 105.20Q169 101.60 179.80 101.60L179.80 101.60Q189.80 101.60 198.10 105.10Q206.40 108.60 212.30 115.20Q218.20 121.80 221.50 131.50Q224.80 141.20 224.80 153.80L224.80 153.80L224.80 160.40ZM151.60 142.40L200.80 142.40Q200.60 131.80 194.20 125.70Q187.80 119.60 176.40 119.60L176.40 119.60Q165.60 119.60 159.30 125.80Q153 132 151.60 142.40L151.60 142.40ZM259.80 124.40L240.00 124.40L240.00 104L259.80 104L259.80 76.20L283.80 76.20L283.80 104L310.20 104L310.20 124.40L283.80 124.40L283.80 166.40Q283.80 173.60 286.50 177.80Q289.20 182 297.20 182L297.20 182Q300.40 182 304.20 181.30Q308 180.60 310.20 179L310.20 179L310.20 199.20Q306.40 201 300.90 201.70Q295.40 202.40 291.20 202.40L291.20 202.40Q281.60 202.40 275.50 200.30Q269.40 198.20 265.90 193.90Q262.40 189.60 261.10 183.20Q259.80 176.80 259.80 168.40L259.80 168.40L259.80 124.40ZM333.20 200L333.20 48.80L357.20 48.80L357.20 116.20L357.80 116.20Q359.60 113.80 362.40 111.30Q365.20 108.80 369.20 106.60Q373.20 104.40 378.40 103Q383.60 101.60 390.40 101.60L390.40 101.60Q400.60 101.60 409.20 105.50Q417.80 109.40 423.90 116.20Q430 123 433.40 132.20Q436.80 141.40 436.80 152L436.80 152Q436.80 162.60 433.60 171.80Q430.40 181 424.20 187.80Q418 194.60 409.20 198.50Q400.40 202.40 389.40 202.40L389.40 202.40Q379.20 202.40 370.40 198.40Q361.60 194.40 356.40 185.60L356.40 185.60L356 185.60L356 200L333.20 200ZM412.80 152L412.80 152Q412.80 146.40 410.90 141.20Q409 136 405.30 132Q401.60 128 396.40 125.60Q391.20 123.20 384.60 123.20L384.60 123.20Q378 123.20 372.80 125.60Q367.60 128 363.90 132Q360.20 136 358.30 141.20Q356.40 146.40 356.40 152L356.40 152Q356.40 157.60 358.30 162.80Q360.20 168 363.90 172Q367.60 176 372.80 178.40Q378 180.80 384.60 180.80L384.60 180.80Q391.20 180.80 396.40 178.40Q401.60 176 405.30 172Q409 168 410.90 162.80Q412.80 157.60 412.80 152ZM458.40 152L458.40 152Q458.40 140.60 462.50 131.30Q466.60 122 473.60 115.40Q480.60 108.80 490.20 105.20Q499.80 101.60 510.60 101.60L510.60 101.60Q521.40 101.60 531 105.20Q540.60 108.80 547.60 115.40Q554.60 122 558.70 131.30Q562.80 140.60 562.80 152L562.80 152Q562.80 163.40 558.70 172.70Q554.60 182 547.60 188.60Q540.60 195.20 531 198.80Q521.40 202.40 510.60 202.40L510.60 202.40Q499.80 202.40 490.20 198.80Q480.60 195.20 473.60 188.60Q466.60 182 462.50 172.70Q458.40 163.40 458.40 152ZM482.40 152L482.40 152Q482.40 157.60 484.30 162.80Q486.20 168 489.90 172Q493.60 176 498.80 178.40Q504 180.80 510.60 180.80L510.60 180.80Q517.20 180.80 522.40 178.40Q527.60 176 531.30 172Q535 168 536.90 162.80Q538.80 157.60 538.80 152L538.80 152Q538.80 146.40 536.90 141.20Q535 136 531.30 132Q527.60 128 522.40 125.60Q517.20 123.20 510.60 123.20L510.60 123.20Q504 123.20 498.80 125.60Q493.60 128 489.90 132Q486.20 136 484.30 141.20Q482.40 146.40 482.40 152ZM575.40 200L614 148.40L580.80 104L610 104L629.20 132.80L650 104L677.40 104L644.60 148.40L683.20 200L654 200L629 165.60L603.80 200L575.40 200Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

1
docs/release-notes/index.md Symbolic link
View File

@@ -0,0 +1 @@
version-2.7.md

View File

@@ -0,0 +1,22 @@
# v1.0.7-r1 (2016-07-05)
* [#199](https://github.com/netbox-community/netbox/issues/199) - Correct IP address validation
---
# v1.0.7 (2016-06-30)
**Note:** If upgrading from a previous release, be sure to run ./upgrade.sh after downloading the new code.
* [#135](https://github.com/netbox-community/netbox/issues/135) - Fixed display of navigation menu on mobile screens
* [#141](https://github.com/netbox-community/netbox/issues/141) - Fixed rendering of "getting started" guide
* Modified upgrade.sh to use sudo for pip installations
* [#109](https://github.com/netbox-community/netbox/issues/109) - Hide the navigation menu from anonymous users if login is required
* [#143](https://github.com/netbox-community/netbox/issues/143) - Add help_text to Device.position
* [#136](https://github.com/netbox-community/netbox/issues/136) - Prefixes which have host bits set will trigger an error instead of being silently corrected
* [#140](https://github.com/netbox-community/netbox/issues/140) - Improved support for Unicode in object names
---
# v1.0.0 (2016-06-27)
NetBox was originally developed internally at DigitalOcean by the network development team. This release marks the debut of NetBox as an open source project.

View File

@@ -0,0 +1,15 @@
# v1.1.0 (2016-07-07)
## New Features
* [#107](https://github.com/netbox-community/netbox/pull/107) - Docker support
* [#91](https://github.com/netbox-community/netbox/issues/91) - Support for subdevices within a device
* [#170](https://github.com/netbox-community/netbox/pull/170) - Added MAC address field to interfaces
## Bug Fixes
* [#169](https://github.com/netbox-community/netbox/issues/169) - Fix rendering of cancellation URL when editing objects
* [#183](https://github.com/netbox-community/netbox/issues/183) - Ignore vi swap files
* [#209](https://github.com/netbox-community/netbox/issues/209) - Corrected error when not confirming component template deletions
* [#214](https://github.com/netbox-community/netbox/issues/214) - Fixed redundant message on bulk interface creation
* [#68](https://github.com/netbox-community/netbox/issues/68) - Improved permissions-related error reporting for secrets

View File

@@ -0,0 +1,48 @@
# v1.2.2 (2016-07-14)
## Improvements
* [#174](https://github.com/netbox-community/netbox/issues/174) - Added search and site filter to provider list
* [#270](https://github.com/netbox-community/netbox/issues/270) - Added the ability to filter devices by rack group
## Bug Fixes
* [#115](https://github.com/netbox-community/netbox/issues/115) - Fix deprecated django.core.context_processors reference
* [#268](https://github.com/netbox-community/netbox/issues/268) - Added support for entire 32-bit ASN space
* [#282](https://github.com/netbox-community/netbox/issues/282) - De-select "all" checkbox if one or more objects are deselected
* [#290](https://github.com/netbox-community/netbox/issues/290) - Always display management interfaces for a device type (even if `is_network_device` is not set)
---
# v1.2.1 (2016-07-13)
**Note:** This release introduces a new dependency ([natsort](https://pypi.python.org/pypi/natsort)). Be sure to run `upgrade.sh` if upgrading from a previous release.
## Improvements
* [#285](https://github.com/netbox-community/netbox/issues/285) - Added the ability to prefer IPv4 over IPv6 for primary device IPs
## Bug Fixes
* [#243](https://github.com/netbox-community/netbox/issues/243) - Improved ordering of device object lists
* [#271](https://github.com/netbox-community/netbox/issues/271) - Fixed primary_ip bug in secrets API
* [#274](https://github.com/netbox-community/netbox/issues/274) - Fixed primary_ip bug in DCIM admin UI
* [#275](https://github.com/netbox-community/netbox/issues/275) - Fixed bug preventing the expansion of an existing aggregate
---
# v1.2.0 (2016-07-12)
## New Features
* [#73](https://github.com/netbox-community/netbox/issues/73) - Added optional persistent banner
* [#93](https://github.com/netbox-community/netbox/issues/73) - Ability to set both IPv4 and IPv6 primary IPs for devices
* [#203](https://github.com/netbox-community/netbox/issues/203) - Introduced support for LDAP
## Bug Fixes
* [#162](https://github.com/netbox-community/netbox/issues/228) - Fixed support for Unicode characters in rack/device/VLAN names
* [#228](https://github.com/netbox-community/netbox/issues/228) - Corrected conditional inclusion of device bay templates
* [#246](https://github.com/netbox-community/netbox/issues/246) - Corrected Docker build instructions
* [#260](https://github.com/netbox-community/netbox/issues/260) - Fixed error on admin UI device type list
* Miscellaneous layout improvements for mobile devices

View File

@@ -0,0 +1,54 @@
# v1.3.2 (2016-07-26)
## Improvements
* [#292](https://github.com/netbox-community/netbox/issues/292) - Added part_number field to DeviceType
* [#363](https://github.com/netbox-community/netbox/issues/363) - Added a description field to the VLAN model
* [#374](https://github.com/netbox-community/netbox/issues/374) - Increased VLAN name length to 64 characters
* Enabled bulk deletion of interfaces from devices
## Bug Fixes
* [#359](https://github.com/netbox-community/netbox/issues/359) - Corrected the DCIM API endpoint for finding related connections
* [#370](https://github.com/netbox-community/netbox/issues/370) - Notify user when secret decryption fails
* [#381](https://github.com/netbox-community/netbox/issues/381) - Fix 'u_consumed' error on rack import
* [#384](https://github.com/netbox-community/netbox/issues/384) - Fixed description field's maximum length on IPAM bulk edit forms
* [#385](https://github.com/netbox-community/netbox/issues/385) - Fixed error when deleting a user with one or more associated UserActions
---
# v1.3.1 (2016-07-21)
## Improvements
* [#258](https://github.com/netbox-community/netbox/issues/258) - Add an API endpoint to list interface connections
* [#303](https://github.com/netbox-community/netbox/issues/303) - Improved numeric ordering of sites, racks, and devices
* [#304](https://github.com/netbox-community/netbox/issues/304) - Display utilization percentage on rack list
* [#327](https://github.com/netbox-community/netbox/issues/327) - Disable rack assignment for installed child devices
## Bug Fixes
* [#331](https://github.com/netbox-community/netbox/issues/331) - Add group field to VLAN bulk edit form
* Miscellaneous improvements to Unicode handling
---
# v1.3.0 (2016-07-18)
## New Features
* [#42](https://github.com/netbox-community/netbox/issues/42) - Allow assignment of VLAN on prefix import
* [#43](https://github.com/netbox-community/netbox/issues/43) - Toggling of IP space uniqueness within a VRF
* [#111](https://github.com/netbox-community/netbox/issues/111) - Introduces VLAN groups
* [#227](https://github.com/netbox-community/netbox/issues/227) - Support for bulk import of child devices
## Bug Fixes
* [#301](https://github.com/netbox-community/netbox/issues/301) - Prevent deletion of DeviceBay when installed device is deleted
* [#306](https://github.com/netbox-community/netbox/issues/306) - Fixed device import to allow an unspecified rack face
* [#307](https://github.com/netbox-community/netbox/issues/307) - Catch `RelatedObjectDoesNotExist` when an invalid device type is defined during device import
* [#308](https://github.com/netbox-community/netbox/issues/308) - Update rack assignment for all child devices when moving a parent device
* [#311](https://github.com/netbox-community/netbox/issues/311) - Fix assignment of primary_ip on IP address import
* [#317](https://github.com/netbox-community/netbox/issues/317) - Rack elevation display fix for device types greater than 42U in height
* [#320](https://github.com/netbox-community/netbox/issues/320) - Disallow import of prefixes with host masks
* [#322](https://github.com/netbox-community/netbox/issues/320) - Corrected VLAN import behavior

View File

@@ -0,0 +1,54 @@
# v1.4.2 (2016-08-06)
## Improvements
* [#167](https://github.com/netbox-community/netbox/issues/167) - Added new interface form factors
* [#253](https://github.com/netbox-community/netbox/issues/253) - Added new interface form factors
* [#434](https://github.com/netbox-community/netbox/issues/434) - Restored admin UI access to user action history (however bulk deletion is disabled)
* [#435](https://github.com/netbox-community/netbox/issues/435) - Added an "add prefix" button to the VLAN view
## Bug Fixes
* [#425](https://github.com/netbox-community/netbox/issues/425) - Ignore leading and trailing periods when generating a slug
* [#427](https://github.com/netbox-community/netbox/issues/427) - Prevent error when duplicate IPs are present in a prefix's IP list
* [#429](https://github.com/netbox-community/netbox/issues/429) - Correct redirection of user when adding a secret to a device
---
# v1.4.1 (2016-08-03)
## Improvements
* [#289](https://github.com/netbox-community/netbox/issues/289) - Annotate available ranges in prefix IP list
* [#412](https://github.com/netbox-community/netbox/issues/412) - Tenant group assignment is no longer mandatory
* [#422](https://github.com/netbox-community/netbox/issues/422) - CSV import now supports double-quoting values which contain commas
## Bug Fixes
* [#395](https://github.com/netbox-community/netbox/issues/395) - Show child prefixes from all VRFs if the parent belongs to the global table
* [#406](https://github.com/netbox-community/netbox/issues/406) - Fixed circuit list rendring when filtering on port speed or commit rate
* [#409](https://github.com/netbox-community/netbox/issues/409) - Filter IPs and prefixes by tenant slug rather than by its PK
* [#411](https://github.com/netbox-community/netbox/issues/411) - Corrected title of secret roles view
* [#419](https://github.com/netbox-community/netbox/issues/419) - Fixed a potential database performance issue when gathering tenant statistics
---
# v1.4.0 (2016-08-01)
## New Features
### Multitenancy ([#16](https://github.com/netbox-community/netbox/issues/16))
NetBox now supports tenants and tenant groups. Sites, racks, devices, VRFs, prefixes, IP addresses, VLANs, and circuits can be assigned to tenants to track the allocation of these resources among customers or internal departments. If a prefix or IP address does not have a tenant assigned, it will fall back to the tenant assigned to its parent VRF (where applicable).
## Improvements
* [#176](https://github.com/netbox-community/netbox/issues/176) - Introduced seed data for new installs
* [#358](https://github.com/netbox-community/netbox/issues/358) - Improved search for all objects
* [#394](https://github.com/netbox-community/netbox/issues/394) - Improved VRF selection during bulk editing of prefixes and IP addresses
* Miscellaneous cosmetic improvements to the UI
## Bug Fixes
* [#392](https://github.com/netbox-community/netbox/issues/392) - Don't include child devices in non-racked devices table
* [#397](https://github.com/netbox-community/netbox/issues/397) - Only include child IPs which belong to the same VRF as the parent prefix

View File

@@ -0,0 +1,50 @@
# v1.5.2 (2016-08-16)
## Bug Fixes
* [#460](https://github.com/netbox-community/netbox/issues/460) - Corrected ordering of IP addresses with differing prefix lengths
* [#463](https://github.com/netbox-community/netbox/issues/463) - Prevent pre-population of livesearch field with '---------'
* [#467](https://github.com/netbox-community/netbox/issues/467) - Include prefixes and IPs which inherit tenancy from their VRF in tenant stats
* [#468](https://github.com/netbox-community/netbox/issues/468) - Don't allow connected interfaces to be changed to the "virtual" form factor
* [#469](https://github.com/netbox-community/netbox/issues/469) - Added missing import buttons to list views
* [#472](https://github.com/netbox-community/netbox/issues/472) - Hide the connection button for interfaces which have a circuit terminated to them
---
# v1.5.1 (2016-08-11)
## Improvements
* [#421](https://github.com/netbox-community/netbox/issues/421) - Added an asset tag field to devices
* [#456](https://github.com/netbox-community/netbox/issues/456) - Added IP search box to home page
* Colorized rack and device roles
## Bug Fixes
* [#454](https://github.com/netbox-community/netbox/issues/454) - Corrected error on rack export
* [#457](https://github.com/netbox-community/netbox/issues/457) - Added role field to rack edit form
---
# v1.5.0 (2016-08-10)
## New Features
### Rack Enhancements ([#180](https://github.com/netbox-community/netbox/issues/180), [#241](https://github.com/netbox-community/netbox/issues/241))
Like devices, racks can now be assigned to functional roles. This allows users to group racks by designated function as well as by physical location (rack groups). Additionally, rack can now have a defined rail-to-rail width (19 or 23 inches) and a type (two-post-rack, cabinet, etc.).
## Improvements
* [#149](https://github.com/netbox-community/netbox/issues/149) - Added discrete upstream speed field for circuits
* [#157](https://github.com/netbox-community/netbox/issues/157) - Added manufacturer field for device modules
* We have a logo!
* Upgraded to Django 1.10
## Bug Fixes
* [#433](https://github.com/netbox-community/netbox/issues/433) - Corrected form validation when editing child devices
* [#442](https://github.com/netbox-community/netbox/issues/442) - Corrected child device import instructions
* [#443](https://github.com/netbox-community/netbox/issues/443) - Correctly display and initialize VRF for creation of new IP addresses
* [#444](https://github.com/netbox-community/netbox/issues/444) - Corrected prefix model validation
* [#445](https://github.com/netbox-community/netbox/issues/445) - Limit rack height to between 1U and 100U (inclusive)

View File

@@ -0,0 +1,85 @@
# v1.6.3 (2016-10-19)
## Improvements
* [#353](https://github.com/netbox-community/netbox/issues/353) - Bulk editing of device and device type interfaces
* [#527](https://github.com/netbox-community/netbox/issues/527) - Support for nullification of fields when bulk editing
* [#592](https://github.com/netbox-community/netbox/issues/592) - Allow space-delimited lists of ALLOWED_HOSTS in Docker
* [#608](https://github.com/netbox-community/netbox/issues/608) - Added "select all" button for device and device type components
## Bug Fixes
* [#602](https://github.com/netbox-community/netbox/issues/602) - Correct display of custom integer fields with value of 0 or 1
* [#604](https://github.com/netbox-community/netbox/issues/604) - Correct display of unnamed devices in form selection fields
* [#611](https://github.com/netbox-community/netbox/issues/611) - Power/console/interface connection import: status field should be case-insensitive
* [#615](https://github.com/netbox-community/netbox/issues/615) - Account for BASE_PATH in static URLs and during login
* [#616](https://github.com/netbox-community/netbox/issues/616) - Correct display of custom URL fields
---
# v1.6.2-r1 (2016-10-04)
## Improvements
* [#212](https://github.com/netbox-community/netbox/issues/212) - Introduced the `BASE_PATH` configuration setting to allow running NetBox in a URL subdirectory
* [#345](https://github.com/netbox-community/netbox/issues/345) - Bulk edit: allow user to select all objects on page or all matching query
* [#475](https://github.com/netbox-community/netbox/issues/475) - Display "add" buttons at top and bottom of all device/device type panels
* [#480](https://github.com/netbox-community/netbox/issues/480) - Improved layout on mobile devices
* [#481](https://github.com/netbox-community/netbox/issues/481) - Require interface creation before trying to assign an IP to a device
* [#575](https://github.com/netbox-community/netbox/issues/575) - Allow all valid URL schemes in custom fields
* [#579](https://github.com/netbox-community/netbox/issues/579) - Add a description field to export templates
## Bug Fixes
* [#466](https://github.com/netbox-community/netbox/issues/466) - Validate available free space for all instances when increasing the U height of a device type
* [#571](https://github.com/netbox-community/netbox/issues/571) - Correct rack group filter on device list
* [#576](https://github.com/netbox-community/netbox/issues/576) - Delete all relevant CustomFieldValues when deleting a CustomFieldChoice
* [#581](https://github.com/netbox-community/netbox/issues/581) - Correct initialization of custom boolean and select fields
* [#591](https://github.com/netbox-community/netbox/issues/591) - Correct display of component creation buttons in device type view
---
# v1.6.1-r1 (2016-09-21)
## Improvements
* [#415](https://github.com/netbox-community/netbox/issues/415) - Add an expand/collapse toggle button to the prefix list
* [#552](https://github.com/netbox-community/netbox/issues/552) - Allow filtering on custom select fields by "none"
* [#561](https://github.com/netbox-community/netbox/issues/561) - Make custom fields accessible from within export templates
## Bug Fixes
* [#493](https://github.com/netbox-community/netbox/issues/493) - CSV import support for UTF-8
* [#531](https://github.com/netbox-community/netbox/issues/531) - Order prefix list by VRF assignment
* [#542](https://github.com/netbox-community/netbox/issues/542) - Add LDAP support in Docker
* [#557](https://github.com/netbox-community/netbox/issues/557) - Add 'global' choice to VRF filter for prefixes and IP addresses
* [#558](https://github.com/netbox-community/netbox/issues/558) - Update slug field when name is populated without a key press
* [#562](https://github.com/netbox-community/netbox/issues/562) - Fixed bulk interface creation
* [#564](https://github.com/netbox-community/netbox/issues/564) - Display custom fields for all applicable objects
---
# v1.6.0 (2016-09-13)
## New Features
### Custom Fields ([#129](https://github.com/netbox-community/netbox/issues/129))
Users can now create custom fields to associate arbitrary data with core NetBox objects. For example, you might want to add a geolocation tag to IP prefixes, or a ticket number to each device. Text, integer, boolean, date, URL, and selection fields are supported.
## Improvements
* [#489](https://github.com/netbox-community/netbox/issues/489) - Docker file now builds from a `python:2.7-wheezy` base instead of `ubuntu:14.04`
* [#540](https://github.com/netbox-community/netbox/issues/540) - Add links for VLAN roles under VLAN navigation menu
* Added new interface form factors
* Added address family filters to aggregate and prefix lists
## Bug Fixes
* [#476](https://github.com/netbox-community/netbox/issues/476) - Corrected rack import instructions
* [#484](https://github.com/netbox-community/netbox/issues/484) - Allow bulk deletion of >1K objects
* [#486](https://github.com/netbox-community/netbox/issues/486) - Prompt for secret key only if updating a secret's value
* [#490](https://github.com/netbox-community/netbox/issues/490) - Corrected display of circuit commit rate
* [#495](https://github.com/netbox-community/netbox/issues/495) - Include tenant in prefix and IP CSV export
* [#507](https://github.com/netbox-community/netbox/issues/507) - Corrected rendering of nav menu on screens narrower than 1200px
* [#515](https://github.com/netbox-community/netbox/issues/515) - Clarified instructions for the "face" field when importing devices
* [#522](https://github.com/netbox-community/netbox/issues/522) - Remove obsolete check for staff status when bulk deleting objects
* [#544](https://github.com/netbox-community/netbox/issues/544) - Strip CRLF-style line terminators from rendered export templates

View File

@@ -0,0 +1,75 @@
# v1.7.3 (2016-12-08)
## Bug Fixes
* [#724](https://github.com/netbox-community/netbox/issues/724) - Exempt API views from LoginRequiredMiddleware to enable basic HTTP authentication when LOGIN_REQUIRED is true
* [#729](https://github.com/netbox-community/netbox/issues/729) - Corrected cancellation links when editing secondary objects
* [#732](https://github.com/netbox-community/netbox/issues/732) - Allow custom select field values to be deselected if the field is not required
* [#733](https://github.com/netbox-community/netbox/issues/733) - Fixed MAC address filter on device list
* [#734](https://github.com/netbox-community/netbox/issues/734) - Corrected display of device type when editing a device
---
# v1.7.2-r1 (2016-12-06)
## Improvements
* [#663](https://github.com/netbox-community/netbox/issues/663) - Added MAC address search field to device list
* [#672](https://github.com/netbox-community/netbox/issues/672) - Increased the selection of available colors for rack and device roles
* [#695](https://github.com/netbox-community/netbox/issues/695) - Added is_private field to RIR
## Bug Fixes
* [#677](https://github.com/netbox-community/netbox/issues/677) - Fix setuptools installation error on Debian 8.6
* [#696](https://github.com/netbox-community/netbox/issues/696) - Corrected link to VRF in prefix and IP address breadcrumbs
* [#702](https://github.com/netbox-community/netbox/issues/702) - Improved Unicode support for custom fields
* [#712](https://github.com/netbox-community/netbox/issues/712) - Corrected export of tenants which are not assigned to a group
* [#713](https://github.com/netbox-community/netbox/issues/713) - Include a label for the comments field when editing circuits, providers, or racks in bulk
* [#718](https://github.com/netbox-community/netbox/issues/718) - Restore is_primary field on IP assignment form
* [#723](https://github.com/netbox-community/netbox/issues/723) - API documentation is now accessible when using BASE_PATH
* [#727](https://github.com/netbox-community/netbox/issues/727) - Corrected error in rack elevation display (v1.7.2)
---
# v1.7.1 (2016-11-15)
## Improvements
* [#667](https://github.com/netbox-community/netbox/issues/667) - Added prefix utilization statistics to the RIR list view
* [#685](https://github.com/netbox-community/netbox/issues/685) - When assigning an IP to a device, automatically select the interface if only one exists
## Bug Fixes
* [#674](https://github.com/netbox-community/netbox/issues/674) - Fix assignment of status to imported IP addresses
* [#676](https://github.com/netbox-community/netbox/issues/676) - Server error when bulk editing device types
* [#678](https://github.com/netbox-community/netbox/issues/678) - Server error on device import specifying an invalid device type
* [#691](https://github.com/netbox-community/netbox/issues/691) - Allow the assignment of power ports to PDUs
* [#692](https://github.com/netbox-community/netbox/issues/692) - Form errors are not displayed on checkbox fields
---
# v1.7.0 (2016-11-03)
## New Features
### IP address statuses ([#87](https://github.com/netbox-community/netbox/issues/87))
An IP address can now be designated as active, reserved, or DHCP. The DHCP status implies that the IP address is part of a DHCP pool and may or may not be assigned to a DHCP client.
### Top-to-bottom rack numbering ([#191](https://github.com/netbox-community/netbox/issues/191))
Racks can now be set to have descending rack units, with U1 at the top of the rack. When adding a device to a rack with descending units, be sure to position it in the **lowest-numbered** unit which it occupies (this will be physically the topmost unit).
## Improvements
* [#211](https://github.com/netbox-community/netbox/issues/211) - Allow device assignment and removal from IP address view
* [#630](https://github.com/netbox-community/netbox/issues/630) - Added a custom 404 page
* [#652](https://github.com/netbox-community/netbox/issues/652) - Use password input controls when editing secrets
* [#654](https://github.com/netbox-community/netbox/issues/654) - Added Cisco FlexStack and FlexStack Plus form factors
* [#661](https://github.com/netbox-community/netbox/issues/661) - Display relevant IP addressing when viewing a circuit
## Bug Fixes
* [#632](https://github.com/netbox-community/netbox/issues/632) - Use semicolons instead of commas to separate regexes in topology maps
* [#647](https://github.com/netbox-community/netbox/issues/647) - Extend form used when assigning an IP to a device
* [#657](https://github.com/netbox-community/netbox/issues/657) - Unicode error when adding device modules
* [#660](https://github.com/netbox-community/netbox/issues/660) - Corrected calculation of utilized space in rack list
* [#664](https://github.com/netbox-community/netbox/issues/664) - Fixed bulk creation of interfaces across multiple devices

View File

@@ -0,0 +1,106 @@
# v1.8.4 (2017-02-03)
## Improvements
* [#856](https://github.com/netbox-community/netbox/issues/856) - Strip whitespace from fields during CSV import
## Bug Fixes
* [#851](https://github.com/netbox-community/netbox/issues/851) - Resolve encoding issues during import/export (Python 3)
* [#854](https://github.com/netbox-community/netbox/issues/854) - Correct processing of get_return_url() in ObjectDeleteView
* [#859](https://github.com/netbox-community/netbox/issues/859) - Fix Javascript for connection status toggle button on device view
* [#861](https://github.com/netbox-community/netbox/issues/861) - Avoid overwriting device primary IP assignment from alternate family during bulk import of IP addresses
* [#865](https://github.com/netbox-community/netbox/issues/865) - Fix server error when attempting to delete a protected object parent (Python 3)
---
# v1.8.3 (2017-01-26)
## Improvements
* [#782](https://github.com/netbox-community/netbox/issues/782) - Allow filtering devices list by manufacturer
* [#820](https://github.com/netbox-community/netbox/issues/820) - Add VLAN column to parent prefixes table on IP address view
* [#821](https://github.com/netbox-community/netbox/issues/821) - Support for comma separation in bulk IP/interface creation
* [#827](https://github.com/netbox-community/netbox/issues/827) - **Introduced support for Python 3**
* [#836](https://github.com/netbox-community/netbox/issues/836) - Add "deprecated" status for IP addresses
* [#841](https://github.com/netbox-community/netbox/issues/841) - Merged search and filter forms on all object lists
## Bug Fixes
* [#816](https://github.com/netbox-community/netbox/issues/816) - Redirect back to parent prefix view after deleting child prefixes termination
* [#817](https://github.com/netbox-community/netbox/issues/817) - Update last_updated time of a circuit when editing a child termination
* [#830](https://github.com/netbox-community/netbox/issues/830) - Redirect user to device view after editing a device component
* [#840](https://github.com/netbox-community/netbox/issues/840) - Correct API path resolution for secrets when BASE_PATH is configured
* [#844](https://github.com/netbox-community/netbox/issues/844) - Apply order_naturally() to API interfaces list
* [#845](https://github.com/netbox-community/netbox/issues/845) - Fix missing edit/delete buttons on object tables for non-superusers
---
# v1.8.2 (2017-01-18)
## Improvements
* [#284](https://github.com/netbox-community/netbox/issues/284) - Enabled toggling of interface display order per device type
* [#760](https://github.com/netbox-community/netbox/issues/760) - Redirect user back to device view after deleting an assigned IP address
* [#783](https://github.com/netbox-community/netbox/issues/783) - Add a description field to the Circuit model
* [#797](https://github.com/netbox-community/netbox/issues/797) - Add description column to VLANs table
* [#803](https://github.com/netbox-community/netbox/issues/803) - Clarify that no child objects are deleted when deleting a prefix
* [#805](https://github.com/netbox-community/netbox/issues/805) - Linkify site column in device table
## Bug Fixes
* [#776](https://github.com/netbox-community/netbox/issues/776) - Prevent circuits from appearing twice while searching
* [#778](https://github.com/netbox-community/netbox/issues/778) - Corrected an issue preventing multiple interfaces with the same position ID from appearing in a device's interface list
* [#785](https://github.com/netbox-community/netbox/issues/785) - Trigger validation error when importing a prefix assigned to a nonexistent VLAN
* [#802](https://github.com/netbox-community/netbox/issues/802) - Fixed enforcement of ENFORCE_GLOBAL_UNIQUE for prefixes
* [#807](https://github.com/netbox-community/netbox/issues/807) - Redirect user back to form when adding IP addresses in bulk and "create and add another" is clicked
* [#810](https://github.com/netbox-community/netbox/issues/810) - Suppress unique IP validation on invalid IP addresses and prefixes
---
# v1.8.1 (2017-01-04)
## Improvements
* [#771](https://github.com/netbox-community/netbox/issues/771) - Don't automatically redirect user when only one object is returned in a list
## Bug Fixes
* [#764](https://github.com/netbox-community/netbox/issues/764) - Encapsulate in double quotes values containing commas when exporting to CSV
* [#767](https://github.com/netbox-community/netbox/issues/767) - Fixes xconnect_id error when searching for circuits
* [#769](https://github.com/netbox-community/netbox/issues/769) - Show default value for boolean custom fields
* [#772](https://github.com/netbox-community/netbox/issues/772) - Fixes TypeError in API RackUnitListView when no device is excluded
---
# v1.8.0 (2017-01-03)
## New Features
### Point-to-Point Circuits ([#49](https://github.com/netbox-community/netbox/issues/49))
Until now, NetBox has supported tracking only one end of a data circuit. This is fine for Internet connections where you don't care (or know) much about the provider side of the circuit, but many users need the ability to track inter-site circuits as well. This release expands circuit modeling so that each circuit can have an A and/or Z side. Each endpoint must be terminated to a site, and may optionally be terminated to a specific device and interface within that site.
### L4 Services ([#539](https://github.com/netbox-community/netbox/issues/539))
Our first major community contribution introduces the ability to track discrete TCP and UDP services associated with a device (for example, SSH or HTTP). Each service can optionally be assigned to one or more specific IP addresses belonging to the device. Thanks to [@if-fi](https://github.com/if-fi) for the addition!
## Improvements
* [#122](https://github.com/netbox-community/netbox/issues/122) - Added comments field to device types
* [#181](https://github.com/netbox-community/netbox/issues/181) - Implemented support for bulk IP address creation
* [#613](https://github.com/netbox-community/netbox/issues/613) - Added prefixes column to VLAN list; added VLAN column to prefix list
* [#716](https://github.com/netbox-community/netbox/issues/716) - Add ASN field to site bulk edit form
* [#722](https://github.com/netbox-community/netbox/issues/722) - Enabled custom fields for device types
* [#743](https://github.com/netbox-community/netbox/issues/743) - Enabled bulk creation of all device components
* [#756](https://github.com/netbox-community/netbox/issues/756) - Added contact details to site model
## Bug Fixes
* [#563](https://github.com/netbox-community/netbox/issues/563) - Allow a device to be flipped from one rack face to the other without moving it
* [#658](https://github.com/netbox-community/netbox/issues/658) - Enabled conditional treatment of network/broadcast IPs for a prefix by defining it as a pool
* [#741](https://github.com/netbox-community/netbox/issues/741) - Hide "select all" button for users without edit permissions
* [#744](https://github.com/netbox-community/netbox/issues/744) - Fixed export of sites without an AS number
* [#747](https://github.com/netbox-community/netbox/issues/747) - Fixed natural_order_by integer cast error on large numbers
* [#751](https://github.com/netbox-community/netbox/issues/751) - Fixed python-cryptography installation issue on Debian
* [#763](https://github.com/netbox-community/netbox/issues/763) - Added missing fields to CSV exports for racks and prefixes

View File

@@ -0,0 +1,136 @@
# v1.9.6 (2017-04-21)
## Improvements
* [#878](https://github.com/netbox-community/netbox/issues/878) - Merged IP addresses with interfaces list on device view
* [#1001](https://github.com/netbox-community/netbox/issues/1001) - Interface assignment can be modified when editing an IP address
* [#1084](https://github.com/netbox-community/netbox/issues/1084) - Include custom fields when creating IP addresses in bulk
## Bug Fixes
* [#1057](https://github.com/netbox-community/netbox/issues/1057) - Corrected VLAN validation during prefix import
* [#1061](https://github.com/netbox-community/netbox/issues/1061) - Fixed potential for script injection via create/edit/delete messages
* [#1070](https://github.com/netbox-community/netbox/issues/1070) - Corrected installation instructions for Python3 on CentOS/RHEL
* [#1071](https://github.com/netbox-community/netbox/issues/1071) - Protect assigned circuit termination when an interface is deleted
* [#1072](https://github.com/netbox-community/netbox/issues/1072) - Order LAG interfaces naturally on bulk interface edit form
* [#1074](https://github.com/netbox-community/netbox/issues/1074) - Require ncclient 0.5.3 (Python 3 fix)
* [#1090](https://github.com/netbox-community/netbox/issues/1090) - Improved installation documentation for Python 3
* [#1092](https://github.com/netbox-community/netbox/issues/1092) - Increase randomness in SECRET_KEY generation tool
---
# v1.9.5 (2017-04-06)
## Improvements
* [#1052](https://github.com/netbox-community/netbox/issues/1052) - Added rack reservation list and bulk delete views
## Bug Fixes
* [#1038](https://github.com/netbox-community/netbox/issues/1038) - Suppress upgrading to Django 1.11 (will be supported in v2.0)
* [#1037](https://github.com/netbox-community/netbox/issues/1037) - Fixed error on VLAN import with duplicate VLAN group names
* [#1047](https://github.com/netbox-community/netbox/issues/1047) - Correct ordering of numbered subinterfaces
* [#1051](https://github.com/netbox-community/netbox/issues/1051) - Upgraded django-rest-swagger
---
# v1.9.4-r1 (2017-04-04)
## Improvements
* [#362](https://github.com/netbox-community/netbox/issues/362) - Added per_page query parameter to control pagination page length
## Bug Fixes
* [#991](https://github.com/netbox-community/netbox/issues/991) - Correct server error on "create and connect another" interface connection
* [#1022](https://github.com/netbox-community/netbox/issues/1022) - Record user actions when creating IP addresses in bulk
* [#1027](https://github.com/netbox-community/netbox/issues/1027) - Fixed nav menu highlighting when BASE_PATH is set
* [#1034](https://github.com/netbox-community/netbox/issues/1034) - Added migration missing from v1.9.4 release
---
# v1.9.3 (2017-03-23)
## Improvements
* [#972](https://github.com/netbox-community/netbox/issues/972) - Add ability to filter connections list by device name
* [#974](https://github.com/netbox-community/netbox/issues/974) - Added MAC address filter to API interfaces list
* [#978](https://github.com/netbox-community/netbox/issues/978) - Allow filtering device types by function and subdevice role
* [#981](https://github.com/netbox-community/netbox/issues/981) - Allow filtering primary objects by a given set of IDs
* [#983](https://github.com/netbox-community/netbox/issues/983) - Include peer device names when listing circuits in device view
## Bug Fixes
* [#967](https://github.com/netbox-community/netbox/issues/967) - Fix error when assigning a new interface to a LAG
---
# v1.9.2 (2017-03-14)
## Bug Fixes
* [#950](https://github.com/netbox-community/netbox/issues/950) - Fix site_id error on child device import
* [#956](https://github.com/netbox-community/netbox/issues/956) - Correct bug affecting unnamed rackless devices
* [#957](https://github.com/netbox-community/netbox/issues/957) - Correct device site filter count to include unracked devices
* [#963](https://github.com/netbox-community/netbox/issues/963) - Fix bug in IPv6 address range expansion
* [#964](https://github.com/netbox-community/netbox/issues/964) - Fix bug when bulk editing/deleting filtered set of objects
---
# v1.9.1 (2017-03-08)
## Improvements
* [#945](https://github.com/netbox-community/netbox/issues/945) - Display the current user in the navigation menu
* [#946](https://github.com/netbox-community/netbox/issues/946) - Disregard mask length when filtering IP addresses by a parent prefix
## Bug Fixes
* [#941](https://github.com/netbox-community/netbox/issues/941) - Corrected old references to rack.site on Device
* [#943](https://github.com/netbox-community/netbox/issues/943) - Child prefixes missing on Python 3
* [#944](https://github.com/netbox-community/netbox/issues/944) - Corrected console and power connection form behavior
* [#948](https://github.com/netbox-community/netbox/issues/948) - Region name should be hyperlinked to site list
---
# v1.9.0-r1 (2017-03-03)
## New Features
### Rack Reservations ([#36](https://github.com/netbox-community/netbox/issues/36))
Users can now reserve an arbitrary number of units within a rack, adding a comment noting their intentions. Reservations do not interfere with installed devices: It is possible to reserve a unit for future use even if it is currently occupied by a device.
### Interface Groups ([#105](https://github.com/netbox-community/netbox/issues/105))
A new Link Aggregation Group (LAG) virtual form factor has been added. Physical interfaces can be assigned to a parent LAG interface to represent a port-channel or similar logical bundling of links.
### Regions ([#164](https://github.com/netbox-community/netbox/issues/164))
A new region model has been introduced to allow for the geographic organization of sites. Regions can be nested recursively to form a hierarchy.
### Rackless Devices ([#198](https://github.com/netbox-community/netbox/issues/198))
Previous releases required each device to be assigned to a particular rack within a site. This requirement has been relaxed so that devices must only be assigned to a site, and may optionally be assigned to a rack.
### Global VLANs ([#235](https://github.com/netbox-community/netbox/issues/235))
Assignment of VLANs and VLAN groups to sites is now optional, allowing for the representation of a VLAN spanning multiple sites.
## Improvements
* [#862](https://github.com/netbox-community/netbox/issues/862) - Show both IPv6 and IPv4 primary IPs in device list
* [#894](https://github.com/netbox-community/netbox/issues/894) - Expand device name max length to 64 characters
* [#898](https://github.com/netbox-community/netbox/issues/898) - Expanded circuits list in provider view rack face
* [#901](https://github.com/netbox-community/netbox/issues/901) - Support for filtering prefixes and IP addresses by mask length
## Bug Fixes
* [#872](https://github.com/netbox-community/netbox/issues/872) - Fixed TypeError on bulk IP address creation (Python 3)
* [#884](https://github.com/netbox-community/netbox/issues/884) - Preserve selected rack unit when changing a device's rack face
* [#892](https://github.com/netbox-community/netbox/issues/892) - Restored missing edit/delete buttons when viewing child prefixes and IP addresses from a parent object
* [#897](https://github.com/netbox-community/netbox/issues/897) - Fixed power connections CSV export
* [#903](https://github.com/netbox-community/netbox/issues/903) - Only alert on missing critical connections if present in the parent device type
* [#935](https://github.com/netbox-community/netbox/issues/935) - Fix form validation error when connecting an interface using live search
* [#937](https://github.com/netbox-community/netbox/issues/937) - Region assignment should be optional when creating a site
* [#938](https://github.com/netbox-community/netbox/issues/938) - Provider view yields an error if one or more circuits is assigned to a tenant

View File

@@ -0,0 +1,230 @@
# v2.0.10 (2017-07-14)
## Bug Fixes
* [#1312](https://github.com/netbox-community/netbox/issues/1312) - Catch error when attempting to activate a user key with an invalid private key
* [#1333](https://github.com/netbox-community/netbox/issues/1333) - Corrected label on is_console_server field of DeviceType bulk edit form
* [#1338](https://github.com/netbox-community/netbox/issues/1338) - Allow importing prefixes with "container" status
* [#1339](https://github.com/netbox-community/netbox/issues/1339) - Fixed disappearing checkbox column under django-tables2 v1.7+
* [#1342](https://github.com/netbox-community/netbox/issues/1342) - Allow designation of users and groups when creating/editing a secret role
---
# v2.0.9 (2017-07-10)
## Bug Fixes
* [#1319](https://github.com/netbox-community/netbox/issues/1319) - Fixed server error when attempting to create console/power connections
* [#1325](https://github.com/netbox-community/netbox/issues/1325) - Retain interface attachment when editing a circuit termination
---
# v2.0.8 (2017-07-05)
## Enhancements
* [#1298](https://github.com/netbox-community/netbox/issues/1298) - Calculate prefix utilization based on its status (container or non-container)
* [#1303](https://github.com/netbox-community/netbox/issues/1303) - Highlight installed interface connections in green on device view
* [#1315](https://github.com/netbox-community/netbox/issues/1315) - Enforce lowercase file extensions for image attachments
## Bug Fixes
* [#1279](https://github.com/netbox-community/netbox/issues/1279) - Fix primary_ip assignment during IP address import
* [#1281](https://github.com/netbox-community/netbox/issues/1281) - Show LLDP neighbors tab on device view only if necessary conditions are met
* [#1282](https://github.com/netbox-community/netbox/issues/1282) - Fixed tooltips on "mark connected/planned" toggle buttons for device connections
* [#1288](https://github.com/netbox-community/netbox/issues/1288) - Corrected permission name for deleting image attachments
* [#1289](https://github.com/netbox-community/netbox/issues/1289) - Retain inside NAT assignment when editing an IP address
* [#1297](https://github.com/netbox-community/netbox/issues/1297) - Allow passing custom field choice selection PKs to API as string-quoted integers
* [#1299](https://github.com/netbox-community/netbox/issues/1299) - Corrected permission name for adding services to devices
---
# v2.0.7 (2017-06-15)
## Enhancements
* [#626](https://github.com/netbox-community/netbox/issues/626) - Added bulk disconnect function for console/power/interface connections on device view
## Bug Fixes
* [#1238](https://github.com/netbox-community/netbox/issues/1238) - Fix error when editing an IP with a NAT assignment which has no assigned device
* [#1263](https://github.com/netbox-community/netbox/issues/1263) - Differentiate add and edit permissions for objects
* [#1265](https://github.com/netbox-community/netbox/issues/1265) - Fix console/power/interface connection validation when selecting a device via live search
* [#1266](https://github.com/netbox-community/netbox/issues/1266) - Prevent terminating a circuit to an already-connected interface
* [#1268](https://github.com/netbox-community/netbox/issues/1268) - Fix CSV import error under Python 3
* [#1273](https://github.com/netbox-community/netbox/issues/1273) - Corrected status choices in IP address import form
* [#1274](https://github.com/netbox-community/netbox/issues/1274) - Exclude unterminated circuits from topology maps
* [#1275](https://github.com/netbox-community/netbox/issues/1275) - Raise validation error on prefix import when multiple VLANs are found
---
# v2.0.6 (2017-06-12)
## Enhancements
* [#40](https://github.com/netbox-community/netbox/issues/40) - Added IP utilization graph to prefix list
* [#704](https://github.com/netbox-community/netbox/issues/704) - Allow filtering VLANs by group when editing prefixes
* [#913](https://github.com/netbox-community/netbox/issues/913) - Added headers to object CSV exports
* [#990](https://github.com/netbox-community/netbox/issues/990) - Enable logging configuration in configuration.py
* [#1180](https://github.com/netbox-community/netbox/issues/1180) - Simplified the process of finding related devices when viewing a device
## Bug Fixes
* [#1253](https://github.com/netbox-community/netbox/issues/1253) - Improved `upgrade.sh` to allow forcing Python2
---
# v2.0.5 (2017-06-08)
## Notes
The maximum number of objects an API consumer can request has been set to 1000 (e.g. `?limit=1000`). This limit can be modified by defining `MAX_PAGE_SIZE` in confgiuration.py. (To remove this limit, set `MAX_PAGE_SIZE=0`.)
## Enhancements
* [#655](https://github.com/netbox-community/netbox/issues/655) - Implemented header-based CSV import of objects
* [#1190](https://github.com/netbox-community/netbox/issues/1190) - Allow partial string matching when searching on custom fields
* [#1237](https://github.com/netbox-community/netbox/issues/1237) - Enabled setting limit=0 to disable pagination in API requests; added `MAX_PAGE_SIZE` configuration setting
## Bug Fixes
* [#837](https://github.com/netbox-community/netbox/issues/837) - Enforce uniqueness where applicable during bulk import of IP addresses
* [#1226](https://github.com/netbox-community/netbox/issues/1226) - Improved validation for custom field values submitted via the API
* [#1232](https://github.com/netbox-community/netbox/issues/1232) - Improved rack space validation on bulk import of devices (see #655)
* [#1235](https://github.com/netbox-community/netbox/issues/1235) - Fix permission name for adding/editing inventory items
* [#1236](https://github.com/netbox-community/netbox/issues/1236) - Truncate rack names in elevations list; add facility ID
* [#1239](https://github.com/netbox-community/netbox/issues/1239) - Fix server error when creating VLANGroup via API
* [#1243](https://github.com/netbox-community/netbox/issues/1243) - Catch ValueError in IP-based object filters
* [#1244](https://github.com/netbox-community/netbox/issues/1244) - Corrected "device" secrets filter to accept a device name
---
# v2.0.4 (2017-05-25)
## Bug Fixes
* [#1206](https://github.com/netbox-community/netbox/issues/1206) - Fix redirection in admin UI after activating secret keys when BASE_PATH is set
* [#1207](https://github.com/netbox-community/netbox/issues/1207) - Include nested LAG serializer when showing interface connections (API)
* [#1210](https://github.com/netbox-community/netbox/issues/1210) - Fix TemplateDoesNotExist errors on browsable API views
* [#1212](https://github.com/netbox-community/netbox/issues/1212) - Allow assigning new VLANs to global VLAN groups
* [#1213](https://github.com/netbox-community/netbox/issues/1213) - Corrected table header ordering links on object list views
* [#1214](https://github.com/netbox-community/netbox/issues/1214) - Add status to list of required fields on child device import form
* [#1219](https://github.com/netbox-community/netbox/issues/1219) - Fix image attachment URLs when BASE_PATH is set
* [#1220](https://github.com/netbox-community/netbox/issues/1220) - Suppressed innocuous warning about untracked migrations under Python 3
* [#1229](https://github.com/netbox-community/netbox/issues/1229) - Fix validation error on forms where API search is used
---
# v2.0.3 (2017-05-18)
## Enhancements
* [#1196](https://github.com/netbox-community/netbox/issues/1196) - Added a lag_id filter to the API interfaces view
* [#1198](https://github.com/netbox-community/netbox/issues/1198) - Allow filtering unracked devices on device list
## Bug Fixes
* [#1157](https://github.com/netbox-community/netbox/issues/1157) - Hide nav menu search bar on small displays
* [#1186](https://github.com/netbox-community/netbox/issues/1186) - Corrected VLAN edit form so that site assignment is not required
* [#1187](https://github.com/netbox-community/netbox/issues/1187) - Fixed table pagination by introducing a custom table template
* [#1188](https://github.com/netbox-community/netbox/issues/1188) - Serialize interface LAG as nested objected (API)
* [#1189](https://github.com/netbox-community/netbox/issues/1189) - Enforce consistent ordering of objects returned by a global search
* [#1191](https://github.com/netbox-community/netbox/issues/1191) - Bulk selection of IPs under a prefix incorrect when "select all" is used
* [#1195](https://github.com/netbox-community/netbox/issues/1195) - Unable to create an interface connection when searching for peer device
* [#1197](https://github.com/netbox-community/netbox/issues/1197) - Fixed status assignment during bulk import of devices, prefixes, IPs, and VLANs
* [#1199](https://github.com/netbox-community/netbox/issues/1199) - Bulk import of secrets does not prompt user to generate a session key
* [#1200](https://github.com/netbox-community/netbox/issues/1200) - Form validation error when connecting power ports to power outlets
---
# v2.0.2 (2017-05-15)
## Enhancements
* [#1122](https://github.com/netbox-community/netbox/issues/1122) - Include NAT inside IPs in IP address list
* [#1137](https://github.com/netbox-community/netbox/issues/1137) - Allow filtering devices list by rack
* [#1170](https://github.com/netbox-community/netbox/issues/1170) - Include A and Z sites for circuits in global search results
* [#1172](https://github.com/netbox-community/netbox/issues/1172) - Linkify racks in side-by-side elevations view
* [#1177](https://github.com/netbox-community/netbox/issues/1177) - Render planned connections as dashed lines on topology maps
* [#1179](https://github.com/netbox-community/netbox/issues/1179) - Adjust topology map text color based on node background
* On all object edit forms, allow filtering the tenant list by tenant group
## Bug Fixes
* [#1158](https://github.com/netbox-community/netbox/issues/1158) - Exception thrown when creating a device component with an invalid name
* [#1159](https://github.com/netbox-community/netbox/issues/1159) - Only superusers can see "edit IP" buttons on the device interfaces list
* [#1160](https://github.com/netbox-community/netbox/issues/1160) - Linkify secrets and tenants in global search results
* [#1161](https://github.com/netbox-community/netbox/issues/1161) - Fix "add another" behavior when creating an API token
* [#1166](https://github.com/netbox-community/netbox/issues/1166) - Fixed bulk IP address creation when assigning tenants
* [#1168](https://github.com/netbox-community/netbox/issues/1168) - Total count of objects missing from list view paginator
* [#1171](https://github.com/netbox-community/netbox/issues/1171) - Allow removing site assignment when bulk editing VLANs
* [#1173](https://github.com/netbox-community/netbox/issues/1173) - Tweak interface manager to fall back to naive ordering
---
# v2.0.1 (2017-05-10)
## Bug Fixes
* [#1149](https://github.com/netbox-community/netbox/issues/1149) - Port list does not populate when creating a console or power connection
* [#1150](https://github.com/netbox-community/netbox/issues/1150) - Error when uploading image attachments with Unicode names under Python 2
* [#1151](https://github.com/netbox-community/netbox/issues/1151) - Server error: name 'escape' is not defined
* [#1152](https://github.com/netbox-community/netbox/issues/1152) - Unable to edit user keys
* [#1153](https://github.com/netbox-community/netbox/issues/1153) - UnicodeEncodeError when searching for non-ASCII characters on Python 2
---
# v2.0.0 (2017-05-09)
## New Features
### API 2.0 ([#113](https://github.com/netbox-community/netbox/issues/113))
The NetBox API has been completely rewritten and now features full read/write ability.
### Image Attachments ([#152](https://github.com/netbox-community/netbox/issues/152))
Users are now able to attach photos and other images to sites, racks, and devices. (Please ensure that the new `media` directory is writable by the system account NetBox runs as.)
### Global Search ([#159](https://github.com/netbox-community/netbox/issues/159))
NetBox now supports searching across all primary object types at once.
### Rack Elevations View ([#951](https://github.com/netbox-community/netbox/issues/951))
A new view has been introduced to display the elevations of multiple racks side-by-side.
## Enhancements
* [#154](https://github.com/netbox-community/netbox/issues/154) - Expanded device status field to include options other than active/offline
* [#430](https://github.com/netbox-community/netbox/issues/430) - Include circuits when rendering topology maps
* [#578](https://github.com/netbox-community/netbox/issues/578) - Show topology maps not assigned to a site on the home view
* [#1100](https://github.com/netbox-community/netbox/issues/1100) - Add a "view all" link to completed bulk import views is_pool for prefixes)
* [#1110](https://github.com/netbox-community/netbox/issues/1110) - Expand bulk edit forms to include boolean fields (e.g. toggle is_pool for prefixes)
## Bug Fixes
From v1.9.6:
* [#403](https://github.com/netbox-community/netbox/issues/403) - Record console/power/interface connects and disconnects as user actions
* [#853](https://github.com/netbox-community/netbox/issues/853) - Added "status" field to device bulk import form
* [#1101](https://github.com/netbox-community/netbox/issues/1101) - Fix AJAX scripting for device component selection forms
* [#1103](https://github.com/netbox-community/netbox/issues/1103) - Correct handling of validation errors when creating IP addresses in bulk
* [#1104](https://github.com/netbox-community/netbox/issues/1104) - Fix VLAN assignment on prefix import
* [#1115](https://github.com/netbox-community/netbox/issues/1115) - Enabled responsive (side-scrolling) tables for small screens
* [#1116](https://github.com/netbox-community/netbox/issues/1116) - Correct object links on recursive deletion error
* [#1125](https://github.com/netbox-community/netbox/issues/1125) - Include MAC addresses on a device's interface list
* [#1144](https://github.com/netbox-community/netbox/issues/1144) - Allow multiple status selections for Prefix, IP address, and VLAN filters
From beta3:
* [#1113](https://github.com/netbox-community/netbox/issues/1113) - Fixed server error when attempting to delete an image attachment
* [#1114](https://github.com/netbox-community/netbox/issues/1114) - Suppress OSError when attempting to access a deleted image attachment
* [#1126](https://github.com/netbox-community/netbox/issues/1126) - Fixed server error when editing a user key via admin UI attachment
* [#1132](https://github.com/netbox-community/netbox/issues/1132) - Prompt user to unlock session key when importing secrets
## Additional Changes
* The Module DCIM model has been renamed to InventoryItem to better reflect its intended function, and to make room for work on [#824](https://github.com/netbox-community/netbox/issues/824).
* Redundant portions of the admin UI have been removed ([#973](https://github.com/netbox-community/netbox/issues/973)).
* The Docker build components have been moved into [their own repository](https://github.com/netbox-community/netbox-docker).

View File

@@ -0,0 +1,152 @@
# v2.1.6 (2017-10-11)
## Enhancements
* [#1548](https://github.com/netbox-community/netbox/issues/1548) - Automatically populate tenant assignment when adding an IP address from the prefix view
* [#1561](https://github.com/netbox-community/netbox/issues/1561) - Added primary IP to the devices table in global search
* [#1563](https://github.com/netbox-community/netbox/issues/1563) - Made necessary updates for Django REST Framework v3.7.0
---
# v2.1.5 (2017-09-25)
## Enhancements
* [#1484](https://github.com/netbox-community/netbox/issues/1484) - Added individual "add VLAN" buttons on the VLAN groups list
* [#1485](https://github.com/netbox-community/netbox/issues/1485) - Added `BANNER_LOGIN` configuration setting to display a banner on the login page
* [#1499](https://github.com/netbox-community/netbox/issues/1499) - Added utilization graph to child prefixes table
* [#1523](https://github.com/netbox-community/netbox/issues/1523) - Improved the natural ordering of interfaces (thanks to [@tarkatronic](https://github.com/tarkatronic))
* [#1536](https://github.com/netbox-community/netbox/issues/1536) - Improved formatting of aggregate prefix statistics
## Bug Fixes
* [#1469](https://github.com/netbox-community/netbox/issues/1469) - Allow a NAT IP to be assigned as the primary IP for a device
* [#1472](https://github.com/netbox-community/netbox/issues/1472) - Prevented truncation when displaying secret strings containing HTML characters
* [#1486](https://github.com/netbox-community/netbox/issues/1486) - Ignore subinterface IDs when validating LLDP neighbor connections
* [#1489](https://github.com/netbox-community/netbox/issues/1489) - Corrected server error on validation of empty required custom field
* [#1507](https://github.com/netbox-community/netbox/issues/1507) - Fixed error when creating the next available IP from a prefix within a VRF
* [#1520](https://github.com/netbox-community/netbox/issues/1520) - Redirect on GET request to bulk edit/delete views
* [#1522](https://github.com/netbox-community/netbox/issues/1522) - Removed object create/edit forms from the browsable API
---
# v2.1.4 (2017-08-30)
## Enhancements
* [#1326](https://github.com/netbox-community/netbox/issues/1326) - Added dropdown widget with common values for circuit speed fields
* [#1341](https://github.com/netbox-community/netbox/issues/1341) - Added a `MEDIA_ROOT` configuration setting to specify where uploaded files are stored on disk
* [#1376](https://github.com/netbox-community/netbox/issues/1376) - Ignore anycast addresses when detecting duplicate IPs
* [#1402](https://github.com/netbox-community/netbox/issues/1402) - Increased max length of name field for device components
* [#1431](https://github.com/netbox-community/netbox/issues/1431) - Added interface form factor for 10GBASE-CX4
* [#1432](https://github.com/netbox-community/netbox/issues/1432) - Added a `commit_rate` field to the circuits list search form
* [#1460](https://github.com/netbox-community/netbox/issues/1460) - Hostnames with no domain are now acceptable in custom URL fields
## Bug Fixes
* [#1429](https://github.com/netbox-community/netbox/issues/1429) - Fixed uptime formatting on device status page
* [#1433](https://github.com/netbox-community/netbox/issues/1433) - Fixed `devicetype_id` filter for DeviceType components
* [#1443](https://github.com/netbox-community/netbox/issues/1443) - Fixed API validation error involving custom field data
* [#1458](https://github.com/netbox-community/netbox/issues/1458) - Corrected permission name on prefix/VLAN roles list
---
# v2.1.3 (2017-08-15)
## Bug Fixes
* [#1330](https://github.com/netbox-community/netbox/issues/1330) - Raise validation error when assigning an unrelated IP as the primary IP for a device
* [#1389](https://github.com/netbox-community/netbox/issues/1389) - Avoid splitting carat/prefix on prefix list
* [#1400](https://github.com/netbox-community/netbox/issues/1400) - Removed redundant display of assigned device interface from IP address list
* [#1414](https://github.com/netbox-community/netbox/issues/1414) - Selecting a site from the rack filters automatically updates the available rack groups
* [#1419](https://github.com/netbox-community/netbox/issues/1419) - Allow editing image attachments without re-uploading an image
* [#1420](https://github.com/netbox-community/netbox/issues/1420) - Exclude virtual interfaces from device LLDP neighbors view
* [#1421](https://github.com/netbox-community/netbox/issues/1421) - Improved model validation logic for API serializers
* Fixed page title capitalization in the browsable API
---
# v2.1.2 (2017-08-04)
## Enhancements
* [#992](https://github.com/netbox-community/netbox/issues/992) - Allow the creation of multiple services per device with the same protocol and port
* Tweaked navigation menu styling
## Bug Fixes
* [#1388](https://github.com/netbox-community/netbox/issues/1388) - Fixed server error when searching globally for IPs/prefixes (rolled back #1379)
* [#1390](https://github.com/netbox-community/netbox/issues/1390) - Fixed IndexError when viewing available IPs within large IPv6 prefixes
---
# v2.1.1 (2017-08-02)
## Enhancements
* [#893](https://github.com/netbox-community/netbox/issues/893) - Allow filtering by null values for NullCharacterFields (e.g. return only unnamed devices)
* [#1368](https://github.com/netbox-community/netbox/issues/1368) - Render reservations in rack elevations view
* [#1374](https://github.com/netbox-community/netbox/issues/1374) - Added NAPALM_ARGS and NAPALM_TIMEOUT configiuration parameters
* [#1375](https://github.com/netbox-community/netbox/issues/1375) - Renamed `NETBOX_USERNAME` and `NETBOX_PASSWORD` configuration parameters to `NAPALM_USERNAME` and `NAPALM_PASSWORD`
* [#1379](https://github.com/netbox-community/netbox/issues/1379) - Allow searching devices by interface MAC address in global search
## Bug Fixes
* [#461](https://github.com/netbox-community/netbox/issues/461) - Display a validation error when attempting to assigning a new child device to a rack face/position
* [#1385](https://github.com/netbox-community/netbox/issues/1385) - Connected device API endpoint no longer requires authentication if `LOGIN_REQUIRED` is False
---
# v2.1.0 (2017-07-25)
## New Features
### IP Address Roles ([#819](https://github.com/netbox-community/netbox/issues/819))
The IP address model now supports the assignment of a functional role to help identify special-purpose IPs. These include:
* Loopback
* Secondary
* Anycast
* VIP
* VRRP
* HSRP
* GLBP
### Automatic Provisioning of Next Available IP ([#1246](https://github.com/netbox-community/netbox/issues/1246))
A new API endpoint has been added at `/api/ipam/prefixes/<pk>/available-ips/`. A GET request to this endpoint will return a list of available IP addresses within the prefix (up to the pagination limit). A POST request will automatically create and return the next available IP address.
### NAPALM Integration ([#1348](https://github.com/netbox-community/netbox/issues/1348))
The [NAPALM automation](https://napalm-automation.net/) library provides an abstracted interface for pulling live data (e.g. uptime, software version, running config, LLDP neighbors, etc.) from network devices. The NetBox API has been extended to support executing read-only NAPALM methods on devices defined in NetBox. To enable this functionality, ensure that NAPALM has been installed (`pip install napalm`) and the `NETBOX_USERNAME` and `NETBOX_PASSWORD` [configuration parameters](http://netbox.readthedocs.io/en/stable/configuration/optional-settings/#netbox_username) have been set in configuration.py.
## Enhancements
* [#838](https://github.com/netbox-community/netbox/issues/838) - Display details of all objects being edited/deleted in bulk
* [#1041](https://github.com/netbox-community/netbox/issues/1041) - Added enabled and MTU fields to the interface model
* [#1121](https://github.com/netbox-community/netbox/issues/1121) - Added asset_tag and description fields to the InventoryItem model
* [#1141](https://github.com/netbox-community/netbox/issues/1141) - Include RD when listing VRFs in a form selection field
* [#1203](https://github.com/netbox-community/netbox/issues/1203) - Implemented query filters for all models
* [#1218](https://github.com/netbox-community/netbox/issues/1218) - Added IEEE 802.11 wireless interface types
* [#1269](https://github.com/netbox-community/netbox/issues/1269) - Added circuit termination to interface serializer
* [#1320](https://github.com/netbox-community/netbox/issues/1320) - Removed checkbox from confirmation dialog
## Bug Fixes
* [#1079](https://github.com/netbox-community/netbox/issues/1079) - Order interfaces naturally via API
* [#1285](https://github.com/netbox-community/netbox/issues/1285) - Enforce model validation when creating/editing objects via the API
* [#1358](https://github.com/netbox-community/netbox/issues/1358) - Correct VRF example values in IP/prefix import forms
* [#1362](https://github.com/netbox-community/netbox/issues/1362) - Raise validation error when attempting to create an API key that's too short
* [#1371](https://github.com/netbox-community/netbox/issues/1371) - Extend DeviceSerializer.parent_device to include standard fields
## API changes
* Added a new API endpoint which makes [NAPALM](https://github.com/napalm-automation/napalm) accessible via NetBox
* Device components (console ports, power ports, interfaces, etc.) can only be filtered by a single device name or ID. This limitation was necessary to allow the natural ordering of interfaces according to the device's parent device type.
* Added two new fields to the interface serializer: `enabled` (boolean) and `mtu` (unsigned integer)
* Modified the interface serializer to include three discrete fields relating to connections: `is_connected` (boolean), `interface_connection`, and `circuit_termination`
* Added two new fields to the inventory item serializer: `asset_tag` and `description`
* Added "wireless" to interface type filter (in addition to physical, virtual, and LAG)
* Added a new endpoint at /api/ipam/prefixes/<pk>/available-ips/ to retrieve or create available IPs within a prefix
* Extended `parent_device` on DeviceSerializer to include the `url` and `display_name` of the parent Device, and the `url` of the DeviceBay

View File

@@ -0,0 +1,225 @@
# v2.2.10 (2018-02-21)
## Enhancements
* [#78](https://github.com/netbox-community/netbox/issues/78) - Extended topology maps to support console and power connections
* [#1693](https://github.com/netbox-community/netbox/issues/1693) - Allow specifying loose or exact matching for custom field filters
* [#1714](https://github.com/netbox-community/netbox/issues/1714) - Standardized CSV export functionality for all object lists
* [#1876](https://github.com/netbox-community/netbox/issues/1876) - Added explanatory title text to disabled NAPALM buttons on device view
* [#1885](https://github.com/netbox-community/netbox/issues/1885) - Added a device filter field for primary IP
## Bug Fixes
* [#1858](https://github.com/netbox-community/netbox/issues/1858) - Include device/VM count for cluster list in global search results
* [#1859](https://github.com/netbox-community/netbox/issues/1859) - Implemented support for line breaks within CSV fields
* [#1860](https://github.com/netbox-community/netbox/issues/1860) - Do not populate initial values for custom fields when editing objects in bulk
* [#1869](https://github.com/netbox-community/netbox/issues/1869) - Corrected ordering of VRFs with duplicate names
* [#1886](https://github.com/netbox-community/netbox/issues/1886) - Allow setting the primary IPv4/v6 address for a virtual machine via the web UI
---
# v2.2.9 (2018-01-31)
## Enhancements
* [#144](https://github.com/netbox-community/netbox/issues/144) - Implemented bulk import/edit/delete views for InventoryItems
* [#1073](https://github.com/netbox-community/netbox/issues/1073) - Include prefixes/IPs from all VRFs when viewing the children of a container prefix in the global table
* [#1366](https://github.com/netbox-community/netbox/issues/1366) - Enable searching for regions by name/slug
* [#1406](https://github.com/netbox-community/netbox/issues/1406) - Display tenant description as title text in object tables
* [#1824](https://github.com/netbox-community/netbox/issues/1824) - Add virtual machine count to platforms list
* [#1835](https://github.com/netbox-community/netbox/issues/1835) - Consistent positioning of previous/next rack buttons
## Bug Fixes
* [#1621](https://github.com/netbox-community/netbox/issues/1621) - Tweaked LLDP interface name evaluation logic
* [#1765](https://github.com/netbox-community/netbox/issues/1765) - Improved rendering of null options for model choice fields in filter forms
* [#1807](https://github.com/netbox-community/netbox/issues/1807) - Populate VRF from parent when creating a new prefix
* [#1809](https://github.com/netbox-community/netbox/issues/1809) - Populate tenant assignment from parent when creating a new prefix
* [#1818](https://github.com/netbox-community/netbox/issues/1818) - InventoryItem API serializer no longer requires specifying a null value for items with no parent
* [#1845](https://github.com/netbox-community/netbox/issues/1845) - Correct display of VMs in list with no role assigned
* [#1850](https://github.com/netbox-community/netbox/issues/1850) - Fix TypeError when attempting IP address import if only unnamed devices exist
---
# v2.2.8 (2017-12-20)
## Enhancements
* [#1771](https://github.com/netbox-community/netbox/issues/1771) - Added name filter for racks
* [#1772](https://github.com/netbox-community/netbox/issues/1772) - Added position filter for devices
* [#1773](https://github.com/netbox-community/netbox/issues/1773) - Moved child prefixes table to its own view
* [#1774](https://github.com/netbox-community/netbox/issues/1774) - Include a button to refine search results for all object types under global search
* [#1784](https://github.com/netbox-community/netbox/issues/1784) - Added `cluster_type` filters for virtual machines
## Bug Fixes
* [#1766](https://github.com/netbox-community/netbox/issues/1766) - Fixed display of "select all" button on device power outlets list
* [#1767](https://github.com/netbox-community/netbox/issues/1767) - Use proper template for 404 responses
* [#1778](https://github.com/netbox-community/netbox/issues/1778) - Preserve initial VRF assignment when adding IP addresses in bulk from a prefix
* [#1783](https://github.com/netbox-community/netbox/issues/1783) - Added `vm_role` filter for device roles
* [#1785](https://github.com/netbox-community/netbox/issues/1785) - Omit filter forms from browsable API
* [#1787](https://github.com/netbox-community/netbox/issues/1787) - Added missing site field to virtualization cluster CSV export
---
# v2.2.7 (2017-12-07)
## Enhancements
* [#1722](https://github.com/netbox-community/netbox/issues/1722) - Added virtual machine count to site view
* [#1737](https://github.com/netbox-community/netbox/issues/1737) - Added a `contains` API filter to find all prefixes containing a given IP or prefix
## Bug Fixes
* [#1712](https://github.com/netbox-community/netbox/issues/1712) - Corrected tenant inheritance for new IP addresses created from a parent prefix
* [#1721](https://github.com/netbox-community/netbox/issues/1721) - Differentiated child IP count from utilization percentage for prefixes
* [#1740](https://github.com/netbox-community/netbox/issues/1740) - Delete session_key cookie on logout
* [#1741](https://github.com/netbox-community/netbox/issues/1741) - Fixed Unicode support for secret plaintexts
* [#1743](https://github.com/netbox-community/netbox/issues/1743) - Include number of instances for device types in global search
* [#1751](https://github.com/netbox-community/netbox/issues/1751) - Corrected filtering for IPv6 addresses containing letters
* [#1756](https://github.com/netbox-community/netbox/issues/1756) - Improved natural ordering of console server ports and power outlets
---
# v2.2.6 (2017-11-16)
## Enhancements
* [#1669](https://github.com/netbox-community/netbox/issues/1669) - Clicking "add an IP" from the prefix view will default to the first available IP within the prefix
## Bug Fixes
* [#1397](https://github.com/netbox-community/netbox/issues/1397) - Display global search in navigation menu unless display is less than 1200px wide
* [#1599](https://github.com/netbox-community/netbox/issues/1599) - Reduce mobile cut-off for navigation menu to 960px
* [#1715](https://github.com/netbox-community/netbox/issues/1715) - Added missing import buttons on object lists
* [#1717](https://github.com/netbox-community/netbox/issues/1717) - Fixed interface validation for virtual machines
* [#1718](https://github.com/netbox-community/netbox/issues/1718) - Set empty label to "Global" or VRF field in IP assignment form
---
# v2.2.5 (2017-11-14)
## Enhancements
* [#1512](https://github.com/netbox-community/netbox/issues/1512) - Added a view to search for an IP address being assigned to an interface
* [#1679](https://github.com/netbox-community/netbox/issues/1679) - Added IP address roles to device/VM interface lists
* [#1683](https://github.com/netbox-community/netbox/issues/1683) - Replaced default 500 handler with custom middleware to provide preliminary troubleshooting assistance
* [#1684](https://github.com/netbox-community/netbox/issues/1684) - Replaced prefix `parent` filter with `within` and `within_include`
## Bug Fixes
* [#1471](https://github.com/netbox-community/netbox/issues/1471) - Correct bulk selection of IP addresses within a prefix assigned to a VRF
* [#1642](https://github.com/netbox-community/netbox/issues/1642) - Validate device type classification when creating console server ports and power outlets
* [#1650](https://github.com/netbox-community/netbox/issues/1650) - Correct numeric ordering for interfaces with no alphabetic type
* [#1676](https://github.com/netbox-community/netbox/issues/1676) - Correct filtering of child prefixes upon bulk edit/delete from the parent prefix view
* [#1689](https://github.com/netbox-community/netbox/issues/1689) - Disregard IP address mask when filtering for child IPs of a prefix
* [#1696](https://github.com/netbox-community/netbox/issues/1696) - Fix for NAPALM v2.0+
* [#1699](https://github.com/netbox-community/netbox/issues/1699) - Correct nested representation in the API of primary IPs for virtual machines and add missing primary_ip property
* [#1701](https://github.com/netbox-community/netbox/issues/1701) - Fixed validation in `extras/0008_reports.py` migration for certain versions of PostgreSQL
* [#1703](https://github.com/netbox-community/netbox/issues/1703) - Added API serializer validation for custom integer fields
* [#1705](https://github.com/netbox-community/netbox/issues/1705) - Fixed filtering of devices with a status of offline
---
# v2.2.4 (2017-10-31)
## Bug Fixes
* [#1670](https://github.com/netbox-community/netbox/issues/1670) - Fixed server error when calling certain filters (regression from #1649)
---
# v2.2.3 (2017-10-31)
## Enhancements
* [#999](https://github.com/netbox-community/netbox/issues/999) - Display devices on which circuits are terminated in circuits list
* [#1491](https://github.com/netbox-community/netbox/issues/1491) - Added initial data for the virtualization app
* [#1620](https://github.com/netbox-community/netbox/issues/1620) - Loosen IP address search filter to match all IPs that start with the given string
* [#1631](https://github.com/netbox-community/netbox/issues/1631) - Added a `post_run` method to the Report class
* [#1666](https://github.com/netbox-community/netbox/issues/1666) - Allow modifying the owner of a rack reservation
## Bug Fixes
* [#1513](https://github.com/netbox-community/netbox/issues/1513) - Correct filtering of custom field choices
* [#1603](https://github.com/netbox-community/netbox/issues/1603) - Hide selection checkboxes for tables with no available actions
* [#1618](https://github.com/netbox-community/netbox/issues/1618) - Allow bulk deletion of all virtual machines
* [#1619](https://github.com/netbox-community/netbox/issues/1619) - Correct text-based filtering of IP network and address fields
* [#1624](https://github.com/netbox-community/netbox/issues/1624) - Add VM count to device roles table
* [#1634](https://github.com/netbox-community/netbox/issues/1634) - Cluster should not be a required field when importing child devices
* [#1649](https://github.com/netbox-community/netbox/issues/1649) - Correct filtering on null values (e.g. ?tenant_id=0) for django-filters v1.1.0+
* [#1653](https://github.com/netbox-community/netbox/issues/1653) - Remove outdated description for DeviceType's `is_network_device` flag
* [#1664](https://github.com/netbox-community/netbox/issues/1664) - Added missing `serial` field in default rack CSV export
---
# v2.2.2 (2017-10-17)
## Enhancements
* [#1580](https://github.com/netbox-community/netbox/issues/1580) - Allow cluster assignment when bulk importing devices
* [#1587](https://github.com/netbox-community/netbox/issues/1587) - Add primary IP column for virtual machines in global search results
## Bug Fixes
* [#1498](https://github.com/netbox-community/netbox/issues/1498) - Avoid duplicating nodes when generating topology maps
* [#1579](https://github.com/netbox-community/netbox/issues/1579) - Devices already assigned to a cluster cannot be added to a different cluster
* [#1582](https://github.com/netbox-community/netbox/issues/1582) - Add `virtual_machine` attribute to IPAddress
* [#1584](https://github.com/netbox-community/netbox/issues/1584) - Colorized virtual machine role column
* [#1585](https://github.com/netbox-community/netbox/issues/1585) - Fixed slug-based filtering of virtual machines
* [#1605](https://github.com/netbox-community/netbox/issues/1605) - Added clusters and virtual machines to object list for global search
* [#1609](https://github.com/netbox-community/netbox/issues/1609) - Added missing `virtual_machine` field to IP address interface serializer
---
# v2.2.1 (2017-10-12)
## Bug Fixes
* [#1576](https://github.com/netbox-community/netbox/issues/1576) - Moved PostgreSQL validation logic into the relevant migration (fixed ImproperlyConfigured exception on init)
---
# v2.2.0 (2017-10-12)
**Note:** This release requires PostgreSQL 9.4 or higher. Do not attempt to upgrade unless you are running at least PostgreSQL 9.4.
**Note:** The release replaces the deprecated pycrypto library with [pycryptodome](https://github.com/Legrandin/pycryptodome). The upgrade script has been extended to automatically uninstall the old library, but please verify your installed packages with `pip freeze | grep pycrypto` if you run into problems.
## New Features
### Virtual Machines and Clusters ([#142](https://github.com/netbox-community/netbox/issues/142))
Our second-most popular feature request has arrived! NetBox now supports the creation of virtual machines, which can be assigned virtual interfaces and IP addresses. VMs are arranged into clusters, each of which has a type and (optionally) a group.
### Custom Validation Reports ([#1511](https://github.com/netbox-community/netbox/issues/1511))
Users can now create custom reports which are run to validate data in NetBox. Reports work very similar to Python unit tests: Each report inherits from NetBox's Report class and contains one or more test method. Reports can be run and retrieved via the web UI, API, or CLI. See [the docs](http://netbox.readthedocs.io/en/stable/miscellaneous/reports/) for more info.
## Enhancements
* [#494](https://github.com/netbox-community/netbox/issues/494) - Include asset tag in device info pop-up on rack elevation
* [#1444](https://github.com/netbox-community/netbox/issues/1444) - Added a `serial` field to the rack model
* [#1479](https://github.com/netbox-community/netbox/issues/1479) - Added an IP address role for CARP
* [#1506](https://github.com/netbox-community/netbox/issues/1506) - Extended rack facility ID field from 30 to 50 characters
* [#1510](https://github.com/netbox-community/netbox/issues/1510) - Added ability to search by name when adding devices to a cluster
* [#1527](https://github.com/netbox-community/netbox/issues/1527) - Replace deprecated pycrypto library with pycryptodome
* [#1551](https://github.com/netbox-community/netbox/issues/1551) - Added API endpoints listing static field choices for each app
* [#1556](https://github.com/netbox-community/netbox/issues/1556) - Added CPAK, CFP2, and CFP4 100GE interface form factors
* Added CSV import views for all object types
## Bug Fixes
* [#1550](https://github.com/netbox-community/netbox/issues/1550) - Corrected interface connections link in navigation menu
* [#1554](https://github.com/netbox-community/netbox/issues/1554) - Don't require form_factor when creating an interface assigned to a virtual machine
* [#1557](https://github.com/netbox-community/netbox/issues/1557) - Added filtering for virtual machine interfaces
* [#1567](https://github.com/netbox-community/netbox/issues/1567) - Prompt user for session key when importing secrets
## API Changes
* Introduced the virtualization app and its associated endpoints at `/api/virtualization`
* Added the `/api/extras/reports` endpoint for fetching and running reports
* The `ipam.Service` and `dcim.Interface` models now have a `virtual_machine` field in addition to the `device` field. Only one of the two fields may be defined for each object
* Added a `vm_role` field to `dcim.DeviceRole`, which indicates whether a role is suitable for assigned to a virtual machine
* Added a `serial` field to 'dcim.Rack` for serial numbers
* Each app now has a `_choices` endpoint, which lists the available options for all model field with static choices (e.g. interface form factors)

View File

@@ -0,0 +1,223 @@
# v2.3.7 (2018-07-26)
## Enhancements
* [#2166](https://github.com/netbox-community/netbox/issues/2166) - Enable partial matching on device asset_tag during search
## Bug Fixes
* [#1977](https://github.com/netbox-community/netbox/issues/1977) - Fixed exception when creating a virtual chassis with a non-master device in position 1
* [#1992](https://github.com/netbox-community/netbox/issues/1992) - Isolate errors when one of multiple NAPALM methods fails
* [#2202](https://github.com/netbox-community/netbox/issues/2202) - Ditched half-baked concept of tenancy inheritance via VRF
* [#2222](https://github.com/netbox-community/netbox/issues/2222) - IP addresses created via the `available-ips` API endpoint should have the same mask as their parent prefix (not /32)
* [#2231](https://github.com/netbox-community/netbox/issues/2231) - Remove `get_absolute_url()` from DeviceRole (can apply to devices or VMs)
* [#2250](https://github.com/netbox-community/netbox/issues/2250) - Include stat counters on report result navigation
* [#2255](https://github.com/netbox-community/netbox/issues/2255) - Corrected display of results in reports list
* [#2256](https://github.com/netbox-community/netbox/issues/2256) - Prevent navigation menu overlap when jumping to test results on report page
* [#2257](https://github.com/netbox-community/netbox/issues/2257) - Corrected casting of RIR utilization stats as floats
* [#2266](https://github.com/netbox-community/netbox/issues/2266) - Permit additional logging of exceptions beyond custom middleware
---
# v2.3.6 (2018-07-16)
## Enhancements
* [#2107](https://github.com/netbox-community/netbox/issues/2107) - Added virtual chassis to global search
* [#2125](https://github.com/netbox-community/netbox/issues/2125) - Show child status in device bay list
## Bug Fixes
* [#2214](https://github.com/netbox-community/netbox/issues/2214) - Error when assigning a VLAN to an interface on a VM in a cluster with no assigned site
* [#2239](https://github.com/netbox-community/netbox/issues/2239) - Pin django-filter to version 1.1.0
---
# v2.3.5 (2018-07-02)
## Enhancements
* [#2159](https://github.com/netbox-community/netbox/issues/2159) - Allow custom choice field to specify a default choice
* [#2177](https://github.com/netbox-community/netbox/issues/2177) - Include device serial number in rack elevation pop-up
* [#2194](https://github.com/netbox-community/netbox/issues/2194) - Added `address` filter to IPAddress model
## Bug Fixes
* [#1826](https://github.com/netbox-community/netbox/issues/1826) - Corrected description of security parameters under API definition
* [#2021](https://github.com/netbox-community/netbox/issues/2021) - Fix recursion error when viewing API docs under Python 3.4
* [#2064](https://github.com/netbox-community/netbox/issues/2064) - Disable calls to online swagger validator
* [#2173](https://github.com/netbox-community/netbox/issues/2173) - Fixed IndexError when automatically allocating IP addresses from large IPv6 prefixes
* [#2181](https://github.com/netbox-community/netbox/issues/2181) - Raise validation error on invalid `prefix_length` when allocating next-available prefix
* [#2182](https://github.com/netbox-community/netbox/issues/2182) - ValueError can be raised when viewing the interface connections table
* [#2191](https://github.com/netbox-community/netbox/issues/2191) - Added missing static choices to circuits and DCIM API endpoints
* [#2192](https://github.com/netbox-community/netbox/issues/2192) - Prevent a 0U device from being assigned to a rack position
---
# v2.3.4 (2018-06-07)
## Bug Fixes
* [#2066](https://github.com/netbox-community/netbox/issues/2066) - Catch `AddrFormatError` exception on invalid IP addresses
* [#2075](https://github.com/netbox-community/netbox/issues/2075) - Enable tenant assignment when creating a rack reservation via the API
* [#2083](https://github.com/netbox-community/netbox/issues/2083) - Add missing export button to rack roles list view
* [#2087](https://github.com/netbox-community/netbox/issues/2087) - Don't overwrite existing vc_position of master device when creating a virtual chassis
* [#2093](https://github.com/netbox-community/netbox/issues/2093) - Fix link to circuit termination in device interfaces table
* [#2097](https://github.com/netbox-community/netbox/issues/2097) - Fixed queryset-based bulk deletion of clusters and regions
* [#2098](https://github.com/netbox-community/netbox/issues/2098) - Fixed missing checkboxes for host devices in cluster view
* [#2127](https://github.com/netbox-community/netbox/issues/2127) - Prevent non-conntectable interfaces from being connected
* [#2143](https://github.com/netbox-community/netbox/issues/2143) - Accept null value for empty time zone field
* [#2148](https://github.com/netbox-community/netbox/issues/2148) - Do not force timezone selection when editing sites in bulk
* [#2150](https://github.com/netbox-community/netbox/issues/2150) - Fix display of LLDP neighbors when interface name contains a colon
---
# v2.3.3 (2018-04-19)
## Enhancements
* [#1990](https://github.com/netbox-community/netbox/issues/1990) - Improved search function when assigning an IP address to an interface
## Bug Fixes
* [#1975](https://github.com/netbox-community/netbox/issues/1975) - Correct filtering logic for custom boolean fields
* [#1988](https://github.com/netbox-community/netbox/issues/1988) - Order interfaces naturally when bulk renaming
* [#1993](https://github.com/netbox-community/netbox/issues/1993) - Corrected status choices in site CSV import form
* [#1999](https://github.com/netbox-community/netbox/issues/1999) - Added missing description field to site edit form
* [#2012](https://github.com/netbox-community/netbox/issues/2012) - Fixed deselection of an IP address as the primary IP for its parent device/VM
* [#2014](https://github.com/netbox-community/netbox/issues/2014) - Allow assignment of VLANs to VM interfaces via the API
* [#2019](https://github.com/netbox-community/netbox/issues/2019) - Avoid casting oversized numbers as integers
* [#2022](https://github.com/netbox-community/netbox/issues/2022) - Show 0 for zero-value fields on CSV export
* [#2023](https://github.com/netbox-community/netbox/issues/2023) - Manufacturer should not be a required field when importing platforms
* [#2037](https://github.com/netbox-community/netbox/issues/2037) - Fixed IndexError exception when attempting to create a new rack reservation
---
# v2.3.2 (2018-03-22)
## Enhancements
* [#1586](https://github.com/netbox-community/netbox/issues/1586) - Extend bulk interface creation to support alphanumeric characters
* [#1866](https://github.com/netbox-community/netbox/issues/1866) - Introduced AnnotatedMultipleChoiceField for filter forms
* [#1930](https://github.com/netbox-community/netbox/issues/1930) - Switched to drf-yasg for Swagger API documentation
* [#1944](https://github.com/netbox-community/netbox/issues/1944) - Enable assigning VLANs to virtual machine interfaces
* [#1945](https://github.com/netbox-community/netbox/issues/1945) - Implemented a VLAN members view
* [#1949](https://github.com/netbox-community/netbox/issues/1949) - Added a button to view elevations on rack groups list
* [#1952](https://github.com/netbox-community/netbox/issues/1952) - Implemented a more robust mechanism for assigning VLANs to interfaces
## Bug Fixes
* [#1948](https://github.com/netbox-community/netbox/issues/1948) - Fix TypeError when attempting to add a member to an existing virtual chassis
* [#1951](https://github.com/netbox-community/netbox/issues/1951) - Fix TypeError exception when importing platforms
* [#1953](https://github.com/netbox-community/netbox/issues/1953) - Ignore duplicate IPs when calculating prefix utilization
* [#1955](https://github.com/netbox-community/netbox/issues/1955) - Require a plaintext value when creating a new secret
* [#1978](https://github.com/netbox-community/netbox/issues/1978) - Include all virtual chassis member interfaces in LLDP neighbors view
* [#1980](https://github.com/netbox-community/netbox/issues/1980) - Fixed bug when trying to nullify a selection custom field under Python 2
---
# v2.3.1 (2018-03-01)
## Enhancements
* [#1910](https://github.com/netbox-community/netbox/issues/1910) - Added filters for cluster group and cluster type
## Bug Fixes
* [#1915](https://github.com/netbox-community/netbox/issues/1915) - Redirect to device view after deleting a component
* [#1919](https://github.com/netbox-community/netbox/issues/1919) - Prevent exception when attempting to create a virtual machine without selecting devices
* [#1921](https://github.com/netbox-community/netbox/issues/1921) - Ignore ManyToManyFields when validating a new object created via the API
* [#1924](https://github.com/netbox-community/netbox/issues/1924) - Include VID in VLAN lists when editing an interface
* [#1926](https://github.com/netbox-community/netbox/issues/1926) - Prevent reassignment of parent device when bulk editing VC member interfaces
* [#1927](https://github.com/netbox-community/netbox/issues/1927) - Include all VC member interfaces on A side when creating a new interface connection
* [#1928](https://github.com/netbox-community/netbox/issues/1928) - Fixed form validation when modifying VLANs assigned to an interface
* [#1934](https://github.com/netbox-community/netbox/issues/1934) - Fixed exception when rendering export template on an object type with custom fields assigned
* [#1935](https://github.com/netbox-community/netbox/issues/1935) - Correct API validation of VLANs assigned to interfaces
* [#1936](https://github.com/netbox-community/netbox/issues/1936) - Trigger validation error when attempting to create a virtual chassis without specifying member positions
---
# v2.3.0 (2018-02-26)
## New Features
### Virtual Chassis ([#99](https://github.com/netbox-community/netbox/issues/99))
A virtual chassis represents a set of physical devices with a shared control plane; for example, a stack of switches managed as a single device. Viewing the master device of a virtual chassis will show all member interfaces and IP addresses.
### Interface VLAN Assignments ([#150](https://github.com/netbox-community/netbox/issues/150))
Interfaces can now be assigned an 802.1Q mode (access or trunked) and associated with particular VLANs. Thanks to [John Anderson](https://github.com/lampwins) for his work on this!
### Bulk Object Creation via the API ([#1553](https://github.com/netbox-community/netbox/issues/1553))
The REST API now supports the creation of multiple objects of the same type using a single POST request. For example, to create multiple devices:
```
curl -X POST -H "Authorization: Token <TOKEN>" -H "Content-Type: application/json" -H "Accept: application/json; indent=4" http://localhost:8000/api/dcim/devices/ --data '[
{"name": "device1", "device_type": 24, "device_role": 17, "site": 6},
{"name": "device2", "device_type": 24, "device_role": 17, "site": 6},
{"name": "device3", "device_type": 24, "device_role": 17, "site": 6},
]'
```
Bulk creation is all-or-none: If any of the creations fails, the entire operation is rolled back.
### Automatic Provisioning of Next Available Prefixes ([#1694](https://github.com/netbox-community/netbox/issues/1694))
Similar to IP addresses, NetBox now supports automated provisioning of available prefixes from within a parent prefix. For example, to retrieve the next three available /28s within a parent /24:
```
curl -X POST -H "Authorization: Token <TOKEN>" -H "Content-Type: application/json" -H "Accept: application/json; indent=4" http://localhost:8000/api/ipam/prefixes/10153/available-prefixes/ --data '[
{"prefix_length": 28},
{"prefix_length": 28},
{"prefix_length": 28}
]'
```
If the parent prefix cannot accommodate all requested prefixes, the operation is cancelled and no new prefixes are created.
### Bulk Renaming of Device/VM Components ([#1781](https://github.com/netbox-community/netbox/issues/1781))
Device components (interfaces, console ports, etc.) can now be renamed in bulk via the web interface. This was implemented primarily to support the bulk renumbering of interfaces whose parent is part of a virtual chassis.
## Enhancements
* [#1283](https://github.com/netbox-community/netbox/issues/1283) - Added a `time_zone` field to the site model
* [#1321](https://github.com/netbox-community/netbox/issues/1321) - Added `created` and `last_updated` fields for relevant models to their API serializers
* [#1553](https://github.com/netbox-community/netbox/issues/1553) - Introduced support for bulk object creation via the API
* [#1592](https://github.com/netbox-community/netbox/issues/1592) - Added tenancy assignment for rack reservations
* [#1744](https://github.com/netbox-community/netbox/issues/1744) - Allow associating a platform with a specific manufacturer
* [#1758](https://github.com/netbox-community/netbox/issues/1758) - Added a `status` field to the site model
* [#1821](https://github.com/netbox-community/netbox/issues/1821) - Added a `description` field to the site model
* [#1864](https://github.com/netbox-community/netbox/issues/1864) - Added a `status` field to the circuit model
## Bug Fixes
* [#1136](https://github.com/netbox-community/netbox/issues/1136) - Enforce model validation during bulk update
* [#1645](https://github.com/netbox-community/netbox/issues/1645) - Simplified interface serialzier for IP addresses and optimized API view queryset
* [#1838](https://github.com/netbox-community/netbox/issues/1838) - Fix KeyError when attempting to create a VirtualChassis with no devices selected
* [#1847](https://github.com/netbox-community/netbox/issues/1847) - RecursionError when a virtual chasis master device has no name
* [#1848](https://github.com/netbox-community/netbox/issues/1848) - Allow null value for interface encapsulation mode
* [#1867](https://github.com/netbox-community/netbox/issues/1867) - Allow filtering on device status with multiple values
* [#1881](https://github.com/netbox-community/netbox/issues/1881)* - Fixed bulk editing of interface 802.1Q settings
* [#1884](https://github.com/netbox-community/netbox/issues/1884)* - Provide additional context to identify devices when creating/editing a virtual chassis
* [#1907](https://github.com/netbox-community/netbox/issues/1907) - Allow removing an IP as the primary for a device when editing the IP directly
\* New since v2.3-beta2
## Breaking Changes
* Constants representing device status have been renamed for clarity (for example, `STATUS_ACTIVE` is now `DEVICE_STATUS_ACTIVE`). Custom validation reports will need to be updated if they reference any of these constants.
## API Changes
* API creation calls now accept either a single JSON object or a list of JSON objects. If multiple objects are passed and one or more them fail validation, no objects will be created.
* Added `created` and `last_updated` fields for objects inheriting from CreatedUpdatedModel.
* Removed the `parent` filter for prefixes (use `within` or `within_include` instead).
* The IP address serializer now includes only a minimal nested representation of the assigned interface (if any) and its parent device or virtual machine.
* The rack reservation serializer now includes a nested representation of its owning user (as well as the assigned tenant, if any).
* Added endpoints for virtual chassis and VC memberships.
* Added `status`, `time_zone` (pytz format), and `description` fields to dcim.Site.
* Added a `manufacturer` foreign key field on dcim.Platform.
* Added a `status` field on circuits.Circuit.

View File

@@ -0,0 +1,233 @@
# v2.4.9 (2018-12-07)
## Enhancements
* [#2089](https://github.com/netbox-community/netbox/issues/2089) - Add SONET interface form factors
* [#2495](https://github.com/netbox-community/netbox/issues/2495) - Enable deep-merging of config context data
* [#2597](https://github.com/netbox-community/netbox/issues/2597) - Add FibreChannel SFP28 (32GFC) interface form factor
## Bug Fixes
* [#2400](https://github.com/netbox-community/netbox/issues/2400) - Correct representation of nested object assignment in API docs
* [#2576](https://github.com/netbox-community/netbox/issues/2576) - Correct type for count_* fields in site API representation
* [#2606](https://github.com/netbox-community/netbox/issues/2606) - Fixed filtering for interfaces with a virtual form factor
* [#2611](https://github.com/netbox-community/netbox/issues/2611) - Fix error handling when assigning a clustered device to a different site
* [#2613](https://github.com/netbox-community/netbox/issues/2613) - Decrease live search minimum characters to three
* [#2615](https://github.com/netbox-community/netbox/issues/2615) - Tweak live search widget to use brief format for API requests
* [#2623](https://github.com/netbox-community/netbox/issues/2623) - Removed the need to pass the model class to the rqworker process for webhooks
* [#2634](https://github.com/netbox-community/netbox/issues/2634) - Enforce consistent representation of unnamed devices in rack view
---
# v2.4.8 (2018-11-20)
## Enhancements
* [#2490](https://github.com/netbox-community/netbox/issues/2490) - Added bulk editing for config contexts
* [#2557](https://github.com/netbox-community/netbox/issues/2557) - Added object view for tags
## Bug Fixes
* [#2473](https://github.com/netbox-community/netbox/issues/2473) - Fix encoding of long (>127 character) secrets
* [#2558](https://github.com/netbox-community/netbox/issues/2558) - Filter on all tags when multiple are passed
* [#2565](https://github.com/netbox-community/netbox/issues/2565) - Improved rendering of Markdown tables
* [#2575](https://github.com/netbox-community/netbox/issues/2575) - Correct model specified for rack roles table
* [#2588](https://github.com/netbox-community/netbox/issues/2588) - Catch all exceptions from failed NAPALM API Calls
* [#2589](https://github.com/netbox-community/netbox/issues/2589) - Virtual machine API serializer should require cluster assignment
---
# v2.4.7 (2018-11-06)
## Enhancements
* [#2388](https://github.com/netbox-community/netbox/issues/2388) - Enable filtering of devices/VMs by region
* [#2427](https://github.com/netbox-community/netbox/issues/2427) - Allow filtering of interfaces by assigned VLAN or VLAN ID
* [#2512](https://github.com/netbox-community/netbox/issues/2512) - Add device field to inventory item filter form
## Bug Fixes
* [#2502](https://github.com/netbox-community/netbox/issues/2502) - Allow duplicate VIPs inside a uniqueness-enforced VRF
* [#2514](https://github.com/netbox-community/netbox/issues/2514) - Prevent new connections to already connected interfaces
* [#2515](https://github.com/netbox-community/netbox/issues/2515) - Only use django-rq admin tmeplate if webhooks are enabled
* [#2528](https://github.com/netbox-community/netbox/issues/2528) - Enable creating circuit terminations with interface assignment via API
* [#2549](https://github.com/netbox-community/netbox/issues/2549) - Changed naming of `peer_device` and `peer_interface` on API /dcim/connected-device/ endpoint to use underscores
---
# v2.4.6 (2018-10-05)
## Enhancements
* [#2479](https://github.com/netbox-community/netbox/issues/2479) - Add user permissions for creating/modifying API tokens
* [#2487](https://github.com/netbox-community/netbox/issues/2487) - Return abbreviated API output when passed `?brief=1`
## Bug Fixes
* [#2393](https://github.com/netbox-community/netbox/issues/2393) - Fix Unicode support for CSV import under Python 2
* [#2483](https://github.com/netbox-community/netbox/issues/2483) - Set max item count of API-populated form fields to MAX_PAGE_SIZE
* [#2484](https://github.com/netbox-community/netbox/issues/2484) - Local config context not available on the Virtual Machine Edit Form
* [#2485](https://github.com/netbox-community/netbox/issues/2485) - Fix cancel button when assigning a service to a device/VM
* [#2491](https://github.com/netbox-community/netbox/issues/2491) - Fix exception when importing devices with invalid device type
* [#2492](https://github.com/netbox-community/netbox/issues/2492) - Sanitize hostname and port values returned through LLDP
---
# v2.4.5 (2018-10-02)
## Enhancements
* [#2392](https://github.com/netbox-community/netbox/issues/2392) - Implemented local context data for devices and virtual machines
* [#2402](https://github.com/netbox-community/netbox/issues/2402) - Order and format JSON data in form fields
* [#2432](https://github.com/netbox-community/netbox/issues/2432) - Link remote interface connections to the Interface view
* [#2438](https://github.com/netbox-community/netbox/issues/2438) - API optimizations for tagged objects
## Bug Fixes
* [#2406](https://github.com/netbox-community/netbox/issues/2406) - Remove hard-coded limit of 1000 objects from API-populated form fields
* [#2414](https://github.com/netbox-community/netbox/issues/2414) - Tags field missing from device/VM component creation forms
* [#2442](https://github.com/netbox-community/netbox/issues/2442) - Nullify "next" link in API when limit=0 is passed
* [#2443](https://github.com/netbox-community/netbox/issues/2443) - Enforce JSON object format when creating config contexts
* [#2444](https://github.com/netbox-community/netbox/issues/2444) - Improve validation of interface MAC addresses
* [#2455](https://github.com/netbox-community/netbox/issues/2455) - Ignore unique address enforcement for IPs with a shared/virtual role
* [#2470](https://github.com/netbox-community/netbox/issues/2470) - Log the creation of device/VM components as object changes
---
# v2.4.4 (2018-08-22)
## Enhancements
* [#2168](https://github.com/netbox-community/netbox/issues/2168) - Added Extreme SummitStack interface form factors
* [#2356](https://github.com/netbox-community/netbox/issues/2356) - Include cluster site as read-only field in VirtualMachine serializer
* [#2362](https://github.com/netbox-community/netbox/issues/2362) - Implemented custom admin site to properly handle BASE_PATH
* [#2254](https://github.com/netbox-community/netbox/issues/2254) - Implemented searchability for Rack Groups
## Bug Fixes
* [#2353](https://github.com/netbox-community/netbox/issues/2353) - Handle `DoesNotExist` exception when deleting a device with connected interfaces
* [#2354](https://github.com/netbox-community/netbox/issues/2354) - Increased maximum MTU for interfaces to 65536 bytes
* [#2355](https://github.com/netbox-community/netbox/issues/2355) - Added item count to inventory tab on device view
* [#2368](https://github.com/netbox-community/netbox/issues/2368) - Record change in device changelog when altering cluster assignment
* [#2369](https://github.com/netbox-community/netbox/issues/2369) - Corrected time zone validation on site API serializer
* [#2370](https://github.com/netbox-community/netbox/issues/2370) - Redirect to parent device after deleting device bays
* [#2374](https://github.com/netbox-community/netbox/issues/2374) - Fix toggling display of IP addresses in virtual machine interfaces list
* [#2378](https://github.com/netbox-community/netbox/issues/2378) - Corrected "edit" link for virtual machine interfaces
---
# v2.4.3 (2018-08-09)
## Enhancements
* [#2333](https://github.com/netbox-community/netbox/issues/2333) - Added search filters for ConfigContexts
## Bug Fixes
* [#2334](https://github.com/netbox-community/netbox/issues/2334) - TypeError raised when WritableNestedSerializer receives a non-integer value
* [#2335](https://github.com/netbox-community/netbox/issues/2335) - API requires group field when creating/updating a rack
* [#2336](https://github.com/netbox-community/netbox/issues/2336) - Bulk deleting power outlets and console server ports from a device redirects to home page
* [#2337](https://github.com/netbox-community/netbox/issues/2337) - Attempting to create the next available prefix within a parent assigned to a VRF raises an AssertionError
* [#2340](https://github.com/netbox-community/netbox/issues/2340) - API requires manufacturer field when creating/updating an inventory item
* [#2342](https://github.com/netbox-community/netbox/issues/2342) - IntegrityError raised when attempting to assign an invalid IP address as the primary for a VM
* [#2344](https://github.com/netbox-community/netbox/issues/2344) - AttributeError when assigning VLANs to an interface on a device/VM not assigned to a site
---
# v2.4.2 (2018-08-08)
## Bug Fixes
* [#2318](https://github.com/netbox-community/netbox/issues/2318) - ImportError when viewing a report
* [#2319](https://github.com/netbox-community/netbox/issues/2319) - Extend ChoiceField to properly handle true/false choice keys
* [#2320](https://github.com/netbox-community/netbox/issues/2320) - TypeError when dispatching a webhook with a secret key configured
* [#2321](https://github.com/netbox-community/netbox/issues/2321) - Allow explicitly setting a null value on nullable ChoiceFields
* [#2322](https://github.com/netbox-community/netbox/issues/2322) - Webhooks firing on non-enabled event types
* [#2323](https://github.com/netbox-community/netbox/issues/2323) - DoesNotExist raised when deleting devices or virtual machines
* [#2330](https://github.com/netbox-community/netbox/issues/2330) - Incorrect tab link in VRF changelog view
---
# v2.4.1 (2018-08-07)
## Bug Fixes
* [#2303](https://github.com/netbox-community/netbox/issues/2303) - Always redirect to parent object when bulk editing/deleting components
* [#2308](https://github.com/netbox-community/netbox/issues/2308) - Custom fields panel absent from object view in UI
* [#2310](https://github.com/netbox-community/netbox/issues/2310) - False validation error on certain nested serializers
* [#2311](https://github.com/netbox-community/netbox/issues/2311) - Redirect to parent after editing interface from device/VM view
* [#2312](https://github.com/netbox-community/netbox/issues/2312) - Running a report yields a ValueError exception
* [#2314](https://github.com/netbox-community/netbox/issues/2314) - Serialized representation of object in change log does not include assigned tags
---
# v2.4.0 (2018-08-06)
## New Features
### Webhooks ([#81](https://github.com/netbox-community/netbox/issues/81))
Webhooks enable NetBox to send a representation of an object every time one is created, updated, or deleted. Webhooks are sent from NetBox to external services via HTTP, and can be limited by object type. Services which receive a webhook can act on the data provided by NetBox to automate other tasks.
Special thanks to [John Anderson](https://github.com/lampwins) for doing the heavy lifting for this feature!
### Tagging ([#132](https://github.com/netbox-community/netbox/issues/132))
Tags are free-form labels which can be assigned to a variety of objects in NetBox. Tags can be used to categorize and filter objects in addition to built-in and custom fields. Objects to which tags apply now include a `tags` field in the API.
### Contextual Configuration Data ([#1349](https://github.com/netbox-community/netbox/issues/1349))
Sometimes it is desirable to associate arbitrary data with a group of devices to aid in their configuration. (For example, you might want to associate a set of syslog servers for all devices at a particular site.) Context data enables the association of arbitrary data (expressed in JSON format) to devices and virtual machines grouped by region, site, role, platform, and/or tenancy. Context data is arranged hierarchically, so that data with a higher weight can be entered to override more general lower-weight data. Multiple instances of data are automatically merged by NetBox to present a single dictionary for each object.
### Change Logging ([#1898](https://github.com/netbox-community/netbox/issues/1898))
When an object is created, updated, or deleted, NetBox now automatically records a serialized representation of that object (similar to how it appears in the REST API) as well the event time and user account associated with the change.
## Enhancements
* [#238](https://github.com/netbox-community/netbox/issues/238) - Allow racks with the same name within a site (but in different groups)
* [#971](https://github.com/netbox-community/netbox/issues/971) - Add a view to show all VLAN IDs available within a group
* [#1673](https://github.com/netbox-community/netbox/issues/1673) - Added object/list views for services
* [#1687](https://github.com/netbox-community/netbox/issues/1687) - Enabled custom fields for services
* [#1739](https://github.com/netbox-community/netbox/issues/1739) - Enabled custom fields for secrets
* [#1794](https://github.com/netbox-community/netbox/issues/1794) - Improved POST/PATCH representation of nested objects
* [#2029](https://github.com/netbox-community/netbox/issues/2029) - Added optional NAPALM arguments to Platform model
* [#2034](https://github.com/netbox-community/netbox/issues/2034) - Include the ID when showing nested interface connections (API change)
* [#2118](https://github.com/netbox-community/netbox/issues/2118) - Added `latitude` and `longitude` fields to Site for GPS coordinates
* [#2131](https://github.com/netbox-community/netbox/issues/2131) - Added `created` and `last_updated` fields to DeviceType
* [#2157](https://github.com/netbox-community/netbox/issues/2157) - Fixed natural ordering of objects when sorted by name
* [#2225](https://github.com/netbox-community/netbox/issues/2225) - Add "view elevations" button for site rack groups
## Bug Fixes
* [#2272](https://github.com/netbox-community/netbox/issues/2272) - Allow subdevice_role to be null on DeviceTypeSerializer"
* [#2286](https://github.com/netbox-community/netbox/issues/2286) - Fixed "mark connected" button for PDU outlet connections
## API Changes
* Introduced the `/extras/config-contexts/`, `/extras/object-changes/`, and `/extras/tags/` API endpoints
* API writes now return a nested representation of related objects (rather than only a numeric ID)
* The dcim.DeviceType serializer now includes `created` and `last_updated` fields
* The dcim.Site serializer now includes `latitude` and `longitude` fields
* The ipam.Service and secrets.Secret serializers now include custom fields
* The dcim.Platform serializer now includes a free-form (JSON) `napalm_args` field
## Changes Since v2.4-beta1
### Enhancements
* [#2229](https://github.com/netbox-community/netbox/issues/2229) - Allow mapping of ConfigContexts to tenant groups
* [#2259](https://github.com/netbox-community/netbox/issues/2259) - Add changelog tab to interface view
* [#2264](https://github.com/netbox-community/netbox/issues/2264) - Added "map it" link for site GPS coordinates
### Bug Fixes
* [#2137](https://github.com/netbox-community/netbox/issues/2137) - Fixed JSON serialization of dates
* [#2258](https://github.com/netbox-community/netbox/issues/2258) - Include changed object type on home page changelog
* [#2265](https://github.com/netbox-community/netbox/issues/2265) - Include parent regions when filtering applicable ConfigContexts
* [#2288](https://github.com/netbox-community/netbox/issues/2288) - Fix exception when assigning objects to a ConfigContext via the API
* [#2296](https://github.com/netbox-community/netbox/issues/2296) - Fix AttributeError when creating a new object with tags assigned
* [#2300](https://github.com/netbox-community/netbox/issues/2300) - Fix assignment of an interface to an IP address via API PATCH
* [#2301](https://github.com/netbox-community/netbox/issues/2301) - Fix model validation on assignment of ManyToMany fields via API PATCH
* [#2305](https://github.com/netbox-community/netbox/issues/2305) - Make VLAN fields optional when creating a VM interface via the API

View File

@@ -0,0 +1,365 @@
# v2.5.13 (2019-05-31)
## Enhancements
* [#2813](https://github.com/netbox-community/netbox/issues/2813) - Add tenant group filters
* [#3085](https://github.com/netbox-community/netbox/issues/3085) - Catch all exceptions during export template rendering
* [#3138](https://github.com/netbox-community/netbox/issues/3138) - Add 2.5GE and 5GE interface form factors
* [#3151](https://github.com/netbox-community/netbox/issues/3151) - Add inventory item count to manufacturers list
* [#3156](https://github.com/netbox-community/netbox/issues/3156) - Add site link to rack reservations overview
* [#3183](https://github.com/netbox-community/netbox/issues/3183) - Enable bulk deletion of sites
* [#3185](https://github.com/netbox-community/netbox/issues/3185) - Improve performance for custom field access within templates
* [#3186](https://github.com/netbox-community/netbox/issues/3186) - Add interface name filter for IP addresses
## Bug Fixes
* [#3031](https://github.com/netbox-community/netbox/issues/3031) - Fixed form field population of tags with spaces
* [#3132](https://github.com/netbox-community/netbox/issues/3132) - Circuit termination missing from available cable termination types
* [#3150](https://github.com/netbox-community/netbox/issues/3150) - Fix formatting of cable length during cable trace
* [#3184](https://github.com/netbox-community/netbox/issues/3184) - Correctly display color block for white cables
* [#3190](https://github.com/netbox-community/netbox/issues/3190) - Fix custom field rendering for Jinja2 export templates
* [#3211](https://github.com/netbox-community/netbox/issues/3211) - Fix error handling when attempting to delete a protected object via API
* [#3223](https://github.com/netbox-community/netbox/issues/3223) - Fix filtering devices by "has power outlets"
* [#3227](https://github.com/netbox-community/netbox/issues/3227) - Fix exception when deleting a circuit with a termination(s)
* [#3228](https://github.com/netbox-community/netbox/issues/3228) - Fixed login link retaining query parameters
---
# v2.5.12 (2019-05-01)
## Bug Fixes
* [#3127](https://github.com/netbox-community/netbox/issues/3127) - Fix natural ordering of device components
---
2.5.11 (2019-04-29)
## Notes
This release upgrades the Django framework to version 2.2.
## Enhancements
* [#2986](https://github.com/netbox-community/netbox/issues/2986) - Improve natural ordering of device components
* [#3023](https://github.com/netbox-community/netbox/issues/3023) - Add support for filtering cables by connected device
* [#3070](https://github.com/netbox-community/netbox/issues/3070) - Add decommissioning status for devices
## Bug Fixes
* [#2621](https://github.com/netbox-community/netbox/issues/2621) - Upgrade Django requirement to 2.2 to fix object deletion issue in the changelog middleware
* [#3072](https://github.com/netbox-community/netbox/issues/3072) - Preserve multiselect filter values when updating per-page count for list views
* [#3112](https://github.com/netbox-community/netbox/issues/3112) - Fix ordering of interface connections list by termination B name/device
* [#3116](https://github.com/netbox-community/netbox/issues/3116) - Fix `tagged_items` count in tags API endpoint
* [#3118](https://github.com/netbox-community/netbox/issues/3118) - Disable `last_login` update on login when maintenance mode is enabled
---
# v2.5.10 (2019-04-08)
## Enhancements
* [#3052](https://github.com/netbox-community/netbox/issues/3052) - Add Jinja2 support for export templates
## Bug Fixes
* [#2937](https://github.com/netbox-community/netbox/issues/2937) - Redirect to list view after editing an object from list view
* [#3036](https://github.com/netbox-community/netbox/issues/3036) - DCIM interfaces API endpoint should not include VM interfaces
* [#3039](https://github.com/netbox-community/netbox/issues/3039) - Fix exception when retrieving change object for a component template via API
* [#3041](https://github.com/netbox-community/netbox/issues/3041) - Fix form widget for bulk cable label update
* [#3044](https://github.com/netbox-community/netbox/issues/3044) - Ignore site/rack fields when connecting a new cable via device search
* [#3046](https://github.com/netbox-community/netbox/issues/3046) - Fix exception at reports API endpoint
* [#3047](https://github.com/netbox-community/netbox/issues/3047) - Fix exception when writing mac address for an interface via API
---
# v2.5.9 (2019-04-01)
## Enhancements
* [#2933](https://github.com/netbox-community/netbox/issues/2933) - Add username to outbound webhook requests
* [#3011](https://github.com/netbox-community/netbox/issues/3011) - Add SSL support for django-rq (requires django-rq v1.3.1+)
* [#3025](https://github.com/netbox-community/netbox/issues/3025) - Add request ID to outbound webhook requests (for correlating all changes part of a single request)
## Bug Fixes
* [#2207](https://github.com/netbox-community/netbox/issues/2207) - Fixes deterministic ordering of interfaces
* [#2577](https://github.com/netbox-community/netbox/issues/2577) - Clarification of wording in API regarding filtering
* [#2924](https://github.com/netbox-community/netbox/issues/2924) - Add interface type for QSFP28 50GE
* [#2936](https://github.com/netbox-community/netbox/issues/2936) - Fix device role selection showing duplicate first entry
* [#2998](https://github.com/netbox-community/netbox/issues/2998) - Limit device query to non-racked devices if no rack selected when creating a cable
* [#3001](https://github.com/netbox-community/netbox/issues/3001) - Fix API representation of ObjectChange `action` and add `changed_object_type`
* [#3014](https://github.com/netbox-community/netbox/issues/3014) - Fixes VM Role filtering
* [#3019](https://github.com/netbox-community/netbox/issues/3019) - Fix tag population when running NetBox within a path
* [#3022](https://github.com/netbox-community/netbox/issues/3022) - Add missing cable termination types to DCIM `_choices` endpoint
* [#3026](https://github.com/netbox-community/netbox/issues/3026) - Tweak prefix/IP filter forms to filter using VRF ID rather than route distinguisher
* [#3027](https://github.com/netbox-community/netbox/issues/3027) - Ignore empty local context data when rendering config contexts
* [#3032](https://github.com/netbox-community/netbox/issues/3032) - Save assigned tags when creating a new secret
---
# v2.5.8 (2019-03-11)
## Enhancements
* [#2435](https://github.com/netbox-community/netbox/issues/2435) - Printer friendly CSS
## Bug Fixes
* [#2065](https://github.com/netbox-community/netbox/issues/2065) - Correct documentation for VM interface serializer
* [#2705](https://github.com/netbox-community/netbox/issues/2705) - Fix endpoint grouping in API docs
* [#2781](https://github.com/netbox-community/netbox/issues/2781) - Fix filtering of sites/devices/VMs by multiple regions
* [#2923](https://github.com/netbox-community/netbox/issues/2923) - Provider filter form's site field should be blank by default
* [#2938](https://github.com/netbox-community/netbox/issues/2938) - Enforce deterministic ordering of device components returned by API
* [#2939](https://github.com/netbox-community/netbox/issues/2939) - Exclude circuit terminations from API interface connections endpoint
* [#2940](https://github.com/netbox-community/netbox/issues/2940) - Allow CSV import of prefixes/IPs to VRF without an RD assigned
* [#2944](https://github.com/netbox-community/netbox/issues/2944) - Record the deletion of an IP address in the changelog of its parent interface (if any)
* [#2952](https://github.com/netbox-community/netbox/issues/2952) - Added the `slug` field to the Tenant filter for use in the API and search function
* [#2954](https://github.com/netbox-community/netbox/issues/2954) - Remove trailing slashes to fix root/template paths on Windows
* [#2961](https://github.com/netbox-community/netbox/issues/2961) - Prevent exception when exporting inventory items belonging to unnamed devices
* [#2962](https://github.com/netbox-community/netbox/issues/2962) - Increase ExportTemplate `mime_type` field length
* [#2966](https://github.com/netbox-community/netbox/issues/2966) - Accept `null` cable length_unit via API
* [#2972](https://github.com/netbox-community/netbox/issues/2972) - Improve ContentTypeField serializer to elegantly handle invalid data
* [#2976](https://github.com/netbox-community/netbox/issues/2976) - Add delete button to tag view
* [#2980](https://github.com/netbox-community/netbox/issues/2980) - Improve rendering time for API docs
* [#2982](https://github.com/netbox-community/netbox/issues/2982) - Correct CSS class assignment on color picker
* [#2984](https://github.com/netbox-community/netbox/issues/2984) - Fix logging of unlabeled cable ID on cable deletion
* [#2985](https://github.com/netbox-community/netbox/issues/2985) - Fix pagination page length for rack elevations
---
# v2.5.7 (2019-02-21)
## Enhancements
* [#2357](https://github.com/netbox-community/netbox/issues/2357) - Enable filtering of devices by rack face
* [#2638](https://github.com/netbox-community/netbox/issues/2638) - Add button to copy unlocked secret to clipboard
* [#2870](https://github.com/netbox-community/netbox/issues/2870) - Add Markdown rendering for provider NOC/admin contact fields
* [#2878](https://github.com/netbox-community/netbox/issues/2878) - Add cable types for OS1/OS2 singlemode fiber
* [#2890](https://github.com/netbox-community/netbox/issues/2890) - Add port types for APC fiber
* [#2898](https://github.com/netbox-community/netbox/issues/2898) - Enable filtering cables list by connection status
* [#2903](https://github.com/netbox-community/netbox/issues/2903) - Clarify purpose of tags field on interface edit form
## Bug Fixes
* [#2852](https://github.com/netbox-community/netbox/issues/2852) - Allow filtering devices by null rack position
* [#2884](https://github.com/netbox-community/netbox/issues/2884) - Don't display connect button for wireless interfaces
* [#2888](https://github.com/netbox-community/netbox/issues/2888) - Correct foreground color of device roles in rack elevations
* [#2893](https://github.com/netbox-community/netbox/issues/2893) - Remove duplicate display of VRF RD on IP address view
* [#2895](https://github.com/netbox-community/netbox/issues/2895) - Fix filtering of nullable character fields
* [#2901](https://github.com/netbox-community/netbox/issues/2901) - Fix ordering regions by site count
* [#2910](https://github.com/netbox-community/netbox/issues/2910) - Fix config context list and edit forms to use Select2 elements
* [#2912](https://github.com/netbox-community/netbox/issues/2912) - Cable type in filter form should be blank by default
* [#2913](https://github.com/netbox-community/netbox/issues/2913) - Fix assigned prefixes link on VRF view
* [#2914](https://github.com/netbox-community/netbox/issues/2914) - Fix empty connected circuit link on device interfaces list
* [#2915](https://github.com/netbox-community/netbox/issues/2915) - Fix bulk editing of pass-through ports
---
# v2.5.6 (2019-02-13)
## Enhancements
* [#2758](https://github.com/netbox-community/netbox/issues/2758) - Add cable trace button to pass-through ports
* [#2839](https://github.com/netbox-community/netbox/issues/2839) - Add "110 punch" type for pass-through ports
* [#2854](https://github.com/netbox-community/netbox/issues/2854) - Enable bulk editing of pass-through ports
* [#2866](https://github.com/netbox-community/netbox/issues/2866) - Add cellular interface types (GSM/CDMA/LTE)
## Bug Fixes
* [#2841](https://github.com/netbox-community/netbox/issues/2841) - Fix filtering by VRF for prefix and IP address lists
* [#2844](https://github.com/netbox-community/netbox/issues/2844) - Correct display of far cable end for pass-through ports
* [#2845](https://github.com/netbox-community/netbox/issues/2845) - Enable filtering of rack unit list by unit ID
* [#2856](https://github.com/netbox-community/netbox/issues/2856) - Fix navigation links between LAG interfaces and their members on device view
* [#2857](https://github.com/netbox-community/netbox/issues/2857) - Add `display_name` to DeviceType API serializer; fix DeviceType list for bulk device edit
* [#2862](https://github.com/netbox-community/netbox/issues/2862) - Follow return URL when connecting a cable
* [#2864](https://github.com/netbox-community/netbox/issues/2864) - Correct display of VRF name when no RD is assigned
* [#2877](https://github.com/netbox-community/netbox/issues/2877) - Fixed device role label display on light background color
* [#2880](https://github.com/netbox-community/netbox/issues/2880) - Sanitize user password if an exception is raised during login
---
# v2.5.5 (2019-01-31)
## Enhancements
* [#2805](https://github.com/netbox-community/netbox/issues/2805) - Allow null route distinguisher for VRFs
* [#2809](https://github.com/netbox-community/netbox/issues/2809) - Remove VRF child prefixes table; link to main prefixes view
* [#2825](https://github.com/netbox-community/netbox/issues/2825) - Include directly connected device for front/rear ports
## Bug Fixes
* [#2824](https://github.com/netbox-community/netbox/issues/2824) - Fix template exception when viewing rack elevations list
* [#2833](https://github.com/netbox-community/netbox/issues/2833) - Fix form widget for front port template creation
* [#2835](https://github.com/netbox-community/netbox/issues/2835) - Fix certain model filters did not support the `q` query param
* [#2837](https://github.com/netbox-community/netbox/issues/2837) - Fix select2 nullable filter fields add multiple null_option elements when paging
---
# v2.5.4 (2019-01-29)
## Enhancements
* [#2516](https://github.com/netbox-community/netbox/issues/2516) - Implemented Select2 for all Model backed selection fields
* [#2590](https://github.com/netbox-community/netbox/issues/2590) - Implemented the color picker with Select2 to show colors in the background
* [#2733](https://github.com/netbox-community/netbox/issues/2733) - Enable bulk assignment of MAC addresses to interfaces
* [#2735](https://github.com/netbox-community/netbox/issues/2735) - Implemented Select2 for all list filter form select elements
* [#2753](https://github.com/netbox-community/netbox/issues/2753) - Implemented Select2 to replace most all instances of select fields in forms
* [#2766](https://github.com/netbox-community/netbox/issues/2766) - Extend users admin table to include superuser and active fields
* [#2782](https://github.com/netbox-community/netbox/issues/2782) - Add `is_pool` field for prefix filtering
* [#2807](https://github.com/netbox-community/netbox/issues/2807) - Include device site/rack assignment in cable trace view
* [#2808](https://github.com/netbox-community/netbox/issues/2808) - Loosen version pinning for Django to allow patch releases
* [#2810](https://github.com/netbox-community/netbox/issues/2810) - Include description fields in interface connections export
## Bug Fixes
* [#2779](https://github.com/netbox-community/netbox/issues/2779) - Include "none" option when filter IP addresses by role
* [#2783](https://github.com/netbox-community/netbox/issues/2783) - Fix AttributeError exception when attempting to delete region(s)
* [#2795](https://github.com/netbox-community/netbox/issues/2795) - Fix duplicate display of pagination controls on child prefix/IP tables
* [#2798](https://github.com/netbox-community/netbox/issues/2798) - Properly URL-encode "map it" link on site view
* [#2802](https://github.com/netbox-community/netbox/issues/2802) - Better error handling for unsupported NAPALM methods
* [#2816](https://github.com/netbox-community/netbox/issues/2816) - Handle exception when deleting a device with connected components
---
# v2.5.3 (2019-01-11)
## Enhancements
* [#1630](https://github.com/netbox-community/netbox/issues/1630) - Enable bulk editing of prefix/IP mask length
* [#1870](https://github.com/netbox-community/netbox/issues/1870) - Add per-page toggle to object lists
* [#1871](https://github.com/netbox-community/netbox/issues/1871) - Enable filtering sites by parent region
* [#1983](https://github.com/netbox-community/netbox/issues/1983) - Enable regular expressions when bulk renaming device components
* [#2682](https://github.com/netbox-community/netbox/issues/2682) - Add DAC and AOC cable types
* [#2693](https://github.com/netbox-community/netbox/issues/2693) - Additional cable colors
* [#2726](https://github.com/netbox-community/netbox/issues/2726) - Include cables in global search
## Bug Fixes
* [#2742](https://github.com/netbox-community/netbox/issues/2742) - Preserve cluster assignment when editing a device
* [#2757](https://github.com/netbox-community/netbox/issues/2757) - Always treat first/last IPs within a /31 or /127 as usable
* [#2762](https://github.com/netbox-community/netbox/issues/2762) - Add missing DCIM field values to API `_choices` endpoint
* [#2777](https://github.com/netbox-community/netbox/issues/2777) - Fix cable validation to handle duplicate connections on import
---
# v2.5.2 (2018-12-21)
## Enhancements
* [#2561](https://github.com/netbox-community/netbox/issues/2561) - Add 200G and 400G interface types
* [#2701](https://github.com/netbox-community/netbox/issues/2701) - Enable filtering of prefixes by exact prefix value
## Bug Fixes
* [#2673](https://github.com/netbox-community/netbox/issues/2673) - Fix exception on LLDP neighbors view for device with a circuit connected
* [#2691](https://github.com/netbox-community/netbox/issues/2691) - Cable trace should follow circuits
* [#2698](https://github.com/netbox-community/netbox/issues/2698) - Remove pagination restriction on bulk component creation for devices/VMs
* [#2704](https://github.com/netbox-community/netbox/issues/2704) - Fix form select widget population on parent with null value
* [#2707](https://github.com/netbox-community/netbox/issues/2707) - Correct permission evaluation for circuit termination cabling
* [#2712](https://github.com/netbox-community/netbox/issues/2712) - Preserve list filtering after editing objects in bulk
* [#2717](https://github.com/netbox-community/netbox/issues/2717) - Fix bulk deletion of tags
* [#2721](https://github.com/netbox-community/netbox/issues/2721) - Detect loops when tracing front/rear ports
* [#2723](https://github.com/netbox-community/netbox/issues/2723) - Correct permission evaluation when bulk deleting tags
* [#2724](https://github.com/netbox-community/netbox/issues/2724) - Limit rear port choices to current device when editing a front port
---
# v2.5.1 (2018-12-13)
## Enhancements
* [#2655](https://github.com/netbox-community/netbox/issues/2655) - Add 128GFC Fibrechannel interface type
* [#2674](https://github.com/netbox-community/netbox/issues/2674) - Enable filtering changelog by object type under web UI
## Bug Fixes
* [#2662](https://github.com/netbox-community/netbox/issues/2662) - Fix ImproperlyConfigured exception when rendering API docs
* [#2663](https://github.com/netbox-community/netbox/issues/2663) - Prevent duplicate interfaces from appearing under VLAN members view
* [#2666](https://github.com/netbox-community/netbox/issues/2666) - Correct display of length unit in cables list
* [#2676](https://github.com/netbox-community/netbox/issues/2676) - Fix exception when passing dictionary value to a ChoiceField
* [#2678](https://github.com/netbox-community/netbox/issues/2678) - Fix error when viewing webhook in admin UI without write permission
* [#2680](https://github.com/netbox-community/netbox/issues/2680) - Disallow POST requests to `/dcim/interface-connections/` API endpoint
* [#2683](https://github.com/netbox-community/netbox/issues/2683) - Fix exception when connecting a cable to a RearPort with no corresponding FrontPort
* [#2684](https://github.com/netbox-community/netbox/issues/2684) - Fix custom field filtering
* [#2687](https://github.com/netbox-community/netbox/issues/2687) - Correct naming of before/after filters for changelog entries
---
# v2.5.0 (2018-12-10)
## Notes
### Python 3 Required
As promised, Python 2 support has been completed removed. Python 3.5 or higher is now required to run NetBox. Please see [our Python 3 migration guide](https://netbox.readthedocs.io/en/stable/installation/migrating-to-python3/) for assistance with upgrading.
### Removed Deprecated User Activity Log
The UserAction model, which was deprecated by the new change logging feature in NetBox v2.4, has been removed. If you need to archive legacy user activity, do so prior to upgrading to NetBox v2.5, as the database migration will remove all data associated with this model.
### View Permissions in Django 2.1
Django 2.1 introduces view permissions for object types (not to be confused with object-level permissions). Implementation of [#323](https://github.com/netbox-community/netbox/issues/323) is planned for NetBox v2.6. Users are encourage to begin assigning view permissions as desired in preparation for their eventual enforcement.
### upgrade.sh No Longer Invokes sudo
The `upgrade.sh` script has been tweaked so that it no longer invokes `sudo` internally. This was done to ensure compatibility when running NetBox inside a Python virtual environment. If you need elevated permissions when upgrading NetBox, call the upgrade script with `sudo upgrade.sh`.
## New Features
### Patch Panels and Cables ([#20](https://github.com/netbox-community/netbox/issues/20))
NetBox now supports modeling physical cables for console, power, and interface connections. The new pass-through port component type has also been introduced to model patch panels and similar devices.
## Enhancements
* [#450](https://github.com/netbox-community/netbox/issues/450) - Added `outer_width` and `outer_depth` fields to rack model
* [#867](https://github.com/netbox-community/netbox/issues/867) - Added `description` field to circuit terminations
* [#1444](https://github.com/netbox-community/netbox/issues/1444) - Added an `asset_tag` field for racks
* [#1931](https://github.com/netbox-community/netbox/issues/1931) - Added a count of assigned IP addresses to the interface API serializer
* [#2000](https://github.com/netbox-community/netbox/issues/2000) - Dropped support for Python 2
* [#2053](https://github.com/netbox-community/netbox/issues/2053) - Introduced the `LOGIN_TIMEOUT` configuration setting
* [#2057](https://github.com/netbox-community/netbox/issues/2057) - Added description columns to interface connections list
* [#2104](https://github.com/netbox-community/netbox/issues/2104) - Added a `status` field for racks
* [#2165](https://github.com/netbox-community/netbox/issues/2165) - Improved natural ordering of Interfaces
* [#2292](https://github.com/netbox-community/netbox/issues/2292) - Removed the deprecated UserAction model
* [#2367](https://github.com/netbox-community/netbox/issues/2367) - Removed deprecated RPCClient functionality
* [#2426](https://github.com/netbox-community/netbox/issues/2426) - Introduced `SESSION_FILE_PATH` configuration setting for authentication without write access to database
* [#2594](https://github.com/netbox-community/netbox/issues/2594) - `upgrade.sh` no longer invokes sudo
## Changes From v2.5-beta2
* [#2474](https://github.com/netbox-community/netbox/issues/2474) - Add `cabled` and `connection_status` filters for device components
* [#2616](https://github.com/netbox-community/netbox/issues/2616) - Convert Rack `outer_unit` and Cable `length_unit` to integer-based choice fields
* [#2622](https://github.com/netbox-community/netbox/issues/2622) - Enable filtering cables by multiple types/colors
* [#2624](https://github.com/netbox-community/netbox/issues/2624) - Delete associated content type and permissions when removing InterfaceConnection model
* [#2626](https://github.com/netbox-community/netbox/issues/2626) - Remove extraneous permissions generated from proxy models
* [#2632](https://github.com/netbox-community/netbox/issues/2632) - Change representation of null values from `0` to `null`
* [#2639](https://github.com/netbox-community/netbox/issues/2639) - Fix preservation of length/dimensions unit for racks and cables
* [#2648](https://github.com/netbox-community/netbox/issues/2648) - Include the `connection_status` field in nested represenations of connectable device components
* [#2649](https://github.com/netbox-community/netbox/issues/2649) - Add `connected_endpoint_type` to connectable device component API representations
## API Changes
* The `/extras/recent-activity/` endpoint (replaced by change logging in v2.4) has been removed
* The `rpc_client` field has been removed from dcim.Platform (see #2367)
* Introduced a new API endpoint for cables at `/dcim/cables/`
* New endpoints for front and rear pass-through ports (and their templates) in parallel with existing device components
* The fields `interface_connection` on Interface and `interface` on CircuitTermination have been replaced with `connected_endpoint` and `connection_status`
* A new `cable` field has been added to console, power, and interface components and to circuit terminations
* New fields for dcim.Rack: `status`, `asset_tag`, `outer_width`, `outer_depth`, `outer_unit`
* The following boolean filters on dcim.Device and dcim.DeviceType have been renamed:
* `is_console_server`: `console_server_ports`
* `is_pdu`: `power_outlets`
* `is_network_device`: `interfaces`
* The following new boolean filters have been introduced for dcim.Device and dcim.DeviceType:
* `console_ports`
* `power_ports`
* `pass_through_ports`
* The field `interface_ordering` has been removed from the DeviceType serializer
* Added a `description` field to the CircuitTermination serializer
* Added `ipaddress_count` to InterfaceSerializer to show the count of assigned IP addresses for each interface
* The `available-prefixes` and `available-ips` IPAM endpoints now return an HTTP 204 response instead of HTTP 400 when no new objects can be created
* Filtering on null values now uses the string `null` instead of zero

View File

@@ -0,0 +1,505 @@
# v2.6.12 (2020-01-13)
## Enhancements
* [#1982](https://github.com/netbox-community/netbox/issues/1982) - Improved NAPALM method documentation in Swagger (OpenAPI)
* [#2050](https://github.com/netbox-community/netbox/issues/2050) - Preview image attachments when hovering over the link
* [#2113](https://github.com/netbox-community/netbox/issues/2113) - Allow NAPALM driver settings to be changed with request headers
* [#2598](https://github.com/netbox-community/netbox/issues/2598) - Toggle the display of child prefixes/IP addresses
* [#3009](https://github.com/netbox-community/netbox/issues/3009) - Search by description when assigning IP address to interfaces
* [#3021](https://github.com/netbox-community/netbox/issues/3021) - Add `tenant` filter field for cables
* [#3090](https://github.com/netbox-community/netbox/issues/3090) - Enable filtering of interfaces by name on the device view
* [#3187](https://github.com/netbox-community/netbox/issues/3187) - Add rack selection field to rack elevations view
* [#3393](https://github.com/netbox-community/netbox/issues/3393) - Paginate assigned circuits at the provider details view
* [#3440](https://github.com/netbox-community/netbox/issues/3440) - Add total path length to cable trace
* [#3491](https://github.com/netbox-community/netbox/issues/3491) - Include content of response on webhook error
* [#3623](https://github.com/netbox-community/netbox/issues/3623) - Enable word expansion during interface creation
* [#3668](https://github.com/netbox-community/netbox/issues/3668) - Enable searching by DNS name when assigning IP address
* [#3851](https://github.com/netbox-community/netbox/issues/3851) - Allow passing initial data to custom script forms
* [#3891](https://github.com/netbox-community/netbox/issues/3891) - Add `local_context_data` filter for virtual machines
## Bug Fixes
* [#3589](https://github.com/netbox-community/netbox/issues/3589) - Fix validation on tagged VLANs of an interface
* [#3849](https://github.com/netbox-community/netbox/issues/3849) - Fix ordering of models when dumping data to JSON
* [#3853](https://github.com/netbox-community/netbox/issues/3853) - Fix device role link on config context view
* [#3856](https://github.com/netbox-community/netbox/issues/3856) - Allow filtering VM interfaces by multiple MAC addresses
* [#3857](https://github.com/netbox-community/netbox/issues/3857) - Fix rendering of grouped custom links
* [#3862](https://github.com/netbox-community/netbox/issues/3862) - Allow filtering device components by multiple device names
* [#3864](https://github.com/netbox-community/netbox/issues/3864) - Disallow /0 masks for prefixes and IP addresses
* [#3872](https://github.com/netbox-community/netbox/issues/3872) - Paginate related IPs on the IP address view
* [#3876](https://github.com/netbox-community/netbox/issues/3876) - Fix minimum/maximum value rendering for site ASN field
* [#3882](https://github.com/netbox-community/netbox/issues/3882) - Fix filtering of devices by rack group
* [#3898](https://github.com/netbox-community/netbox/issues/3898) - Fix references to deleted cables without a label
* [#3905](https://github.com/netbox-community/netbox/issues/3905) - Fix divide-by-zero on power feeds with low power values
---
# v2.6.11 (2020-01-03)
## Bug Fixes
* [#3831](https://github.com/netbox-community/netbox/issues/3831) - Fix API-driven filter field rendering (#3812 regression)
* [#3833](https://github.com/netbox-community/netbox/issues/3833) - Add missing region filters for multiple objects
---
# v2.6.10 (2020-01-02)
## Enhancements
* [#2233](https://github.com/netbox-community/netbox/issues/2233) - Add ability to move inventory items between devices
* [#2892](https://github.com/netbox-community/netbox/issues/2892) - Extend admin UI to allow deleting old report results
* [#3062](https://github.com/netbox-community/netbox/issues/3062) - Add `assigned_to_interface` filter for IP addresses
* [#3461](https://github.com/netbox-community/netbox/issues/3461) - Fail gracefully on custom link rendering exception
* [#3705](https://github.com/netbox-community/netbox/issues/3705) - Provide request context when executing custom scripts
* [#3762](https://github.com/netbox-community/netbox/issues/3762) - Add date/time picker widgets
* [#3788](https://github.com/netbox-community/netbox/issues/3788) - Enable partial search for inventory items
* [#3812](https://github.com/netbox-community/netbox/issues/3812) - Optimize size of pages containing a dynamic selection field
* [#3827](https://github.com/netbox-community/netbox/issues/3827) - Allow filtering console/power/interface connections by device ID
## Bug Fixes
* [#3106](https://github.com/netbox-community/netbox/issues/3106) - Restrict queryset of chained fields when form validation fails
* [#3695](https://github.com/netbox-community/netbox/issues/3695) - Include A/Z termination sites for circuits in global search
* [#3712](https://github.com/netbox-community/netbox/issues/3712) - Scrolling to target (hash) did not account for the header size
* [#3780](https://github.com/netbox-community/netbox/issues/3780) - Fix AttributeError exception in API docs
* [#3809](https://github.com/netbox-community/netbox/issues/3809) - Filter platform by manufacturer when editing devices
* [#3811](https://github.com/netbox-community/netbox/issues/3811) - Fix filtering of racks by group on device list
* [#3822](https://github.com/netbox-community/netbox/issues/3822) - Fix exception when editing a device bay (regression from #3596)
---
# v2.6.9 (2019-12-16)
## Enhancements
* [#3152](https://github.com/netbox-community/netbox/issues/3152) - Include direct link to rack elevations on site view
* [#3441](https://github.com/netbox-community/netbox/issues/3441) - Move virtual machine results near devices in global search
* [#3761](https://github.com/netbox-community/netbox/issues/3761) - Added copy button for API tokens
## Bug Fixes
* [#2170](https://github.com/netbox-community/netbox/issues/2170) - Prevent the deletion of a virtual chassis when a cross-member LAG is present
* [#2358](https://github.com/netbox-community/netbox/issues/2358) - Respect custom field default values when creating objects via the REST API
* [#3749](https://github.com/netbox-community/netbox/issues/3749) - Fix exception on password change page for local users
* [#3757](https://github.com/netbox-community/netbox/issues/3757) - Fix unable to assign IP to interface
---
# v2.6.8 (2019-12-10)
## Enhancements
* [#3139](https://github.com/netbox-community/netbox/issues/3139) - Disable password change form for LDAP-authenticated users
* [#3457](https://github.com/netbox-community/netbox/issues/3457) - Display cable colors on device view
* [#3329](https://github.com/netbox-community/netbox/issues/3329) - Remove obsolete P3P policy header
* [#3663](https://github.com/netbox-community/netbox/issues/3663) - Add query filters for `created` and `last_updated` fields
* [#3722](https://github.com/netbox-community/netbox/issues/3722) - Allow the underscore character in IPAddress DNS names
## Bug Fixes
* [#3312](https://github.com/netbox-community/netbox/issues/3312) - Fix validation error when editing power cables in bulk
* [#3644](https://github.com/netbox-community/netbox/issues/3644) - Fix exception when connecting a cable to a RearPort with no corresponding FrontPort
* [#3669](https://github.com/netbox-community/netbox/issues/3669) - Include `weight` field in prefix/VLAN role form
* [#3674](https://github.com/netbox-community/netbox/issues/3674) - Include comments on PowerFeed view
* [#3679](https://github.com/netbox-community/netbox/issues/3679) - Fix link for assigned ipaddress in interface page
* [#3709](https://github.com/netbox-community/netbox/issues/3709) - Prevent exception when importing an invalid cable definition
* [#3720](https://github.com/netbox-community/netbox/issues/3720) - Correctly indicate power feed terminations on cable list
* [#3724](https://github.com/netbox-community/netbox/issues/3724) - Fix API filtering of interfaces by more than one device name
* [#3725](https://github.com/netbox-community/netbox/issues/3725) - Enforce client validation for minimum service port number
---
# v2.6.7 (2019-11-01)
## Enhancements
* [#3445](https://github.com/netbox-community/netbox/issues/3445) - Add support for additional user defined headers to be added to webhook requests
* [#3499](https://github.com/netbox-community/netbox/issues/3499) - Add `ca_file_path` to Webhook model to support user supplied CA certificate verification of webhook requests
* [#3594](https://github.com/netbox-community/netbox/issues/3594) - Add ChoiceVar for custom scripts
* [#3619](https://github.com/netbox-community/netbox/issues/3619) - Add 400GE OSFP interface type
* [#3659](https://github.com/netbox-community/netbox/issues/3659) - Add filtering for objects in admin UI
## Bug Fixes
* [#3309](https://github.com/netbox-community/netbox/issues/3309) - Rewrite change logging middleware to resolve sporadic testing failures
* [#3340](https://github.com/netbox-community/netbox/issues/3340) - Add missing options to connect front ports to console ports
* [#3357](https://github.com/netbox-community/netbox/issues/3357) - Enable filter sites/devices/VMs by null region
* [#3460](https://github.com/netbox-community/netbox/issues/3460) - Extend upgrade script to validate Python dependencies
* [#3596](https://github.com/netbox-community/netbox/issues/3596) - Prevent server error when reassigning a device to a new device bay
* [#3629](https://github.com/netbox-community/netbox/issues/3629) - Use `get_lldp_neighors_detail` to validation LLDP neighbors
* [#3635](https://github.com/netbox-community/netbox/issues/3635) - Add missing cache support for the circuits app
* [#3636](https://github.com/netbox-community/netbox/issues/3636) - Add missing `rack_group` field to PowerFeed CSV export
* [#3652](https://github.com/netbox-community/netbox/issues/3652) - Limit next/previous rack by assigned rack group
---
# v2.6.6 (2019-10-10)
## Notes
* This release includes a migration which automatically updates all existing cables to enable filtering by site/rack (see [#3259](https://github.com/netbox-community/netbox/issues/3259)). This migration may take several minutes to complete on installations with tens of thousands of cables defined.
## Enhancements
* [#1941](https://github.com/netbox-community/netbox/issues/1941) - Add InfiniBand interface types
* [#3259](https://github.com/netbox-community/netbox/issues/3259) - Add `rack` and `site` filters for cables
* [#3471](https://github.com/netbox-community/netbox/issues/3471) - Disallow raw HTML in Markdown-rendered fields
* [#3545](https://github.com/netbox-community/netbox/issues/3545) - Add `MultiObjectVar` for custom scripts
* [#3563](https://github.com/netbox-community/netbox/issues/3563) - Enable editing of individual DeviceType components
* [#3580](https://github.com/netbox-community/netbox/issues/3580) - Render text and URL fields as textareas in the custom link form
* [#3581](https://github.com/netbox-community/netbox/issues/3581) - Introduce `commit_default` custom script attribute to not commit changes by default
## Bug Fixes
* [#3458](https://github.com/netbox-community/netbox/issues/3458) - Prevent primary IP address for a device/VM from being reassigned
* [#3463](https://github.com/netbox-community/netbox/issues/3463) - Correct CSV headers for exported power feeds
* [#3474](https://github.com/netbox-community/netbox/issues/3474) - Fix device status page loading when NAPALM call fails
* [#3571](https://github.com/netbox-community/netbox/issues/3571) - Prevent erroneous redirects when editing tags
* [#3573](https://github.com/netbox-community/netbox/issues/3573) - Ensure consistent display of changelog retention period
* [#3574](https://github.com/netbox-community/netbox/issues/3574) - Change `device` to `parent` in interface editing VLAN filtering logic
* [#3575](https://github.com/netbox-community/netbox/issues/3575) - Restore label for comments field when bulk editing circuits
* [#3582](https://github.com/netbox-community/netbox/issues/3582) - Enforce view permissions on global search results
* [#3588](https://github.com/netbox-community/netbox/issues/3588) - Enforce object-form JSON for local context data on devices and VMs
---
# v2.6.5 (2019-09-25)
## Enhancements
* [#3297](https://github.com/netbox-community/netbox/issues/3297) - Include reserved units when calculating rack utilization
* [#3347](https://github.com/netbox-community/netbox/issues/3347) - Extend upgrade script to automatically remove stale content types
* [#3352](https://github.com/netbox-community/netbox/issues/3352) - Enable filtering changelog API by `changed_object_id`
* [#3515](https://github.com/netbox-community/netbox/issues/3515) - Enable export templates for inventory items
* [#3524](https://github.com/netbox-community/netbox/issues/3524) - Enable bulk editing of power outlet/power port associations
* [#3529](https://github.com/netbox-community/netbox/issues/3529) - Enable filtering circuits list by region
## Bug Fixes
* [#3435](https://github.com/netbox-community/netbox/issues/3435) - Change IP/prefix CSV export to reference VRF name instead of RD
* [#3464](https://github.com/netbox-community/netbox/issues/3464) - Fix foreground text color on color picker fields
* [#3519](https://github.com/netbox-community/netbox/issues/3519) - Prevent cables from being terminated to virtual/wireless interfaces via API
* [#3521](https://github.com/netbox-community/netbox/issues/3521) - Fix error in `parseURL` related to variables in API URL
* [#3531](https://github.com/netbox-community/netbox/issues/3531) - Fixed rack role foreground color
* [#3534](https://github.com/netbox-community/netbox/issues/3534) - Added blank option for untagged VLANs
* [#3540](https://github.com/netbox-community/netbox/issues/3540) - Fixed virtual machine interface edit with new inline vlan edit fields
* [#3543](https://github.com/netbox-community/netbox/issues/3543) - Added inline VLAN editing to virtual machine interfaces
---
# v2.6.4 (2019-09-19)
## Enhancements
* [#2160](https://github.com/netbox-community/netbox/issues/2160) - Add bulk editing for interface VLAN assignment
* [#3027](https://github.com/netbox-community/netbox/issues/3028) - Add `local_context_data` boolean filter for devices
* [#3318](https://github.com/netbox-community/netbox/issues/3318) - Increase length of platform name and slug to 100 characters
* [#3341](https://github.com/netbox-community/netbox/issues/3341) - Enable inline VLAN assignment while editing an interface
* [#3485](https://github.com/netbox-community/netbox/issues/3485) - Enable embedded graphs for devices
* [#3510](https://github.com/netbox-community/netbox/issues/3510) - Add minimum/maximum prefix length enforcement for `IPNetworkVar`
## Bug Fixes
* [#3489](https://github.com/netbox-community/netbox/issues/3489) - Prevent exception triggered by webhook upon object deletion
* [#3501](https://github.com/netbox-community/netbox/issues/3501) - Fix rendering of checkboxes on custom script forms
* [#3511](https://github.com/netbox-community/netbox/issues/3511) - Correct API URL for nested device bays
* [#3513](https://github.com/netbox-community/netbox/issues/3513) - Fix assignment of tags when creating front/rear ports
* [#3514](https://github.com/netbox-community/netbox/issues/3514) - Label TextVar fields when rendering custom script forms
---
# v2.6.3 (2019-09-04)
## New Features
### Custom Scripts ([#3415](https://github.com/netbox-community/netbox/issues/3415))
Custom scripts allow for the execution of arbitrary code via the NetBox UI. They can be used to automatically create, manipulate, or clean up objects or perform other tasks within NetBox. Scripts are defined as Python files which contain one or more subclasses of `extras.scripts.Script`. Variable fields can be defined within scripts, which render as form fields within the web UI to prompt the user for input data. Scripts are executed and information is logged via the web UI. Please see [the docs](https://netbox.readthedocs.io/en/stable/additional-features/custom-scripts/) for more detail.
Note: There are currently no API endpoints for this feature. These are planned for the upcoming v2.7 release.
## Enhancements
* [#3386](https://github.com/netbox-community/netbox/issues/3386) - Add `mac_address` filter for virtual machines
* [#3391](https://github.com/netbox-community/netbox/issues/3391) - Update Bootstrap CSS to v3.4.1
* [#3405](https://github.com/netbox-community/netbox/issues/3405) - Fix population of power port/outlet details on device creation
* [#3422](https://github.com/netbox-community/netbox/issues/3422) - Prevent navigation menu from overlapping page content
* [#3430](https://github.com/netbox-community/netbox/issues/3430) - Linkify platform field on device view
* [#3454](https://github.com/netbox-community/netbox/issues/3454) - Enable filtering circuits by region
* [#3456](https://github.com/netbox-community/netbox/issues/3456) - Enable bulk editing of tag color
## Bug Fixes
* [#3392](https://github.com/netbox-community/netbox/issues/3392) - Add database index for ObjectChange time
* [#3420](https://github.com/netbox-community/netbox/issues/3420) - Serial number filter for racks, devices, and inventory items is now case-insensitive
* [#3428](https://github.com/netbox-community/netbox/issues/3428) - Fixed cache invalidation issues ([#3300](https://github.com/netbox-community/netbox/issues/3300), [#3363](https://github.com/netbox-community/netbox/issues/3363), [#3379](https://github.com/netbox-community/netbox/issues/3379), [#3382](https://github.com/netbox-community/netbox/issues/3382)) by switching to `prefetch_related()` instead of `select_related()` and removing use of `update()`
* [#3421](https://github.com/netbox-community/netbox/issues/3421) - Fix exception when ordering power connections list by PDU
* [#3424](https://github.com/netbox-community/netbox/issues/3424) - Fix tag coloring for non-linked tags
* [#3426](https://github.com/netbox-community/netbox/issues/3426) - Improve API error handling for ChoiceFields
---
# v2.6.2 (2019-08-02)
## Enhancements
* [#984](https://github.com/netbox-community/netbox/issues/984) - Allow ordering circuits by A/Z side
* [#3307](https://github.com/netbox-community/netbox/issues/3307) - Add power panels count to home page
* [#3314](https://github.com/netbox-community/netbox/issues/3314) - Paginate object changelog entries
* [#3367](https://github.com/netbox-community/netbox/issues/3367) - Add BNC port type and coaxial cable type
* [#3368](https://github.com/netbox-community/netbox/issues/3368) - Indicate indefinite changelog retention when applicable
* [#3370](https://github.com/netbox-community/netbox/issues/3370) - Add filter class to VirtualChassis API
## Bug Fixes
* [#3018](https://github.com/netbox-community/netbox/issues/3018) - Components connected via a cable must have an equal number of positions
* [#3289](https://github.com/netbox-community/netbox/issues/3289) - Prevent position from being nullified when moving a device to a new rack
* [#3293](https://github.com/netbox-community/netbox/issues/3293) - Enable filtering device components by multiple device IDs
* [#3315](https://github.com/netbox-community/netbox/issues/3315) - Enable filtering devices/interfaces by multiple MAC addresses
* [#3317](https://github.com/netbox-community/netbox/issues/3317) - Fix permissions for ConfigContextBulkDeleteView
* [#3323](https://github.com/netbox-community/netbox/issues/3323) - Fix permission evaluation for interface connections view
* [#3342](https://github.com/netbox-community/netbox/issues/3342) - Fix cluster delete button
* [#3384](https://github.com/netbox-community/netbox/issues/3384) - Maximum and allocated draw fields should be included on power port template creation form
* [#3385](https://github.com/netbox-community/netbox/issues/3385) - Fix power panels list when bulk editing power feeds
---
# v2.6.1 (2019-06-25)
## Enhancements
* [#3154](https://github.com/netbox-community/netbox/issues/3154) - Add `virtual_chassis_member` device filter
* [#3277](https://github.com/netbox-community/netbox/issues/3277) - Add cable trace buttons for console and power ports
* [#3281](https://github.com/netbox-community/netbox/issues/3281) - Hide custom links which render as empty text
## Bug Fixes
* [#3229](https://github.com/netbox-community/netbox/issues/3229) - Limit rack group selection by parent site on racks list
* [#3269](https://github.com/netbox-community/netbox/issues/3269) - Raise validation error when specifying non-existent cable terminations
* [#3275](https://github.com/netbox-community/netbox/issues/3275) - Fix error when adding power outlets to a device type
* [#3279](https://github.com/netbox-community/netbox/issues/3279) - Reset the PostgreSQL sequence for Tag and TaggedItem IDs
* [#3283](https://github.com/netbox-community/netbox/issues/3283) - Fix rack group assignment on PowerFeed CSV import
* [#3290](https://github.com/netbox-community/netbox/issues/3290) - Fix server error when viewing cascaded PDUs
* [#3292](https://github.com/netbox-community/netbox/issues/3292) - Ignore empty URL query parameters
---
# v2.6.0 (2019-06-20)
## New Features
### Power Panels and Feeds ([#54](https://github.com/netbox-community/netbox/issues/54))
NetBox now supports power circuit modeling via two new models: power panels and power feeds. Power feeds are terminated
to power panels and are optionally associated with individual racks. Each power feed defines a supply type (AC/DC),
amperage, voltage, and phase. A power port can be connected directly to a power feed, but a power feed may have only one
power port connected to it.
Additionally, the power port model, which represents a device's power input, has been extended to include fields
denoting maximum and allocated draw, in volt-amperes. This allows a device (e.g. a PDU) to calculate its total load
compared to its connected power feed.
### Caching ([#2647](https://github.com/netbox-community/netbox/issues/2647))
To improve performance, NetBox now supports caching for most object and list views. Caching is implemented using Redis,
which is now a required dependency. (Previously, Redis was required only if webhooks were enabled.)
A new configuration parameter is available to control the cache timeout:
```
# Cache timeout (in seconds)
CACHE_TIMEOUT = 900
```
### View Permissions ([#323](https://github.com/netbox-community/netbox/issues/323))
Django 2.1 introduced the ability to enforce view-only permissions for different object types. NetBox now enforces
these by default. You can grant view permission to a user or group by assigning the "can view" permission for the
desired object(s).
To exempt certain object types from the enforcement of view permissions, so that any user (including anonymous users)
can view them, add them to the new `EXEMPT_VIEW_PERMISSIONS` setting in `configuration.py`:
```
EXEMPT_VIEW_PERMISSIONS = [
'dcim.site',
'ipam.prefix',
]
```
To exclude _all_ objects, effectively disabling view permissions and restoring pre-v2.6 behavior, set:
```
EXEMPT_VIEW_PERMISSIONS = ['*']
```
### Custom Links ([#969](https://github.com/netbox-community/netbox/issues/969))
Custom links are created under the admin UI and will be displayed on each object of the selected type. Link text and
URLs can be formed from Jinja2 template code, with the viewed object passed as context data. For example, to link to an
external NMS from the device view, you might create a custom link with the following URL:
```
https://nms.example.com/nodes/?name={{ obj.name }}
```
Custom links appear as buttons at the top of the object view. Grouped links will render as a dropdown menu beneath a
single button.
### Prometheus Metrics ([#3104](https://github.com/netbox-community/netbox/issues/3104))
NetBox now supports exposing native Prometheus metrics from the application. [Prometheus](https://prometheus.io/) is a
popular time series metric platform used for monitoring. Metric exposition can be toggled with the `METRICS_ENABLED`
configuration setting; it is not enabled by default. NetBox exposes metrics at the `/metrics` HTTP endpoint, e.g.
`https://netbox.local/metrics`.
NetBox makes use of the [django-prometheus](https://github.com/korfuri/django-prometheus) library to export a number of
different types of metrics, including:
* Per model insert, update, and delete counters
* Per view request counters
* Per view request latency histograms
* Request body size histograms
* Response body size histograms
* Response code counters
* Database connection, execution, and error counters
* Cache hit, miss, and invalidation counters
* Django middleware latency histograms
* Other Django related metadata metrics
For the exhaustive list of exposed metrics, visit the `/metrics` endpoint on your NetBox instance. See the documentation
for more details on using Prometheus metrics in NetBox.
## Changes
### New Dependency: Redis
[Redis](https://redis.io/) is an in-memory data store similar to memcached. While Redis has been an optional component
of NetBox since the introduction of webhooks in version 2.4, it is now required to support NetBox's new caching
functionality (as well as other planned features). Redis can be installed via your platform's package manager: for
example, `sudo apt-get install redis-server` on Ubuntu or `sudo yum install redis` on CentOS.
The Redis database is configured using a configuration setting similar to `DATABASE` in `configuration.py`:
```
REDIS = {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 0,
'CACHE_DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
```
Note that if you were using these settings in a prior release with webhooks, the `DATABASE` setting remains the same but
an additional `CACHE_DATABASE` setting has been added with a default value of 1 to support the caching backend. The
`DATABASE` setting will be renamed in a future release of NetBox to better relay the meaning of the setting. It is
highly recommended to keep the webhook and cache databases seperate. Using the same database number for both may result
in webhook processing data being lost during cache flushing events.
### API Support for Specifying Related Objects by Attributes([#3077](https://github.com/netbox-community/netbox/issues/3077))
Previously, specifying a related object in an API request required knowing the primary key (integer ID) of that object.
For example, when creating a new device, its rack would be specified as an integer:
```
{
"name": "MyNewDevice",
"rack": 123,
...
}
```
The NetBox API now also supports referencing related objects by a set of sufficiently unique attrbiutes. For example, a
rack can be identified by its name and parent site:
```
{
"name": "MyNewDevice",
"rack": {
"site": {
"name": "Equinix DC6"
},
"name": "R204"
},
...
}
```
There is no limit to the depth of nested references. Note that if the provided parameters do not return exactly one
object, a validation error is raised.
### API Device/VM Config Context Included by Default ([#2350](https://github.com/netbox-community/netbox/issues/2350))
The rendered config context for devices and VMs is now included by default in all API results (list and detail views).
Previously, the rendered config context was available only in the detail view for individual objects. Users with large
amounts of context data may observe a performance drop when returning multiple objects. To combat this, in cases where
the rendered config context is not needed, the query parameter `?exclude=config_context` may be appended to the request
URL to exclude the config context data from the API response.
### Changes to Tag Permissions
NetBox now makes use of its own `Tag` model instead of the stock model which ships with django-taggit. This new model
lives in the `extras` app and thus any permissions that you may have configured using "Taggit | Tag" should be changed
to now use "Extras | Tag." Also note that the admin interface for tags has been removed as it was redundant to the
functionality provided by the front end UI.
### CORS_ORIGIN_WHITELIST Requires URI Scheme
If you have the `CORS_ORIGIN_WHITELIST` configuration parameter defined, note that each origin must now incldue a URI
scheme. This change was introuced in django-cors-headers 3.0.
## Enhancements
* [#166](https://github.com/netbox-community/netbox/issues/166) - Add `dns_name` field to IPAddress
* [#524](https://github.com/netbox-community/netbox/issues/524) - Added power utilization graphs to power feeds, devices, and racks
* [#1792](https://github.com/netbox-community/netbox/issues/1792) - Add CustomFieldChoices API endpoint at `/api/extras/_custom_field_choices/`
* [#1863](https://github.com/netbox-community/netbox/issues/1863) - Add child object counts to API representation of organizational objects
* [#2324](https://github.com/netbox-community/netbox/issues/2324) - Add `color` field for tags
* [#2643](https://github.com/netbox-community/netbox/issues/2643) - Add `description` field to console/power components and device bays
* [#2791](https://github.com/netbox-community/netbox/issues/2791) - Add `comments` field for tags
* [#2920](https://github.com/netbox-community/netbox/issues/2920) - Rename Interface `form_factor` to `type` (backward-compatible until v2.7)
* [#2926](https://github.com/netbox-community/netbox/issues/2926) - Add change logging to the Tag model
* [#3038](https://github.com/netbox-community/netbox/issues/3038) - OR logic now used when multiple values of a query filter are passed
* [#3264](https://github.com/netbox-community/netbox/issues/3264) - Annotate changelog retention time on UI
## Bug Fixes
* [#2968](https://github.com/netbox-community/netbox/issues/2968) - Correct API documentation for SerializerMethodFields
* [#3176](https://github.com/netbox-community/netbox/issues/3176) - Add cable trace button for console server ports and power outlets
* [#3231](https://github.com/netbox-community/netbox/issues/3231) - Fixed cosmetic error indicating a missing schema migration
* [#3239](https://github.com/netbox-community/netbox/issues/3239) - Corrected count of tags reported via API
## Bug Fixes From v2.6-beta1
* [#3123](https://github.com/netbox-community/netbox/issues/3123) - Exempt `/metrics` view from authentication
* [#3125](https://github.com/netbox-community/netbox/issues/3125) - Fix exception when viewing PDUs
* [#3126](https://github.com/netbox-community/netbox/issues/3126) - Incorrect calculation of PowerFeed available power
* [#3130](https://github.com/netbox-community/netbox/issues/3130) - Fix exception when creating a new power outlet
* [#3136](https://github.com/netbox-community/netbox/issues/3136) - Add power draw fields to power port creation form
* [#3137](https://github.com/netbox-community/netbox/issues/3137) - Add `power_port` and `feed_leg` fields to power outlet creation form
* [#3140](https://github.com/netbox-community/netbox/issues/3140) - Add bulk edit capability for power outlets and console server ports
* [#3204](https://github.com/netbox-community/netbox/issues/3204) - Fix interface filtering when connecting cables
* [#3207](https://github.com/netbox-community/netbox/issues/3207) - Fix link for connecting interface to rear port
* [#3258](https://github.com/netbox-community/netbox/issues/3258) - Exception raised when creating/viewing a circuit with a non-connected termination
## API Changes
* New API endpoints for power modeling: `/api/dcim/power-panels/` and `/api/dcim/power-feeds/`
* New API endpoint for custom field choices: `/api/extras/_custom_field_choices/`
* ForeignKey fields now accept either the related object PK or a dictionary of attributes describing the related object.
* Organizational objects now include child object counts. For example, the Role serializer includes `prefix_count` and `vlan_count`.
* The `id__in` filter is now deprecated and will be removed in v2.7. (Begin using the `?id=1&id=2` format instead.)
* Added a `description` field for all device components.
* dcim.Device: The devices list endpoint now includes rendered context data.
* dcim.DeviceType: `instance_count` has been renamed to `device_count`.
* dcim.Interface: `form_factor` has been renamed to `type`. Backward compatibility for `form_factor` will be maintained until NetBox v2.7.
* dcim.Interface: The `type` filter has been renamed to `kind`.
* dcim.Site: The `count_*` read-only fields have been renamed to `*_count` for consistency with other objects.
* dcim.Site: Added the `virtualmachine_count` read-only field.
* extras.Tag: Added `color` and `comments` fields to the Tag serializer.
* virtualization.VirtualMachine: The virtual machines list endpoint now includes rendered context data.

View File

@@ -0,0 +1,315 @@
# v2.7.2 (2020-01-21)
## Enhancements
* [#3135](https://github.com/netbox-community/netbox/issues/3135) - Documented power modelling
* [#3842](https://github.com/netbox-community/netbox/issues/3842) - Add 802.11ax interface type
* [#3954](https://github.com/netbox-community/netbox/issues/3954) - Add `device_bays` filter for devices and device types
## Bug Fixes
* [#3721](https://github.com/netbox-community/netbox/issues/3721) - Allow Unicode characters in tag slugs
* [#3923](https://github.com/netbox-community/netbox/issues/3923) - Indicate validation failure when using SSH-style RSA keys
* [#3951](https://github.com/netbox-community/netbox/issues/3951) - Fix exception in webhook worker due to missing constant
* [#3953](https://github.com/netbox-community/netbox/issues/3953) - Fix validation error when creating child devices
* [#3960](https://github.com/netbox-community/netbox/issues/3960) - Fix legacy device status choice
* [#3962](https://github.com/netbox-community/netbox/issues/3962) - Fix display of unnamed devices in rack elevations
* [#3963](https://github.com/netbox-community/netbox/issues/3963) - Restore tooltip for devices in rack elevations
* [#3964](https://github.com/netbox-community/netbox/issues/3964) - Show borders around devices in rack elevations
* [#3965](https://github.com/netbox-community/netbox/issues/3965) - Indicate the presence of "background" devices in rack elevations
* [#3966](https://github.com/netbox-community/netbox/issues/3966) - Fix filtering of device components by region/site
* [#3967](https://github.com/netbox-community/netbox/issues/3967) - Resolve migration of "other" interface type
---
# v2.7.1 (2020-01-16)
## Bug Fixes
* [#3941](https://github.com/netbox-community/netbox/issues/3941) - Fixed exception when attempting to assign IP to interface
* [#3943](https://github.com/netbox-community/netbox/issues/3943) - Prevent rack elevation links from opening new tabs/windows
* [#3944](https://github.com/netbox-community/netbox/issues/3944) - Fix AttributeError exception when viewing prefixes list
---
# v2.7.0 (2020-01-16)
**Note:** This release completely removes the topology map feature ([#2745](https://github.com/netbox-community/netbox/issues/2745)).
**Note:** NetBox v2.7 is the last major release that will support Python 3.5. Beginning with NetBox v2.8, Python 3.6 or
higher will be required.
## New Features
### Enhanced Device Type Import ([#451](https://github.com/netbox-community/netbox/issues/451))
NetBox now supports the import of device types and related component templates using definitions written in YAML or
JSON. For example, the following will create a new device type with four network interfaces, two power ports, and a
console port:
```yaml
manufacturer: Acme
model: Packet Shooter 9000
slug: packet-shooter-9000
u_height: 1
interfaces:
- name: ge-0/0/0
type: 1000base-t
- name: ge-0/0/1
type: 1000base-t
- name: ge-0/0/2
type: 1000base-t
- name: ge-0/0/3
type: 1000base-t
power-ports:
- name: PSU0
- name: PSU1
console-ports:
- name: Console
```
This new functionality replaces the old CSV-based import form, which did not allow for bulk import of component
templates.
### Bulk Import of Device Components ([#822](https://github.com/netbox-community/netbox/issues/822))
Device components such as console ports, power ports, and interfaces can now be imported in bulk to multiple devices in
CSV format. Here's an example showing the bulk import of interfaces to several devices:
```
device,name,type
Switch1,Vlan100,Virtual
Switch1,Vlan200,Virtual
Switch2,Vlan100,Virtual
Switch2,Vlan200,Virtual
```
The import form for each type of device component is available under the "Devices" item in the navigation menu.
### External File Storage ([#1814](https://github.com/netbox-community/netbox/issues/1814))
In prior releases, the only option for storing uploaded files (e.g. image attachments) was to save them to the local
filesystem on the NetBox server. This release introduces support for several remote storage backends provided by the
[`django-storages`](https://django-storages.readthedocs.io/en/stable/) library. These include:
* Amazon S3
* ApacheLibcloud
* Azure Storage
* netbox-community Spaces
* Dropbox
* FTP
* Google Cloud Storage
* SFTP
To enable remote file storage, first install the `django-storages` package:
```
pip install django-storages
```
Then, set the appropriate storage backend and its configuration in `configuration.py`. Here's an example using Amazon
S3:
```python
STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage'
STORAGE_CONFIG = {
'AWS_ACCESS_KEY_ID': '<Key>',
'AWS_SECRET_ACCESS_KEY': '<Secret>',
'AWS_STORAGE_BUCKET_NAME': 'netbox',
'AWS_S3_REGION_NAME': 'eu-west-1',
}
```
Thanks to [@steffann](https://github.com/steffann) for contributing this work!
### Rack Elevations Rendered via SVG ([#2248](https://github.com/netbox-community/netbox/issues/2248))
NetBox v2.7 introduces a new method of rendering rack elevations as an
[SVG image](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) via a REST API endpoint. This replaces the prior
method of rendering elevations using pure HTML and CSS, which was cumbersome and had several shortcomings. Rendering
rack elevations as SVG images via the REST API allows users to retrieve and make use of the drawings in their own
tooling. This also opens the door to other feature requests related to rack elevations in the NetBox backlog.
This feature implements a new REST API endpoint:
```
/api/dcim/racks/<id>/elevation/
```
By default, this endpoint returns a paginated JSON response representing each rack unit in the given elevation. This is
the same response returned by the existing rack units detail endpoint at `/api/dcim/racks/<id>/units/`, which will be
removed in v2.8 (see [#3753](https://github.com/netbox-community/netbox/issues/3753)).
To render the elevation as an SVG image, include the `render=svg` query parameter in the request. You may also control
the width and height of the elevation drawing (in pixels) by passing the `unit_width` and `unit_height` parameters. (The
default values for these parameters are 230 and 20, respectively.) Additionally, the `face` parameter may be used to
request either the `front` or `rear` of the elevation. Below is in example request:
```
/api/dcim/racks/<id>/elevation/?render=svg&face=rear&unit_width=300&unit_height=35
```
Thanks to [@hellerve](https://github.com/hellerve) for doing the heavy lifting on this!
## Changes
### Topology Maps Removed ([#2745](https://github.com/netbox-community/netbox/issues/2745))
The topology maps feature has been removed to help focus NetBox development efforts. Please replicate any required data
to another source before upgrading NetBox to v2.7, as any existing topology maps will be deleted.
### Supervisor Replaced with systemd ([#2902](https://github.com/netbox-community/netbox/issues/2902))
The NetBox [installation documentation](https://netbox.readthedocs.io/en/stable/installation/) has been updated to
provide instructions for managing the WSGI and RQ services using systemd instead of supervisor. This removes the need to
install supervisor and simplifies administration of the processes.
### Redis Configuration ([#3282](https://github.com/netbox-community/netbox/issues/3282))
NetBox v2.6 introduced request caching and added the `CACHE_DATABASE` option to the existing `REDIS` database
configuration parameter. This did not, however, allow for using two different Redis connections for the separate caching
and webhook queuing functions. This release modifies the `REDIS` parameter to accept two discrete subsections named
`webhooks` and `caching`. This requires modification of the `REDIS` parameter in `configuration.py` as follows:
Old Redis configuration:
```python
REDIS = {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 0,
'CACHE_DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
```
New Redis configuration:
```python
REDIS = {
'webhooks': {
'HOST': 'redis.example.com',
'PORT': 1234,
'PASSWORD': 'foobar',
'DATABASE': 0,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
}
```
Note that the `CACHE_DATABASE` parameter has been removed and the connection settings have been duplicated for both
`webhooks` and `caching`. This allows the user to make use of separate Redis instances if desired. It is fine to use the
same Redis service for both functions, although the database identifiers should be different.
### WEBHOOKS_ENABLED Configuration Setting Removed ([#3408](https://github.com/netbox-community/netbox/issues/3408))
As `django-rq` is now a required library, NetBox assumes that the RQ worker process is running. The installation and
upgrade documentation has been updated to reflect this, and the `WEBHOOKS_ENABLED` configuration parameter is no longer
used. Please ensure that both the NetBox WSGI service and the RQ worker process are running on all production
installations.
### API Choice Fields Now Use String Values ([#3569](https://github.com/netbox-community/netbox/issues/3569))
NetBox's REST API presents fields which reference a particular choice as a dictionary with two keys: `value` and
`label`. In previous versions, `value` was an integer which represented a particular choice in the database. This has
been changed to a more human-friendly "slug" string, which is essentially a simplified version of the choice's `label`.
For example, The site model's `status` field was previously represented as:
```json
"status": {
"value": 1,
"label": "Active"
},
```
In NetBox v2.7, it now looks like this:
```json
"status": {
"value": "active",
"label": "Active",
"id": 1
},
```
This change allows for much more intuitive representation and manipulation of values, and removes the need for API
consumers to maintain local mappings of static integer values.
Note that that all v2.7 releases will continue to accept the legacy integer values in write requests (`POST`, `PUT`, and
`PATCH`) to maintain backward compatibility. Additionally, the legacy numeric identifier is conveyed in the `id` field
for convenient reference as consumers adopt to the new string values. This behavior will be discontinued in NetBox v2.8.
## Enhancements
* [#33](https://github.com/netbox-community/netbox/issues/33) - Add ability to clone objects (pre-populate form fields)
* [#648](https://github.com/netbox-community/netbox/issues/648) - Pre-populate form fields when selecting "create and
add another"
* [#792](https://github.com/netbox-community/netbox/issues/792) - Add power port and power outlet types
* [#1865](https://github.com/netbox-community/netbox/issues/1865) - Add console port and console server port types
* [#2669](https://github.com/netbox-community/netbox/issues/2669) - Relax uniqueness constraint on device and VM names
* [#2902](https://github.com/netbox-community/netbox/issues/2902) - Replace `supervisord` with `systemd`
* [#3455](https://github.com/netbox-community/netbox/issues/3455) - Add tenant assignment to virtual machine clusters
* [#3520](https://github.com/netbox-community/netbox/issues/3520) - Add Jinja2 template support for graphs
* [#3525](https://github.com/netbox-community/netbox/issues/3525) - Enable IP address filtering using multiple address
parameters
* [#3564](https://github.com/netbox-community/netbox/issues/3564) - Add list views for all device components
* [#3538](https://github.com/netbox-community/netbox/issues/3538) - Introduce a REST API endpoint for executing custom
scripts
* [#3655](https://github.com/netbox-community/netbox/issues/3655) - Add `description` field to organizational models
* [#3664](https://github.com/netbox-community/netbox/issues/3664) - Enable applying configuration contexts by tags
* [#3706](https://github.com/netbox-community/netbox/issues/3706) - Increase `available_power` maximum value on
PowerFeed
* [#3731](https://github.com/netbox-community/netbox/issues/3731) - Change Graph.type to a ContentType foreign key field
* [#3801](https://github.com/netbox-community/netbox/issues/3801) - Use YAML for export of device types
## Bug Fixes
* [#3830](https://github.com/netbox-community/netbox/issues/3830) - Ensure deterministic ordering for all models
* [#3900](https://github.com/netbox-community/netbox/issues/3900) - Fix exception when deleting device types
* [#3914](https://github.com/netbox-community/netbox/issues/3914) - Fix interface filter field when unauthenticated
* [#3919](https://github.com/netbox-community/netbox/issues/3919) - Fix utilization graph extending out of bounds when
utilization > 100%
* [#3927](https://github.com/netbox-community/netbox/issues/3927) - Fix exception when deleting devices with secrets
assigned
* [#3930](https://github.com/netbox-community/netbox/issues/3930) - Fix API rendering of the `family` field for
aggregates
## Bug Fixes (From Beta)
* [#3868](https://github.com/netbox-community/netbox/issues/3868) - Fix creation of interfaces for virtual machines
* [#3878](https://github.com/netbox-community/netbox/issues/3878) - Fix database migration for cable status field
## API Changes
* Choice fields now use human-friendly strings for their values instead of integers (see
[#3569](https://github.com/netbox-community/netbox/issues/3569)).
* Introduced the `/api/extras/scripts/` endpoint for retrieving and executing custom scripts
* circuits.CircuitType: Added field `description`
* dcim.ConsolePort: Added field `type`
* dcim.ConsolePortTemplate: Added field `type`
* dcim.ConsoleServerPort: Added field `type`
* dcim.ConsoleServerPortTemplate: Added field `type`
* dcim.DeviceRole: Added field `description`
* dcim.PowerPort: Added field `type`
* dcim.PowerPortTemplate: Added field `type`
* dcim.PowerOutlet: Added field `type`
* dcim.PowerOutletTemplate: Added field `type`
* dcim.RackRole: Added field `description`
* extras.Graph: Added field `template_language` (to indicate `django` or `jinja2`)
* extras.Graph: The `type` field has been changed to a content type foreign key. Models are specified as
`<app>.<model>`; e.g. `dcim.site`.
* ipam.Role: Added field `description`
* secrets.SecretRole: Added field `description`
* virtualization.Cluster: Added field `tenant`

View File

@@ -12,6 +12,7 @@ pages:
- 4. LDAP (Optional): 'installation/4-ldap.md'
- Upgrading NetBox: 'installation/upgrading.md'
- Migrating to Python3: 'installation/migrating-to-python3.md'
- Migrating to systemd: 'installation/migrating-to-systemd.md'
- Configuration:
- Configuring NetBox: 'configuration/index.md'
- Required Settings: 'configuration/required-settings.md'
@@ -24,20 +25,24 @@ pages:
- Virtual Machines: 'core-functionality/virtual-machines.md'
- Services: 'core-functionality/services.md'
- Circuits: 'core-functionality/circuits.md'
- Power: 'core-functionality/power.md'
- Secrets: 'core-functionality/secrets.md'
- Tenancy: 'core-functionality/tenancy.md'
- Additional Features:
- Tags: 'additional-features/tags.md'
- Custom Fields: 'additional-features/custom-fields.md'
- Caching: 'additional-features/caching.md'
- Change Logging: 'additional-features/change-logging.md'
- Context Data: 'additional-features/context-data.md'
- Custom Fields: 'additional-features/custom-fields.md'
- Custom Links: 'additional-features/custom-links.md'
- Custom Scripts: 'additional-features/custom-scripts.md'
- Export Templates: 'additional-features/export-templates.md'
- Graphs: 'additional-features/graphs.md'
- Topology Maps: 'additional-features/topology-maps.md'
- Reports: 'additional-features/reports.md'
- Webhooks: 'additional-features/webhooks.md'
- Change Logging: 'additional-features/change-logging.md'
- Caching: 'additional-features/caching.md'
- NAPALM: 'additional-features/napalm.md'
- Prometheus Metrics: 'additional-features/prometheus-metrics.md'
- Reports: 'additional-features/reports.md'
- Tags: 'additional-features/tags.md'
- Topology Maps: 'additional-features/topology-maps.md'
- Webhooks: 'additional-features/webhooks.md'
- Administration:
- Replicating NetBox: 'administration/replicating-netbox.md'
- NetBox Shell: 'administration/netbox-shell.md'
@@ -52,6 +57,26 @@ pages:
- Utility Views: 'development/utility-views.md'
- Extending Models: 'development/extending-models.md'
- Release Checklist: 'development/release-checklist.md'
- Squashing Migrations: 'development/squashing-migrations.md'
- Release Notes:
- Version 2.7: 'release-notes/version-2.7.md'
- Version 2.6: 'release-notes/version-2.6.md'
- Version 2.5: 'release-notes/version-2.5.md'
- Version 2.4: 'release-notes/version-2.4.md'
- Version 2.3: 'release-notes/version-2.3.md'
- Version 2.2: 'release-notes/version-2.2.md'
- Version 2.1: 'release-notes/version-2.1.md'
- Version 2.0: 'release-notes/version-2.0.md'
- Version 1.9: 'release-notes/version-1.9.md'
- Version 1.8: 'release-notes/version-1.8.md'
- Version 1.7: 'release-notes/version-1.7.md'
- Version 1.6: 'release-notes/version-1.6.md'
- Version 1.5: 'release-notes/version-1.5.md'
- Version 1.4: 'release-notes/version-1.4.md'
- Version 1.3: 'release-notes/version-1.3.md'
- Version 1.2: 'release-notes/version-1.2.md'
- Version 1.1: 'release-notes/version-1.1.md'
- Version 1.0: 'release-notes/version-1.0.md'
markdown_extensions:
- admonition:

View File

@@ -1,7 +1,7 @@
from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from circuits.constants import CIRCUIT_STATUS_CHOICES
from circuits.choices import CircuitStatusChoices
from circuits.models import Provider, Circuit, CircuitTermination, CircuitType
from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer
from dcim.api.serializers import ConnectedEndpointSerializer
@@ -36,12 +36,12 @@ class CircuitTypeSerializer(ValidatedModelSerializer):
class Meta:
model = CircuitType
fields = ['id', 'name', 'slug', 'circuit_count']
fields = ['id', 'name', 'slug', 'description', 'circuit_count']
class CircuitSerializer(TaggitSerializer, CustomFieldModelSerializer):
provider = NestedProviderSerializer()
status = ChoiceField(choices=CIRCUIT_STATUS_CHOICES, required=False)
status = ChoiceField(choices=CircuitStatusChoices, required=False)
type = NestedCircuitTypeSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False)

View File

@@ -7,7 +7,7 @@ from circuits import filters
from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
from extras.api.serializers import RenderedGraphSerializer
from extras.api.views import CustomFieldModelViewSet
from extras.models import Graph, GRAPH_TYPE_PROVIDER
from extras.models import Graph
from utilities.api import FieldChoicesViewSet, ModelViewSet
from . import serializers
@@ -18,8 +18,8 @@ from . import serializers
class CircuitsFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(Circuit, ['status']),
(CircuitTermination, ['term_side']),
(serializers.CircuitSerializer, ['status']),
(serializers.CircuitTerminationSerializer, ['term_side']),
)
@@ -32,7 +32,7 @@ class ProviderViewSet(CustomFieldModelViewSet):
circuit_count=Count('circuits')
)
serializer_class = serializers.ProviderSerializer
filterset_class = filters.ProviderFilter
filterset_class = filters.ProviderFilterSet
@action(detail=True)
def graphs(self, request, pk):
@@ -40,7 +40,7 @@ class ProviderViewSet(CustomFieldModelViewSet):
A convenience method for rendering graphs for a particular provider.
"""
provider = get_object_or_404(Provider, pk=pk)
queryset = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER)
queryset = Graph.objects.filter(type__model='provider')
serializer = RenderedGraphSerializer(queryset, many=True, context={'graphed_object': provider})
return Response(serializer.data)
@@ -54,7 +54,7 @@ class CircuitTypeViewSet(ModelViewSet):
circuit_count=Count('circuits')
)
serializer_class = serializers.CircuitTypeSerializer
filterset_class = filters.CircuitTypeFilter
filterset_class = filters.CircuitTypeFilterSet
#
@@ -64,7 +64,7 @@ class CircuitTypeViewSet(ModelViewSet):
class CircuitViewSet(CustomFieldModelViewSet):
queryset = Circuit.objects.prefetch_related('type', 'tenant', 'provider').prefetch_related('tags')
serializer_class = serializers.CircuitSerializer
filterset_class = filters.CircuitFilter
filterset_class = filters.CircuitFilterSet
#
@@ -76,4 +76,4 @@ class CircuitTerminationViewSet(ModelViewSet):
'circuit', 'site', 'connected_endpoint__device', 'cable'
)
serializer_class = serializers.CircuitTerminationSerializer
filterset_class = filters.CircuitTerminationFilter
filterset_class = filters.CircuitTerminationFilterSet

View File

@@ -0,0 +1,48 @@
from utilities.choices import ChoiceSet
#
# Circuits
#
class CircuitStatusChoices(ChoiceSet):
STATUS_DEPROVISIONING = 'deprovisioning'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_PROVISIONING = 'provisioning'
STATUS_OFFLINE = 'offline'
STATUS_DECOMMISSIONED = 'decommissioned'
CHOICES = (
(STATUS_PLANNED, 'Planned'),
(STATUS_PROVISIONING, 'Provisioning'),
(STATUS_ACTIVE, 'Active'),
(STATUS_OFFLINE, 'Offline'),
(STATUS_DEPROVISIONING, 'Deprovisioning'),
(STATUS_DECOMMISSIONED, 'Decommissioned'),
)
LEGACY_MAP = {
STATUS_DEPROVISIONING: 0,
STATUS_ACTIVE: 1,
STATUS_PLANNED: 2,
STATUS_PROVISIONING: 3,
STATUS_OFFLINE: 4,
STATUS_DECOMMISSIONED: 5,
}
#
# CircuitTerminations
#
class CircuitTerminationSideChoices(ChoiceSet):
SIDE_A = 'A'
SIDE_Z = 'Z'
CHOICES = (
(SIDE_A, 'A'),
(SIDE_Z, 'Z')
)

View File

@@ -1,24 +0,0 @@
# Circuit statuses
CIRCUIT_STATUS_DEPROVISIONING = 0
CIRCUIT_STATUS_ACTIVE = 1
CIRCUIT_STATUS_PLANNED = 2
CIRCUIT_STATUS_PROVISIONING = 3
CIRCUIT_STATUS_OFFLINE = 4
CIRCUIT_STATUS_DECOMMISSIONED = 5
CIRCUIT_STATUS_CHOICES = [
[CIRCUIT_STATUS_PLANNED, 'Planned'],
[CIRCUIT_STATUS_PROVISIONING, 'Provisioning'],
[CIRCUIT_STATUS_ACTIVE, 'Active'],
[CIRCUIT_STATUS_OFFLINE, 'Offline'],
[CIRCUIT_STATUS_DEPROVISIONING, 'Deprovisioning'],
[CIRCUIT_STATUS_DECOMMISSIONED, 'Decommissioned'],
]
# CircuitTermination sides
TERM_SIDE_A = 'A'
TERM_SIDE_Z = 'Z'
TERM_SIDE_CHOICES = (
(TERM_SIDE_A, 'A'),
(TERM_SIDE_Z, 'Z'),
)

View File

@@ -2,14 +2,21 @@ import django_filters
from django.db.models import Q
from dcim.models import Region, Site
from extras.filters import CustomFieldFilterSet
from tenancy.filtersets import TenancyFilterSet
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
from .constants import CIRCUIT_STATUS_CHOICES
from .models import Provider, Circuit, CircuitTermination, CircuitType
from .choices import *
from .models import Circuit, CircuitTermination, CircuitType, Provider
__all__ = (
'CircuitFilterSet',
'CircuitTerminationFilterSet',
'CircuitTypeFilterSet',
'ProviderFilterSet',
)
class ProviderFilter(CustomFieldFilterSet):
class ProviderFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -18,6 +25,17 @@ class ProviderFilter(CustomFieldFilterSet):
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='circuits__terminations__site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='circuits__terminations__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='circuits__terminations__site',
queryset=Site.objects.all(),
@@ -47,14 +65,14 @@ class ProviderFilter(CustomFieldFilterSet):
)
class CircuitTypeFilter(NameSlugSearchFilterSet):
class CircuitTypeFilterSet(NameSlugSearchFilterSet):
class Meta:
model = CircuitType
fields = ['id', 'name', 'slug']
class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet):
class CircuitFilterSet(CustomFieldFilterSet, TenancyFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -84,7 +102,7 @@ class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet):
label='Circuit type (slug)',
)
status = django_filters.MultipleChoiceFilter(
choices=CIRCUIT_STATUS_CHOICES,
choices=CircuitStatusChoices,
null_value=None
)
site_id = django_filters.ModelMultipleChoiceFilter(
@@ -128,7 +146,7 @@ class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet):
).distinct()
class CircuitTerminationFilter(django_filters.FilterSet):
class CircuitTerminationFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',

View File

@@ -1,26 +0,0 @@
[
{
"model": "circuits.circuittype",
"pk": 1,
"fields": {
"name": "Internet",
"slug": "internet"
}
},
{
"model": "circuits.circuittype",
"pk": 2,
"fields": {
"name": "Private WAN",
"slug": "private-wan"
}
},
{
"model": "circuits.circuittype",
"pk": 3,
"fields": {
"name": "Out-of-Band",
"slug": "out-of-band"
}
}
]

View File

@@ -1,16 +1,15 @@
from django import forms
from taggit.forms import TagField
from dcim.models import Site
from dcim.models import Region, Site
from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
from tenancy.forms import TenancyForm
from tenancy.forms import TenancyFilterForm
from tenancy.forms import TenancyFilterForm, TenancyForm
from tenancy.models import Tenant
from utilities.forms import (
APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, CommentField, CSVChoiceField,
FilterChoiceField, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple
DatePicker, FilterChoiceField, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple
)
from .constants import CIRCUIT_STATUS_CHOICES
from .choices import CircuitStatusChoices
from .models import Circuit, CircuitTermination, CircuitType, Provider
@@ -105,6 +104,18 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldFilterForm):
required=False,
label='Search'
)
region = FilterChoiceField(
queryset=Region.objects.all(),
to_field_name='slug',
required=False,
widget=APISelectMultiple(
api_url="/api/dcim/regions/",
value_field="slug",
filter_for={
'site': 'region'
}
)
)
site = FilterChoiceField(
queryset=Site.objects.all(),
to_field_name='slug',
@@ -129,7 +140,7 @@ class CircuitTypeForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = CircuitType
fields = [
'name', 'slug',
'name', 'slug', 'description',
]
@@ -162,7 +173,6 @@ class CircuitForm(BootstrapMixin, TenancyForm, CustomFieldForm):
]
help_texts = {
'cid': "Unique circuit ID",
'install_date': "Format: YYYY-MM-DD",
'commit_rate': "Committed rate",
}
widgets = {
@@ -173,7 +183,7 @@ class CircuitForm(BootstrapMixin, TenancyForm, CustomFieldForm):
api_url="/api/circuits/circuit-types/"
),
'status': StaticSelect2(),
'install_date': DatePicker(),
}
@@ -195,7 +205,7 @@ class CircuitCSVForm(forms.ModelForm):
}
)
status = CSVChoiceField(
choices=CIRCUIT_STATUS_CHOICES,
choices=CircuitStatusChoices,
required=False,
help_text='Operational status'
)
@@ -236,7 +246,7 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
)
)
status = forms.ChoiceField(
choices=add_blank_choice(CIRCUIT_STATUS_CHOICES),
choices=add_blank_choice(CircuitStatusChoices),
required=False,
initial='',
widget=StaticSelect2()
@@ -257,7 +267,8 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
required=False
)
comments = CommentField(
widget=SmallTextarea
widget=SmallTextarea,
label='Comments'
)
class Meta:
@@ -268,7 +279,9 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Circuit
field_order = ['q', 'type', 'provider', 'status', 'site', 'tenant_group', 'tenant', 'commit_rate']
field_order = [
'q', 'type', 'provider', 'status', 'region', 'site', 'tenant_group', 'tenant', 'commit_rate',
]
q = forms.CharField(
required=False,
label='Search'
@@ -290,10 +303,22 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm
)
)
status = forms.MultipleChoiceField(
choices=CIRCUIT_STATUS_CHOICES,
choices=CircuitStatusChoices,
required=False,
widget=StaticSelect2Multiple()
)
region = forms.ModelMultipleChoiceField(
queryset=Region.objects.all(),
to_field_name='slug',
required=False,
widget=APISelectMultiple(
api_url="/api/dcim/regions/",
value_field="slug",
filter_for={
'site': 'region'
}
)
)
site = FilterChoiceField(
queryset=Site.objects.all(),
to_field_name='slug',

View File

@@ -1,40 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-07-31 02:25
import dcim.fields
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
import dcim.fields
def circuits_to_terms(apps, schema_editor):
Circuit = apps.get_model('circuits', 'Circuit')
CircuitTermination = apps.get_model('circuits', 'CircuitTermination')
for c in Circuit.objects.all():
CircuitTermination(
circuit=c,
term_side=b'A',
site=c.site,
interface=c.interface,
port_speed=c.port_speed,
upstream_speed=c.upstream_speed,
xconnect_id=c.xconnect_id,
pp_info=c.pp_info,
).save()
class Migration(migrations.Migration):
replaces = [('circuits', '0001_initial'), ('circuits', '0002_auto_20160622_1821'), ('circuits', '0003_provider_32bit_asn_support'), ('circuits', '0004_circuit_add_tenant'), ('circuits', '0005_circuit_add_upstream_speed'), ('circuits', '0006_terminations'), ('circuits', '0007_circuit_add_description'), ('circuits', '0008_circuittermination_interface_protect_on_delete'), ('circuits', '0009_unicode_literals'), ('circuits', '0010_circuit_status')]
replaces = [('circuits', '0001_initial'), ('circuits', '0002_auto_20160622_1821'), ('circuits', '0003_provider_32bit_asn_support'), ('circuits', '0004_circuit_add_tenant'), ('circuits', '0005_circuit_add_upstream_speed'), ('circuits', '0006_terminations')]
dependencies = [
('tenancy', '0001_initial'),
('dcim', '0001_initial'),
('dcim', '0022_color_names_to_rgb'),
('tenancy', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Provider',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=50, unique=True)),
('slug', models.SlugField(unique=True)),
('asn', dcim.fields.ASNField(blank=True, null=True, verbose_name='ASN')),
('account', models.CharField(blank=True, max_length=30, verbose_name='Account number')),
('portal_url', models.URLField(blank=True, verbose_name='Portal')),
('noc_contact', models.TextField(blank=True, verbose_name='NOC contact')),
('admin_contact', models.TextField(blank=True, verbose_name='Admin contact')),
('comments', models.TextField(blank=True)),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='CircuitType',
fields=[
@@ -46,49 +42,93 @@ class Migration(migrations.Migration):
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Provider',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=50, unique=True)),
('slug', models.SlugField(unique=True)),
('asn', dcim.fields.ASNField(blank=True, null=True, verbose_name=b'ASN')),
('account', models.CharField(blank=True, max_length=30, verbose_name=b'Account number')),
('portal_url', models.URLField(blank=True, verbose_name=b'Portal')),
('noc_contact', models.TextField(blank=True, verbose_name=b'NOC contact')),
('admin_contact', models.TextField(blank=True, verbose_name=b'Admin contact')),
('comments', models.TextField(blank=True)),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Circuit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('cid', models.CharField(max_length=50, verbose_name='Circuit ID')),
('install_date', models.DateField(blank=True, null=True, verbose_name='Date installed')),
('commit_rate', models.PositiveIntegerField(blank=True, null=True, verbose_name='Commit rate (Kbps)')),
('cid', models.CharField(max_length=50, verbose_name=b'Circuit ID')),
('install_date', models.DateField(blank=True, null=True, verbose_name=b'Date installed')),
('port_speed', models.PositiveIntegerField(verbose_name=b'Port speed (Kbps)')),
('commit_rate', models.PositiveIntegerField(blank=True, null=True, verbose_name=b'Commit rate (Kbps)')),
('xconnect_id', models.CharField(blank=True, max_length=50, verbose_name=b'Cross-connect ID')),
('pp_info', models.CharField(blank=True, max_length=100, verbose_name=b'Patch panel/port(s)')),
('comments', models.TextField(blank=True)),
('interface', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='circuit', to='dcim.Interface')),
('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.Provider')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='dcim.Site')),
('type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.CircuitType')),
('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='tenancy.Tenant')),
('description', models.CharField(blank=True, max_length=100)),
('status', models.PositiveSmallIntegerField(choices=[[2, 'Planned'], [3, 'Provisioning'], [1, 'Active'], [4, 'Offline'], [0, 'Deprovisioning'], [5, 'Decommissioned']], default=1))
('upstream_speed', models.PositiveIntegerField(blank=True, help_text=b'Upstream speed, if different from port speed', null=True, verbose_name=b'Upstream speed (Kbps)')),
],
options={
'ordering': ['provider', 'cid'],
'unique_together': {('provider', 'cid')},
},
),
migrations.AlterUniqueTogether(
name='circuit',
unique_together=set([('provider', 'cid')]),
),
migrations.CreateModel(
name='CircuitTermination',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('term_side', models.CharField(choices=[('A', 'A'), ('Z', 'Z')], max_length=1, verbose_name='Termination')),
('port_speed', models.PositiveIntegerField(verbose_name='Port speed (Kbps)')),
('upstream_speed', models.PositiveIntegerField(blank=True, help_text='Upstream speed, if different from port speed', null=True, verbose_name='Upstream speed (Kbps)')),
('xconnect_id', models.CharField(blank=True, max_length=50, verbose_name='Cross-connect ID')),
('pp_info', models.CharField(blank=True, max_length=100, verbose_name='Patch panel/port(s)')),
('term_side', models.CharField(choices=[(b'A', b'A'), (b'Z', b'Z')], max_length=1, verbose_name='Termination')),
('port_speed', models.PositiveIntegerField(verbose_name=b'Port speed (Kbps)')),
('upstream_speed', models.PositiveIntegerField(blank=True, help_text=b'Upstream speed, if different from port speed', null=True, verbose_name=b'Upstream speed (Kbps)')),
('xconnect_id', models.CharField(blank=True, max_length=50, verbose_name=b'Cross-connect ID')),
('pp_info', models.CharField(blank=True, max_length=100, verbose_name=b'Patch panel/port(s)')),
('circuit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.Circuit')),
('interface', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_termination', to='dcim.Interface')),
('interface', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='circuit_termination', to='dcim.Interface')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='dcim.Site')),
],
options={
'ordering': ['circuit', 'term_side'],
'unique_together': {('circuit', 'term_side')},
},
),
migrations.AlterUniqueTogether(
name='circuittermination',
unique_together=set([('circuit', 'term_side')]),
migrations.RunPython(
code=circuits_to_terms,
),
migrations.RemoveField(
model_name='circuit',
name='interface',
),
migrations.RemoveField(
model_name='circuit',
name='port_speed',
),
migrations.RemoveField(
model_name='circuit',
name='pp_info',
),
migrations.RemoveField(
model_name='circuit',
name='site',
),
migrations.RemoveField(
model_name='circuit',
name='upstream_speed',
),
migrations.RemoveField(
model_name='circuit',
name='xconnect_id',
),
]

View File

@@ -0,0 +1,254 @@
import sys
import django.db.models.deletion
import taggit.managers
from django.db import migrations, models
import dcim.fields
CONNECTION_STATUS_CONNECTED = True
CIRCUIT_STATUS_CHOICES = (
(0, 'deprovisioning'),
(1, 'active'),
(2, 'planned'),
(3, 'provisioning'),
(4, 'offline'),
(5, 'decommissioned')
)
def circuit_terminations_to_cables(apps, schema_editor):
"""
Copy all existing CircuitTermination Interface associations as Cables
"""
ContentType = apps.get_model('contenttypes', 'ContentType')
CircuitTermination = apps.get_model('circuits', 'CircuitTermination')
Interface = apps.get_model('dcim', 'Interface')
Cable = apps.get_model('dcim', 'Cable')
# Load content types
circuittermination_type = ContentType.objects.get_for_model(CircuitTermination)
interface_type = ContentType.objects.get_for_model(Interface)
# Create a new Cable instance from each console connection
if 'test' not in sys.argv:
print("\n Adding circuit terminations... ", end='', flush=True)
for circuittermination in CircuitTermination.objects.filter(interface__isnull=False):
# Create the new Cable
cable = Cable.objects.create(
termination_a_type=circuittermination_type,
termination_a_id=circuittermination.id,
termination_b_type=interface_type,
termination_b_id=circuittermination.interface_id,
status=CONNECTION_STATUS_CONNECTED
)
# Cache the Cable on its two termination points
CircuitTermination.objects.filter(pk=circuittermination.pk).update(
cable=cable,
connected_endpoint=circuittermination.interface,
connection_status=CONNECTION_STATUS_CONNECTED
)
# Cache the connected Cable on the Interface
Interface.objects.filter(pk=circuittermination.interface_id).update(
cable=cable,
_connected_circuittermination=circuittermination,
connection_status=CONNECTION_STATUS_CONNECTED
)
cable_count = Cable.objects.filter(termination_a_type=circuittermination_type).count()
if 'test' not in sys.argv:
print("{} cables created".format(cable_count))
def circuit_status_to_slug(apps, schema_editor):
Circuit = apps.get_model('circuits', 'Circuit')
for id, slug in CIRCUIT_STATUS_CHOICES:
Circuit.objects.filter(status=str(id)).update(status=slug)
class Migration(migrations.Migration):
replaces = [('circuits', '0007_circuit_add_description'), ('circuits', '0008_circuittermination_interface_protect_on_delete'), ('circuits', '0009_unicode_literals'), ('circuits', '0010_circuit_status'), ('circuits', '0011_tags'), ('circuits', '0012_change_logging'), ('circuits', '0013_cables'), ('circuits', '0014_circuittermination_description'), ('circuits', '0015_custom_tag_models'), ('circuits', '0016_3569_circuit_fields'), ('circuits', '0017_circuittype_description')]
dependencies = [
('circuits', '0006_terminations'),
('extras', '0019_tag_taggeditem'),
('taggit', '0002_auto_20150616_2121'),
('dcim', '0066_cables'),
]
operations = [
migrations.AddField(
model_name='circuit',
name='description',
field=models.CharField(blank=True, max_length=100),
),
migrations.AlterField(
model_name='circuittermination',
name='interface',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_termination', to='dcim.Interface'),
),
migrations.AlterField(
model_name='circuit',
name='cid',
field=models.CharField(max_length=50, verbose_name='Circuit ID'),
),
migrations.AlterField(
model_name='circuit',
name='commit_rate',
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Commit rate (Kbps)'),
),
migrations.AlterField(
model_name='circuit',
name='install_date',
field=models.DateField(blank=True, null=True, verbose_name='Date installed'),
),
migrations.AlterField(
model_name='circuittermination',
name='port_speed',
field=models.PositiveIntegerField(verbose_name='Port speed (Kbps)'),
),
migrations.AlterField(
model_name='circuittermination',
name='pp_info',
field=models.CharField(blank=True, max_length=100, verbose_name='Patch panel/port(s)'),
),
migrations.AlterField(
model_name='circuittermination',
name='term_side',
field=models.CharField(choices=[('A', 'A'), ('Z', 'Z')], max_length=1, verbose_name='Termination'),
),
migrations.AlterField(
model_name='circuittermination',
name='upstream_speed',
field=models.PositiveIntegerField(blank=True, help_text='Upstream speed, if different from port speed', null=True, verbose_name='Upstream speed (Kbps)'),
),
migrations.AlterField(
model_name='circuittermination',
name='xconnect_id',
field=models.CharField(blank=True, max_length=50, verbose_name='Cross-connect ID'),
),
migrations.AlterField(
model_name='provider',
name='account',
field=models.CharField(blank=True, max_length=30, verbose_name='Account number'),
),
migrations.AlterField(
model_name='provider',
name='admin_contact',
field=models.TextField(blank=True, verbose_name='Admin contact'),
),
migrations.AlterField(
model_name='provider',
name='asn',
field=dcim.fields.ASNField(blank=True, null=True, verbose_name='ASN'),
),
migrations.AlterField(
model_name='provider',
name='noc_contact',
field=models.TextField(blank=True, verbose_name='NOC contact'),
),
migrations.AlterField(
model_name='provider',
name='portal_url',
field=models.URLField(blank=True, verbose_name='Portal'),
),
migrations.AddField(
model_name='circuit',
name='status',
field=models.PositiveSmallIntegerField(choices=[[2, 'Planned'], [3, 'Provisioning'], [1, 'Active'], [4, 'Offline'], [0, 'Deprovisioning'], [5, 'Decommissioned']], default=1),
),
migrations.AddField(
model_name='circuit',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='provider',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='circuittype',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='circuittype',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AlterField(
model_name='circuit',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='circuit',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AlterField(
model_name='provider',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='provider',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='circuittermination',
name='connected_endpoint',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.Interface'),
),
migrations.AddField(
model_name='circuittermination',
name='connection_status',
field=models.NullBooleanField(),
),
migrations.AddField(
model_name='circuittermination',
name='cable',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.Cable'),
),
migrations.RunPython(
code=circuit_terminations_to_cables,
),
migrations.RemoveField(
model_name='circuittermination',
name='interface',
),
migrations.AddField(
model_name='circuittermination',
name='description',
field=models.CharField(blank=True, max_length=100),
),
migrations.AlterField(
model_name='circuit',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='provider',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='circuit',
name='status',
field=models.CharField(default='active', max_length=50),
),
migrations.RunPython(
code=circuit_status_to_slug,
),
migrations.AddField(
model_name='circuittype',
name='description',
field=models.CharField(blank=True, max_length=100),
),
]

View File

@@ -3,7 +3,7 @@ import sys
from django.db import migrations, models
import django.db.models.deletion
from dcim.constants import CONNECTION_STATUS_CONNECTED
CONNECTION_STATUS_CONNECTED = True
def circuit_terminations_to_cables(apps, schema_editor):

View File

@@ -0,0 +1,39 @@
from django.db import migrations, models
CIRCUIT_STATUS_CHOICES = (
(0, 'deprovisioning'),
(1, 'active'),
(2, 'planned'),
(3, 'provisioning'),
(4, 'offline'),
(5, 'decommissioned')
)
def circuit_status_to_slug(apps, schema_editor):
Circuit = apps.get_model('circuits', 'Circuit')
for id, slug in CIRCUIT_STATUS_CHOICES:
Circuit.objects.filter(status=str(id)).update(status=slug)
class Migration(migrations.Migration):
atomic = False
dependencies = [
('circuits', '0015_custom_tag_models'),
]
operations = [
# Circuit.status
migrations.AlterField(
model_name='circuit',
name='status',
field=models.CharField(default='active', max_length=50),
),
migrations.RunPython(
code=circuit_status_to_slug
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2019-12-10 18:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('circuits', '0016_3569_circuit_fields'),
]
operations = [
migrations.AddField(
model_name='circuittype',
name='description',
field=models.CharField(blank=True, max_length=100),
),
]

View File

@@ -3,13 +3,21 @@ from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager
from dcim.constants import CONNECTION_STATUS_CHOICES, STATUS_CLASSES
from dcim.constants import CONNECTION_STATUS_CHOICES
from dcim.fields import ASNField
from dcim.models import CableTermination
from extras.models import CustomFieldModel, ObjectChange, TaggedItem
from utilities.models import ChangeLoggedModel
from utilities.utils import serialize_object
from .constants import CIRCUIT_STATUS_ACTIVE, CIRCUIT_STATUS_CHOICES, TERM_SIDE_CHOICES
from .choices import *
__all__ = (
'Circuit',
'CircuitTermination',
'CircuitType',
'Provider',
)
class Provider(ChangeLoggedModel, CustomFieldModel):
@@ -57,7 +65,12 @@ class Provider(ChangeLoggedModel, CustomFieldModel):
tags = TaggableManager(through=TaggedItem)
csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
csv_headers = [
'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
]
clone_fields = [
'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact',
]
class Meta:
ordering = ['name']
@@ -93,8 +106,12 @@ class CircuitType(ChangeLoggedModel):
slug = models.SlugField(
unique=True
)
description = models.CharField(
max_length=100,
blank=True,
)
csv_headers = ['name', 'slug']
csv_headers = ['name', 'slug', 'description']
class Meta:
ordering = ['name']
@@ -109,6 +126,7 @@ class CircuitType(ChangeLoggedModel):
return (
self.name,
self.slug,
self.description,
)
@@ -132,9 +150,10 @@ class Circuit(ChangeLoggedModel, CustomFieldModel):
on_delete=models.PROTECT,
related_name='circuits'
)
status = models.PositiveSmallIntegerField(
choices=CIRCUIT_STATUS_CHOICES,
default=CIRCUIT_STATUS_ACTIVE
status = models.CharField(
max_length=50,
choices=CircuitStatusChoices,
default=CircuitStatusChoices.STATUS_ACTIVE
)
tenant = models.ForeignKey(
to='tenancy.Tenant',
@@ -170,6 +189,18 @@ class Circuit(ChangeLoggedModel, CustomFieldModel):
csv_headers = [
'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
]
clone_fields = [
'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description',
]
STATUS_CLASS_MAP = {
CircuitStatusChoices.STATUS_DEPROVISIONING: 'warning',
CircuitStatusChoices.STATUS_ACTIVE: 'success',
CircuitStatusChoices.STATUS_PLANNED: 'info',
CircuitStatusChoices.STATUS_PROVISIONING: 'primary',
CircuitStatusChoices.STATUS_OFFLINE: 'danger',
CircuitStatusChoices.STATUS_DECOMMISSIONED: 'default',
}
class Meta:
ordering = ['provider', 'cid']
@@ -195,7 +226,7 @@ class Circuit(ChangeLoggedModel, CustomFieldModel):
)
def get_status_class(self):
return STATUS_CLASSES[self.status]
return self.STATUS_CLASS_MAP.get(self.status)
def _get_termination(self, side):
for ct in self.terminations.all():
@@ -220,7 +251,7 @@ class CircuitTermination(CableTermination):
)
term_side = models.CharField(
max_length=1,
choices=TERM_SIDE_CHOICES,
choices=CircuitTerminationSideChoices,
verbose_name='Termination'
)
site = models.ForeignKey(

View File

@@ -1,5 +1,4 @@
import django_tables2 as tables
from django.utils.safestring import mark_safe
from django_tables2.utils import Accessor
from tenancy.tables import COL_TENANT
@@ -11,7 +10,8 @@ CIRCUITTYPE_ACTIONS = """
<i class="fa fa-history"></i>
</a>
{% if perms.circuit.change_circuittype %}
<a href="{% url 'circuits:circuittype_edit' slug=record.slug %}?return_url={{ request.path }}" class="btn btn-xs btn-warning"><i class="glyphicon glyphicon-pencil" aria-hidden="true"></i></a>
<a href="{% url 'circuits:circuittype_edit' slug=record.slug %}?return_url={{ request.path }}"
class="btn btn-xs btn-warning"><i class="glyphicon glyphicon-pencil" aria-hidden="true"></i></a>
{% endif %}
"""
@@ -50,12 +50,14 @@ class CircuitTypeTable(BaseTable):
name = tables.LinkColumn()
circuit_count = tables.Column(verbose_name='Circuits')
actions = tables.TemplateColumn(
template_code=CIRCUITTYPE_ACTIONS, attrs={'td': {'class': 'text-right noprint'}}, verbose_name=''
template_code=CIRCUITTYPE_ACTIONS,
attrs={'td': {'class': 'text-right noprint'}},
verbose_name=''
)
class Meta(BaseTable.Meta):
model = CircuitType
fields = ('pk', 'name', 'circuit_count', 'slug', 'actions')
fields = ('pk', 'name', 'circuit_count', 'description', 'slug', 'actions')
#

View File

@@ -1,12 +1,35 @@
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from rest_framework import status
from circuits.constants import CIRCUIT_STATUS_ACTIVE, TERM_SIDE_A, TERM_SIDE_Z
from circuits.choices import *
from circuits.models import Circuit, CircuitTermination, CircuitType, Provider
from dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, Site
from extras.constants import GRAPH_TYPE_PROVIDER
from dcim.models import Site
from extras.models import Graph
from utilities.testing import APITestCase
from utilities.testing import APITestCase, choices_to_dict
class AppTest(APITestCase):
def test_root(self):
url = reverse('circuits-api:api-root')
response = self.client.get('{}?format=api'.format(url), **self.header)
self.assertEqual(response.status_code, 200)
def test_choices(self):
url = reverse('circuits-api:field-choice-list')
response = self.client.get(url, **self.header)
self.assertEqual(response.status_code, 200)
# Circuit
self.assertEqual(choices_to_dict(response.data.get('circuit:status')), CircuitStatusChoices.as_dict())
# CircuitTermination
self.assertEqual(choices_to_dict(response.data.get('circuit-termination:term_side')), CircuitTerminationSideChoices.as_dict())
class ProviderTest(APITestCase):
@@ -28,16 +51,20 @@ class ProviderTest(APITestCase):
def test_get_provider_graphs(self):
provider_ct = ContentType.objects.get(app_label='circuits', model='provider')
self.graph1 = Graph.objects.create(
type=GRAPH_TYPE_PROVIDER, name='Test Graph 1',
type=provider_ct,
name='Test Graph 1',
source='http://example.com/graphs.py?provider={{ obj.slug }}&foo=1'
)
self.graph2 = Graph.objects.create(
type=GRAPH_TYPE_PROVIDER, name='Test Graph 2',
type=provider_ct,
name='Test Graph 2',
source='http://example.com/graphs.py?provider={{ obj.slug }}&foo=2'
)
self.graph3 = Graph.objects.create(
type=GRAPH_TYPE_PROVIDER, name='Test Graph 3',
type=provider_ct,
name='Test Graph 3',
source='http://example.com/graphs.py?provider={{ obj.slug }}&foo=3'
)
@@ -250,7 +277,7 @@ class CircuitTest(APITestCase):
'cid': 'TEST0004',
'provider': self.provider1.pk,
'type': self.circuittype1.pk,
'status': CIRCUIT_STATUS_ACTIVE,
'status': CircuitStatusChoices.STATUS_ACTIVE,
}
url = reverse('circuits-api:circuit-list')
@@ -270,19 +297,19 @@ class CircuitTest(APITestCase):
'cid': 'TEST0004',
'provider': self.provider1.pk,
'type': self.circuittype1.pk,
'status': CIRCUIT_STATUS_ACTIVE,
'status': CircuitStatusChoices.STATUS_ACTIVE,
},
{
'cid': 'TEST0005',
'provider': self.provider1.pk,
'type': self.circuittype1.pk,
'status': CIRCUIT_STATUS_ACTIVE,
'status': CircuitStatusChoices.STATUS_ACTIVE,
},
{
'cid': 'TEST0006',
'provider': self.provider1.pk,
'type': self.circuittype1.pk,
'status': CIRCUIT_STATUS_ACTIVE,
'status': CircuitStatusChoices.STATUS_ACTIVE,
},
]
@@ -336,16 +363,28 @@ class CircuitTerminationTest(APITestCase):
self.circuit2 = Circuit.objects.create(cid='TEST0002', provider=provider, type=circuittype)
self.circuit3 = Circuit.objects.create(cid='TEST0003', provider=provider, type=circuittype)
self.circuittermination1 = CircuitTermination.objects.create(
circuit=self.circuit1, term_side=TERM_SIDE_A, site=self.site1, port_speed=1000000
circuit=self.circuit1,
term_side=CircuitTerminationSideChoices.SIDE_A,
site=self.site1,
port_speed=1000000
)
self.circuittermination2 = CircuitTermination.objects.create(
circuit=self.circuit1, term_side=TERM_SIDE_Z, site=self.site2, port_speed=1000000
circuit=self.circuit1,
term_side=CircuitTerminationSideChoices.SIDE_Z,
site=self.site2,
port_speed=1000000
)
self.circuittermination3 = CircuitTermination.objects.create(
circuit=self.circuit2, term_side=TERM_SIDE_A, site=self.site1, port_speed=1000000
circuit=self.circuit2,
term_side=CircuitTerminationSideChoices.SIDE_A,
site=self.site1,
port_speed=1000000
)
self.circuittermination4 = CircuitTermination.objects.create(
circuit=self.circuit2, term_side=TERM_SIDE_Z, site=self.site2, port_speed=1000000
circuit=self.circuit2,
term_side=CircuitTerminationSideChoices.SIDE_Z,
site=self.site2,
port_speed=1000000
)
def test_get_circuittermination(self):
@@ -366,7 +405,7 @@ class CircuitTerminationTest(APITestCase):
data = {
'circuit': self.circuit3.pk,
'term_side': TERM_SIDE_A,
'term_side': CircuitTerminationSideChoices.SIDE_A,
'site': self.site1.pk,
'port_speed': 1000000,
}
@@ -385,12 +424,15 @@ class CircuitTerminationTest(APITestCase):
def test_update_circuittermination(self):
circuittermination5 = CircuitTermination.objects.create(
circuit=self.circuit3, term_side=TERM_SIDE_A, site=self.site1, port_speed=1000000
circuit=self.circuit3,
term_side=CircuitTerminationSideChoices.SIDE_A,
site=self.site1,
port_speed=1000000
)
data = {
'circuit': self.circuit3.pk,
'term_side': TERM_SIDE_Z,
'term_side': CircuitTerminationSideChoices.SIDE_Z,
'site': self.site2.pk,
'port_speed': 1000000,
}

View File

@@ -0,0 +1,287 @@
from django.test import TestCase
from circuits.choices import *
from circuits.filters import *
from circuits.models import Circuit, CircuitTermination, CircuitType, Provider
from dcim.models import Region, Site
class ProviderTestCase(TestCase):
queryset = Provider.objects.all()
filterset = ProviderFilterSet
@classmethod
def setUpTestData(cls):
providers = (
Provider(name='Provider 1', slug='provider-1', asn=65001, account='1234'),
Provider(name='Provider 2', slug='provider-2', asn=65002, account='2345'),
Provider(name='Provider 3', slug='provider-3', asn=65003, account='3456'),
Provider(name='Provider 4', slug='provider-4', asn=65004, account='4567'),
Provider(name='Provider 5', slug='provider-5', asn=65005, account='5678'),
)
Provider.objects.bulk_create(providers)
regions = (
Region(name='Test Region 1', slug='test-region-1'),
Region(name='Test Region 2', slug='test-region-2'),
)
# Can't use bulk_create for models with MPTT fields
for r in regions:
r.save()
sites = (
Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
)
Site.objects.bulk_create(sites)
circuit_types = (
CircuitType(name='Test Circuit Type 1', slug='test-circuit-type-1'),
CircuitType(name='Test Circuit Type 2', slug='test-circuit-type-2'),
)
CircuitType.objects.bulk_create(circuit_types)
circuits = (
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 1'),
Circuit(provider=providers[1], type=circuit_types[1], cid='Test Circuit 1'),
)
Circuit.objects.bulk_create(circuits)
CircuitTermination.objects.bulk_create((
CircuitTermination(circuit=circuits[0], site=sites[0], term_side='A', port_speed=1000),
CircuitTermination(circuit=circuits[1], site=sites[0], term_side='A', port_speed=1000),
))
def test_name(self):
params = {'name': ['Provider 1', 'Provider 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_slug(self):
params = {'slug': ['provider-1', 'provider-2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_asn(self):
params = {'asn': ['65001', '65002']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_account(self):
params = {'account': ['1234', '2345']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_site(self):
sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_region(self):
regions = Region.objects.all()[:2]
params = {'region_id': [regions[0].pk, regions[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'region': [regions[0].slug, regions[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
class CircuitTypeTestCase(TestCase):
queryset = CircuitType.objects.all()
filterset = CircuitTypeFilterSet
@classmethod
def setUpTestData(cls):
CircuitType.objects.bulk_create((
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
CircuitType(name='Circuit Type 2', slug='circuit-type-2'),
CircuitType(name='Circuit Type 3', slug='circuit-type-3'),
))
def test_id(self):
params = {'id': [self.queryset.first().pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_name(self):
params = {'name': ['Circuit Type 1']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_slug(self):
params = {'slug': ['circuit-type-1']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
class CircuitTestCase(TestCase):
queryset = Circuit.objects.all()
filterset = CircuitFilterSet
@classmethod
def setUpTestData(cls):
regions = (
Region(name='Test Region 1', slug='test-region-1'),
Region(name='Test Region 2', slug='test-region-2'),
Region(name='Test Region 3', slug='test-region-3'),
)
# Can't use bulk_create for models with MPTT fields
for r in regions:
r.save()
sites = (
Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
Site(name='Test Site 3', slug='test-site-3', region=regions[2]),
)
Site.objects.bulk_create(sites)
circuit_types = (
CircuitType(name='Test Circuit Type 1', slug='test-circuit-type-1'),
CircuitType(name='Test Circuit Type 2', slug='test-circuit-type-2'),
)
CircuitType.objects.bulk_create(circuit_types)
providers = (
Provider(name='Provider 1', slug='provider-1'),
Provider(name='Provider 2', slug='provider-2'),
)
Provider.objects.bulk_create(providers)
circuits = (
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE),
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE),
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED),
Circuit(provider=providers[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED),
Circuit(provider=providers[1], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE),
Circuit(provider=providers[1], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE),
)
Circuit.objects.bulk_create(circuits)
circuit_terminations = ((
CircuitTermination(circuit=circuits[0], site=sites[0], term_side='A', port_speed=1000),
CircuitTermination(circuit=circuits[1], site=sites[1], term_side='A', port_speed=1000),
CircuitTermination(circuit=circuits[2], site=sites[2], term_side='A', port_speed=1000),
))
CircuitTermination.objects.bulk_create(circuit_terminations)
def test_cid(self):
params = {'cid': ['Test Circuit 1', 'Test Circuit 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_install_date(self):
params = {'install_date': ['2020-01-01', '2020-01-02']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_commit_rate(self):
params = {'commit_rate': ['1000', '2000']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_provider(self):
provider = Provider.objects.first()
params = {'provider_id': [provider.pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
params = {'provider': [provider.slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_type(self):
circuit_type = CircuitType.objects.first()
params = {'type_id': [circuit_type.pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
params = {'type': [circuit_type.slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_status(self):
params = {'status': [CircuitStatusChoices.STATUS_ACTIVE, CircuitStatusChoices.STATUS_PLANNED]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_region(self):
regions = Region.objects.all()[:2]
params = {'region_id': [regions[0].pk, regions[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'region': [regions[0].slug, regions[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site(self):
sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
class CircuitTerminationTestCase(TestCase):
queryset = CircuitTermination.objects.all()
filterset = CircuitTerminationFilterSet
@classmethod
def setUpTestData(cls):
sites = (
Site(name='Test Site 1', slug='test-site-1'),
Site(name='Test Site 2', slug='test-site-2'),
Site(name='Test Site 3', slug='test-site-3'),
)
Site.objects.bulk_create(sites)
circuit_types = (
CircuitType(name='Test Circuit Type 1', slug='test-circuit-type-1'),
)
CircuitType.objects.bulk_create(circuit_types)
providers = (
Provider(name='Provider 1', slug='provider-1'),
)
Provider.objects.bulk_create(providers)
circuits = (
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 1'),
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 2'),
Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 3'),
)
Circuit.objects.bulk_create(circuits)
circuit_terminations = ((
CircuitTermination(circuit=circuits[0], site=sites[0], term_side='A', port_speed=1000, upstream_speed=1000, xconnect_id='ABC'),
CircuitTermination(circuit=circuits[0], site=sites[1], term_side='Z', port_speed=1000, upstream_speed=1000, xconnect_id='DEF'),
CircuitTermination(circuit=circuits[1], site=sites[1], term_side='A', port_speed=2000, upstream_speed=2000, xconnect_id='GHI'),
CircuitTermination(circuit=circuits[1], site=sites[2], term_side='Z', port_speed=2000, upstream_speed=2000, xconnect_id='JKL'),
CircuitTermination(circuit=circuits[2], site=sites[2], term_side='A', port_speed=3000, upstream_speed=3000, xconnect_id='MNO'),
CircuitTermination(circuit=circuits[2], site=sites[0], term_side='Z', port_speed=3000, upstream_speed=3000, xconnect_id='PQR'),
))
CircuitTermination.objects.bulk_create(circuit_terminations)
def test_term_side(self):
params = {'term_side': 'A'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_port_speed(self):
params = {'port_speed': ['1000', '2000']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_upstream_speed(self):
params = {'upstream_speed': ['1000', '2000']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_xconnect_id(self):
params = {'xconnect_id': ['ABC', 'DEF']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_circuit_id(self):
circuits = Circuit.objects.all()[:2]
params = {'circuit_id': [circuits[0].pk, circuits[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_site(self):
sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)

View File

@@ -10,7 +10,12 @@ from utilities.testing import create_test_user
class ProviderTestCase(TestCase):
def setUp(self):
user = create_test_user(permissions=['circuits.view_provider'])
user = create_test_user(
permissions=[
'circuits.view_provider',
'circuits.add_provider',
]
)
self.client = Client()
self.client.force_login(user)
@@ -36,11 +41,30 @@ class ProviderTestCase(TestCase):
response = self.client.get(provider.get_absolute_url())
self.assertEqual(response.status_code, 200)
def test_provider_import(self):
csv_data = (
"name,slug",
"Provider 4,provider-4",
"Provider 5,provider-5",
"Provider 6,provider-6",
)
response = self.client.post(reverse('circuits:provider_import'), {'csv': '\n'.join(csv_data)})
self.assertEqual(response.status_code, 200)
self.assertEqual(Provider.objects.count(), 6)
class CircuitTypeTestCase(TestCase):
def setUp(self):
user = create_test_user(permissions=['circuits.view_circuittype'])
user = create_test_user(
permissions=[
'circuits.view_circuittype',
'circuits.add_circuittype',
]
)
self.client = Client()
self.client.force_login(user)
@@ -57,11 +81,30 @@ class CircuitTypeTestCase(TestCase):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_circuittype_import(self):
csv_data = (
"name,slug",
"Circuit Type 4,circuit-type-4",
"Circuit Type 5,circuit-type-5",
"Circuit Type 6,circuit-type-6",
)
response = self.client.post(reverse('circuits:circuittype_import'), {'csv': '\n'.join(csv_data)})
self.assertEqual(response.status_code, 200)
self.assertEqual(CircuitType.objects.count(), 6)
class CircuitTestCase(TestCase):
def setUp(self):
user = create_test_user(permissions=['circuits.view_circuit'])
user = create_test_user(
permissions=[
'circuits.view_circuit',
'circuits.add_circuit',
]
)
self.client = Client()
self.client.force_login(user)
@@ -93,3 +136,17 @@ class CircuitTestCase(TestCase):
circuit = Circuit.objects.first()
response = self.client.get(circuit.get_absolute_url())
self.assertEqual(response.status_code, 200)
def test_circuit_import(self):
csv_data = (
"cid,provider,type",
"Circuit 4,Provider 1,Circuit Type 1",
"Circuit 5,Provider 1,Circuit Type 1",
"Circuit 6,Provider 1,Circuit Type 1",
)
response = self.client.post(reverse('circuits:circuit_import'), {'csv': '\n'.join(csv_data)})
self.assertEqual(response.status_code, 200)
self.assertEqual(Circuit.objects.count(), 6)

View File

@@ -1,3 +1,4 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -5,14 +6,16 @@ from django.db import transaction
from django.db.models import Count, OuterRef, Subquery
from django.shortcuts import get_object_or_404, redirect, render
from django.views.generic import View
from django_tables2 import RequestConfig
from extras.models import Graph, GRAPH_TYPE_PROVIDER
from extras.models import Graph
from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator
from utilities.views import (
BulkDeleteView, BulkEditView, BulkImportView, ObjectDeleteView, ObjectEditView, ObjectListView,
)
from . import filters, forms, tables
from .constants import TERM_SIDE_A, TERM_SIDE_Z
from .choices import CircuitTerminationSideChoices
from .models import Circuit, CircuitTermination, CircuitType, Provider
@@ -23,8 +26,8 @@ from .models import Circuit, CircuitTermination, CircuitType, Provider
class ProviderListView(PermissionRequiredMixin, ObjectListView):
permission_required = 'circuits.view_provider'
queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
filter = filters.ProviderFilter
filter_form = forms.ProviderFilterForm
filterset = filters.ProviderFilterSet
filterset_form = forms.ProviderFilterForm
table = tables.ProviderDetailTable
template_name = 'circuits/provider_list.html'
@@ -36,11 +39,20 @@ class ProviderView(PermissionRequiredMixin, View):
provider = get_object_or_404(Provider, slug=slug)
circuits = Circuit.objects.filter(provider=provider).prefetch_related('type', 'tenant', 'terminations__site')
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
show_graphs = Graph.objects.filter(type__model='provider').exists()
circuits_table = tables.CircuitTable(circuits, orderable=False)
circuits_table.columns.hide('provider')
paginate = {
'paginator_class': EnhancedPaginator,
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
}
RequestConfig(request, paginate).configure(circuits_table)
return render(request, 'circuits/provider.html', {
'provider': provider,
'circuits': circuits,
'circuits_table': circuits_table,
'show_graphs': show_graphs,
})
@@ -73,7 +85,7 @@ class ProviderBulkImportView(PermissionRequiredMixin, BulkImportView):
class ProviderBulkEditView(PermissionRequiredMixin, BulkEditView):
permission_required = 'circuits.change_provider'
queryset = Provider.objects.all()
filter = filters.ProviderFilter
filterset = filters.ProviderFilterSet
table = tables.ProviderTable
form = forms.ProviderBulkEditForm
default_return_url = 'circuits:provider_list'
@@ -82,7 +94,7 @@ class ProviderBulkEditView(PermissionRequiredMixin, BulkEditView):
class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
permission_required = 'circuits.delete_provider'
queryset = Provider.objects.all()
filter = filters.ProviderFilter
filterset = filters.ProviderFilterSet
table = tables.ProviderTable
default_return_url = 'circuits:provider_list'
@@ -136,8 +148,8 @@ class CircuitListView(PermissionRequiredMixin, ObjectListView):
a_side=Subquery(_terminations.filter(term_side='A').values('site__name')[:1]),
z_side=Subquery(_terminations.filter(term_side='Z').values('site__name')[:1]),
)
filter = filters.CircuitFilter
filter_form = forms.CircuitFilterForm
filterset = filters.CircuitFilterSet
filterset_form = forms.CircuitFilterForm
table = tables.CircuitTable
template_name = 'circuits/circuit_list.html'
@@ -151,12 +163,12 @@ class CircuitView(PermissionRequiredMixin, View):
termination_a = CircuitTermination.objects.prefetch_related(
'site__region', 'connected_endpoint__device'
).filter(
circuit=circuit, term_side=TERM_SIDE_A
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
).first()
termination_z = CircuitTermination.objects.prefetch_related(
'site__region', 'connected_endpoint__device'
).filter(
circuit=circuit, term_side=TERM_SIDE_Z
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
).first()
return render(request, 'circuits/circuit.html', {
@@ -194,7 +206,7 @@ class CircuitBulkImportView(PermissionRequiredMixin, BulkImportView):
class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
permission_required = 'circuits.change_circuit'
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
filter = filters.CircuitFilter
filterset = filters.CircuitFilterSet
table = tables.CircuitTable
form = forms.CircuitBulkEditForm
default_return_url = 'circuits:circuit_list'
@@ -203,7 +215,7 @@ class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
permission_required = 'circuits.delete_circuit'
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
filter = filters.CircuitFilter
filterset = filters.CircuitFilterSet
table = tables.CircuitTable
default_return_url = 'circuits:circuit_list'
@@ -212,8 +224,12 @@ class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
def circuit_terminations_swap(request, pk):
circuit = get_object_or_404(Circuit, pk=pk)
termination_a = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_A).first()
termination_z = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_Z).first()
termination_a = CircuitTermination.objects.filter(
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_A
).first()
termination_z = CircuitTermination.objects.filter(
circuit=circuit, term_side=CircuitTerminationSideChoices.SIDE_Z
).first()
if not termination_a and not termination_z:
messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
return redirect('circuits:circuit', pk=circuit.pk)

View File

@@ -4,6 +4,7 @@ from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from dcim.choices import *
from dcim.constants import *
from dcim.models import (
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
@@ -67,7 +68,7 @@ class RegionSerializer(serializers.ModelSerializer):
class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer):
status = ChoiceField(choices=SITE_STATUS_CHOICES, required=False)
status = ChoiceField(choices=SiteStatusChoices, required=False)
region = NestedRegionSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True)
time_zone = TimeZoneField(required=False)
@@ -107,18 +108,18 @@ class RackRoleSerializer(ValidatedModelSerializer):
class Meta:
model = RackRole
fields = ['id', 'name', 'slug', 'color', 'rack_count']
fields = ['id', 'name', 'slug', 'color', 'description', 'rack_count']
class RackSerializer(TaggitSerializer, CustomFieldModelSerializer):
site = NestedSiteSerializer()
group = NestedRackGroupSerializer(required=False, allow_null=True, default=None)
tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=RACK_STATUS_CHOICES, required=False)
status = ChoiceField(choices=RackStatusChoices, required=False)
role = NestedRackRoleSerializer(required=False, allow_null=True)
type = ChoiceField(choices=RACK_TYPE_CHOICES, required=False, allow_null=True)
width = ChoiceField(choices=RACK_WIDTH_CHOICES, required=False)
outer_unit = ChoiceField(choices=RACK_DIMENSION_UNIT_CHOICES, required=False)
type = ChoiceField(choices=RackTypeChoices, required=False, allow_null=True)
width = ChoiceField(choices=RackWidthChoices, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, required=False)
tags = TagListSerializerField(required=False)
device_count = serializers.IntegerField(read_only=True)
powerfeed_count = serializers.IntegerField(read_only=True)
@@ -156,7 +157,7 @@ class RackUnitSerializer(serializers.Serializer):
"""
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(read_only=True)
face = serializers.IntegerField(read_only=True)
face = ChoiceField(choices=DeviceFaceChoices, read_only=True)
device = NestedDeviceSerializer(read_only=True)
@@ -170,6 +171,31 @@ class RackReservationSerializer(ValidatedModelSerializer):
fields = ['id', 'rack', 'units', 'created', 'user', 'tenant', 'description']
class RackElevationDetailFilterSerializer(serializers.Serializer):
face = serializers.ChoiceField(
choices=DeviceFaceChoices,
default=DeviceFaceChoices.FACE_FRONT
)
render = serializers.ChoiceField(
choices=RackElevationDetailRenderChoices,
default=RackElevationDetailRenderChoices.RENDER_JSON
)
unit_width = serializers.IntegerField(
default=RACK_ELEVATION_UNIT_WIDTH_DEFAULT
)
unit_height = serializers.IntegerField(
default=RACK_ELEVATION_UNIT_HEIGHT_DEFAULT
)
exclude = serializers.IntegerField(
required=False,
default=None
)
expand_devices = serializers.BooleanField(
required=False,
default=True
)
#
# Device types
#
@@ -186,7 +212,7 @@ class ManufacturerSerializer(ValidatedModelSerializer):
class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):
manufacturer = NestedManufacturerSerializer()
subdevice_role = ChoiceField(choices=SUBDEVICE_ROLE_CHOICES, required=False, allow_null=True)
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, required=False, allow_null=True)
tags = TagListSerializerField(required=False)
device_count = serializers.IntegerField(read_only=True)
@@ -200,58 +226,72 @@ class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):
class ConsolePortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
required=False
)
class Meta:
model = ConsolePortTemplate
fields = ['id', 'device_type', 'name']
fields = ['id', 'device_type', 'name', 'type']
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
required=False
)
class Meta:
model = ConsoleServerPortTemplate
fields = ['id', 'device_type', 'name']
fields = ['id', 'device_type', 'name', 'type']
class PowerPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=PowerPortTypeChoices,
required=False
)
class Meta:
model = PowerPortTemplate
fields = ['id', 'device_type', 'name', 'maximum_draw', 'allocated_draw']
fields = ['id', 'device_type', 'name', 'type', 'maximum_draw', 'allocated_draw']
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=PowerOutletTypeChoices,
required=False
)
power_port = PowerPortTemplateSerializer(
required=False
)
feed_leg = ChoiceField(
choices=POWERFEED_LEG_CHOICES,
choices=PowerOutletFeedLegChoices,
required=False,
allow_null=True
)
class Meta:
model = PowerOutletTemplate
fields = ['id', 'device_type', 'name', 'power_port', 'feed_leg']
fields = ['id', 'device_type', 'name', 'type', 'power_port', 'feed_leg']
class InterfaceTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
# TODO: Remove in v2.7 (backward-compatibility for form_factor)
form_factor = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
type = ChoiceField(choices=InterfaceTypeChoices, required=False)
class Meta:
model = InterfaceTemplate
fields = ['id', 'device_type', 'name', 'type', 'form_factor', 'mgmt_only']
fields = ['id', 'device_type', 'name', 'type', 'mgmt_only']
class RearPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
type = ChoiceField(choices=PortTypeChoices)
class Meta:
model = RearPortTemplate
@@ -260,7 +300,7 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
class FrontPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
type = ChoiceField(choices=PortTypeChoices)
rear_port = NestedRearPortTemplateSerializer()
class Meta:
@@ -286,7 +326,9 @@ class DeviceRoleSerializer(ValidatedModelSerializer):
class Meta:
model = DeviceRole
fields = ['id', 'name', 'slug', 'color', 'vm_role', 'device_count', 'virtualmachine_count']
fields = [
'id', 'name', 'slug', 'color', 'vm_role', 'description', 'device_count', 'virtualmachine_count',
]
class PlatformSerializer(ValidatedModelSerializer):
@@ -309,8 +351,8 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
platform = NestedPlatformSerializer(required=False, allow_null=True)
site = NestedSiteSerializer()
rack = NestedRackSerializer(required=False, allow_null=True)
face = ChoiceField(choices=RACK_FACE_CHOICES, required=False, allow_null=True)
status = ChoiceField(choices=DEVICE_STATUS_CHOICES, required=False)
face = ChoiceField(choices=DeviceFaceChoices, required=False, allow_null=True)
status = ChoiceField(choices=DeviceStatusChoices, required=False)
primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
@@ -370,39 +412,55 @@ class DeviceWithConfigContextSerializer(DeviceSerializer):
return obj.get_config_context()
class DeviceNAPALMSerializer(serializers.Serializer):
method = serializers.DictField()
class ConsoleServerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
required=False
)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsoleServerPort
fields = [
'id', 'device', 'name', 'description', 'connected_endpoint_type', 'connected_endpoint', 'connection_status',
'cable', 'tags',
'id', 'device', 'name', 'type', 'description', 'connected_endpoint_type', 'connected_endpoint',
'connection_status', 'cable', 'tags',
]
class ConsolePortSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
required=False
)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsolePort
fields = [
'id', 'device', 'name', 'description', 'connected_endpoint_type', 'connected_endpoint', 'connection_status',
'cable', 'tags',
'id', 'device', 'name', 'type', 'description', 'connected_endpoint_type', 'connected_endpoint',
'connection_status', 'cable', 'tags',
]
class PowerOutletSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(
choices=PowerOutletTypeChoices,
required=False
)
power_port = NestedPowerPortSerializer(
required=False
)
feed_leg = ChoiceField(
choices=POWERFEED_LEG_CHOICES,
choices=PowerOutletFeedLegChoices,
required=False,
allow_null=True
)
@@ -416,31 +474,33 @@ class PowerOutletSerializer(TaggitSerializer, ConnectedEndpointSerializer):
class Meta:
model = PowerOutlet
fields = [
'id', 'device', 'name', 'power_port', 'feed_leg', 'description', 'connected_endpoint_type',
'id', 'device', 'name', 'type', 'power_port', 'feed_leg', 'description', 'connected_endpoint_type',
'connected_endpoint', 'connection_status', 'cable', 'tags',
]
class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(
choices=PowerPortTypeChoices,
required=False
)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = PowerPort
fields = [
'id', 'device', 'name', 'maximum_draw', 'allocated_draw', 'description', 'connected_endpoint_type',
'id', 'device', 'name', 'type', 'maximum_draw', 'allocated_draw', 'description', 'connected_endpoint_type',
'connected_endpoint', 'connection_status', 'cable', 'tags',
]
class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
# TODO: Remove in v2.7 (backward-compatibility for form_factor)
form_factor = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
type = ChoiceField(choices=InterfaceTypeChoices, required=False)
lag = NestedInterfaceSerializer(required=False, allow_null=True)
mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
mode = ChoiceField(choices=InterfaceModeChoices, required=False, allow_null=True)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
@@ -454,9 +514,9 @@ class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
class Meta:
model = Interface
fields = [
'id', 'device', 'name', 'type', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
'description', 'connected_endpoint_type', 'connected_endpoint', 'connection_status', 'cable', 'mode',
'untagged_vlan', 'tagged_vlans', 'tags', 'count_ipaddresses',
'id', 'device', 'name', 'type', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'connected_endpoint_type', 'connected_endpoint', 'connection_status', 'cable', 'mode', 'untagged_vlan',
'tagged_vlans', 'tags', 'count_ipaddresses',
]
# TODO: This validation should be handled by Interface.clean()
@@ -482,7 +542,7 @@ class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
class RearPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
type = ChoiceField(choices=PortTypeChoices)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
@@ -504,7 +564,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
class FrontPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
type = ChoiceField(choices=PortTypeChoices)
rear_port = FrontPortRearPortSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
@@ -549,15 +609,15 @@ class InventoryItemSerializer(TaggitSerializer, ValidatedModelSerializer):
class CableSerializer(ValidatedModelSerializer):
termination_a_type = ContentTypeField(
queryset=ContentType.objects.filter(model__in=CABLE_TERMINATION_TYPES)
queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
)
termination_b_type = ContentTypeField(
queryset=ContentType.objects.filter(model__in=CABLE_TERMINATION_TYPES)
queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
)
termination_a = serializers.SerializerMethodField(read_only=True)
termination_b = serializers.SerializerMethodField(read_only=True)
status = ChoiceField(choices=CONNECTION_STATUS_CHOICES, required=False)
length_unit = ChoiceField(choices=CABLE_LENGTH_UNIT_CHOICES, required=False, allow_null=True)
status = ChoiceField(choices=CableStatusChoices, required=False)
length_unit = ChoiceField(choices=CableLengthUnitChoices, required=False, allow_null=True)
class Meta:
model = Cable
@@ -662,20 +722,20 @@ class PowerFeedSerializer(TaggitSerializer, CustomFieldModelSerializer):
default=None
)
type = ChoiceField(
choices=POWERFEED_TYPE_CHOICES,
default=POWERFEED_TYPE_PRIMARY
choices=PowerFeedTypeChoices,
default=PowerFeedTypeChoices.TYPE_PRIMARY
)
status = ChoiceField(
choices=POWERFEED_STATUS_CHOICES,
default=POWERFEED_STATUS_ACTIVE
choices=PowerFeedStatusChoices,
default=PowerFeedStatusChoices.STATUS_ACTIVE
)
supply = ChoiceField(
choices=POWERFEED_SUPPLY_CHOICES,
default=POWERFEED_SUPPLY_AC
choices=PowerFeedSupplyChoices,
default=PowerFeedSupplyChoices.SUPPLY_AC
)
phase = ChoiceField(
choices=POWERFEED_PHASE_CHOICES,
default=POWERFEED_PHASE_SINGLE
choices=PowerFeedPhaseChoices,
default=PowerFeedPhaseChoices.PHASE_SINGLE
)
tags = TagListSerializerField(
required=False

View File

@@ -2,7 +2,7 @@ from collections import OrderedDict
from django.conf import settings
from django.db.models import Count, F
from django.http import HttpResponseForbidden
from django.http import HttpResponseForbidden, HttpResponse
from django.shortcuts import get_object_or_404
from drf_yasg import openapi
from drf_yasg.openapi import Parameter
@@ -23,7 +23,6 @@ from dcim.models import (
)
from extras.api.serializers import RenderedGraphSerializer
from extras.api.views import CustomFieldModelViewSet
from extras.constants import GRAPH_TYPE_DEVICE, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
from extras.models import Graph
from ipam.models import Prefix, VLAN
from utilities.api import (
@@ -41,21 +40,26 @@ from .exceptions import MissingFilterException
class DCIMFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(Cable, ['length_unit', 'status', 'termination_a_type', 'termination_b_type', 'type']),
(ConsolePort, ['connection_status']),
(Device, ['face', 'status']),
(DeviceType, ['subdevice_role']),
(FrontPort, ['type']),
(FrontPortTemplate, ['type']),
(Interface, ['type', 'mode']),
(InterfaceTemplate, ['type']),
(PowerOutlet, ['feed_leg']),
(PowerOutletTemplate, ['feed_leg']),
(PowerPort, ['connection_status']),
(Rack, ['outer_unit', 'status', 'type', 'width']),
(RearPort, ['type']),
(RearPortTemplate, ['type']),
(Site, ['status']),
(serializers.CableSerializer, ['length_unit', 'status', 'termination_a_type', 'termination_b_type', 'type']),
(serializers.ConsolePortSerializer, ['type', 'connection_status']),
(serializers.ConsolePortTemplateSerializer, ['type']),
(serializers.ConsoleServerPortSerializer, ['type']),
(serializers.ConsoleServerPortTemplateSerializer, ['type']),
(serializers.DeviceSerializer, ['face', 'status']),
(serializers.DeviceTypeSerializer, ['subdevice_role']),
(serializers.FrontPortSerializer, ['type']),
(serializers.FrontPortTemplateSerializer, ['type']),
(serializers.InterfaceSerializer, ['type', 'mode']),
(serializers.InterfaceTemplateSerializer, ['type']),
(serializers.PowerFeedSerializer, ['phase', 'status', 'supply', 'type']),
(serializers.PowerOutletSerializer, ['type', 'feed_leg']),
(serializers.PowerOutletTemplateSerializer, ['type', 'feed_leg']),
(serializers.PowerPortSerializer, ['type', 'connection_status']),
(serializers.PowerPortTemplateSerializer, ['type']),
(serializers.RackSerializer, ['outer_unit', 'status', 'type', 'width']),
(serializers.RearPortSerializer, ['type']),
(serializers.RearPortTemplateSerializer, ['type']),
(serializers.SiteSerializer, ['status']),
)
@@ -102,7 +106,7 @@ class RegionViewSet(ModelViewSet):
site_count=Count('sites')
)
serializer_class = serializers.RegionSerializer
filterset_class = filters.RegionFilter
filterset_class = filters.RegionFilterSet
#
@@ -121,7 +125,7 @@ class SiteViewSet(CustomFieldModelViewSet):
virtualmachine_count=get_subquery(VirtualMachine, 'cluster__site'),
)
serializer_class = serializers.SiteSerializer
filterset_class = filters.SiteFilter
filterset_class = filters.SiteFilterSet
@action(detail=True)
def graphs(self, request, pk):
@@ -129,7 +133,7 @@ class SiteViewSet(CustomFieldModelViewSet):
A convenience method for rendering graphs for a particular site.
"""
site = get_object_or_404(Site, pk=pk)
queryset = Graph.objects.filter(type=GRAPH_TYPE_SITE)
queryset = Graph.objects.filter(type__model='site')
serializer = RenderedGraphSerializer(queryset, many=True, context={'graphed_object': site})
return Response(serializer.data)
@@ -143,7 +147,7 @@ class RackGroupViewSet(ModelViewSet):
rack_count=Count('racks')
)
serializer_class = serializers.RackGroupSerializer
filterset_class = filters.RackGroupFilter
filterset_class = filters.RackGroupFilterSet
#
@@ -155,7 +159,7 @@ class RackRoleViewSet(ModelViewSet):
rack_count=Count('racks')
)
serializer_class = serializers.RackRoleSerializer
filterset_class = filters.RackRoleFilter
filterset_class = filters.RackRoleFilterSet
#
@@ -170,15 +174,17 @@ class RackViewSet(CustomFieldModelViewSet):
powerfeed_count=get_subquery(PowerFeed, 'rack')
)
serializer_class = serializers.RackSerializer
filterset_class = filters.RackFilter
filterset_class = filters.RackFilterSet
@swagger_auto_schema(deprecated=True)
@action(detail=True)
def units(self, request, pk=None):
"""
List rack units (by rack)
"""
# TODO: Remove this action detail route in v2.8
rack = get_object_or_404(Rack, pk=pk)
face = request.GET.get('face', 0)
face = request.GET.get('face', 'front')
exclude_pk = request.GET.get('exclude', None)
if exclude_pk is not None:
try:
@@ -197,6 +203,39 @@ class RackViewSet(CustomFieldModelViewSet):
rack_units = serializers.RackUnitSerializer(page, many=True, context={'request': request})
return self.get_paginated_response(rack_units.data)
@swagger_auto_schema(
responses={200: serializers.RackUnitSerializer(many=True)},
query_serializer=serializers.RackElevationDetailFilterSerializer
)
@action(detail=True)
def elevation(self, request, pk=None):
"""
Rack elevation representing the list of rack units. Also supports rendering the elevation as an SVG.
"""
rack = get_object_or_404(Rack, pk=pk)
serializer = serializers.RackElevationDetailFilterSerializer(data=request.GET)
if not serializer.is_valid():
return Response(serializer.errors, 400)
data = serializer.validated_data
if data['render'] == 'svg':
# Render and return the elevation as an SVG drawing with the correct content type
drawing = rack.get_elevation_svg(data['face'], data['unit_width'], data['unit_height'])
return HttpResponse(drawing.tostring(), content_type='image/svg+xml')
else:
# Return a JSON representation of the rack units in the elevation
elevation = rack.get_rack_units(
face=data['face'],
exclude=data['exclude'],
expand_devices=data['expand_devices']
)
page = self.paginate_queryset(elevation)
if page is not None:
rack_units = serializers.RackUnitSerializer(page, many=True, context={'request': request})
return self.get_paginated_response(rack_units.data)
#
# Rack reservations
@@ -205,7 +244,7 @@ class RackViewSet(CustomFieldModelViewSet):
class RackReservationViewSet(ModelViewSet):
queryset = RackReservation.objects.prefetch_related('rack', 'user', 'tenant')
serializer_class = serializers.RackReservationSerializer
filterset_class = filters.RackReservationFilter
filterset_class = filters.RackReservationFilterSet
# Assign user from request
def perform_create(self, serializer):
@@ -223,7 +262,7 @@ class ManufacturerViewSet(ModelViewSet):
platform_count=get_subquery(Platform, 'manufacturer')
)
serializer_class = serializers.ManufacturerSerializer
filterset_class = filters.ManufacturerFilter
filterset_class = filters.ManufacturerFilterSet
#
@@ -235,7 +274,7 @@ class DeviceTypeViewSet(CustomFieldModelViewSet):
device_count=Count('instances')
)
serializer_class = serializers.DeviceTypeSerializer
filterset_class = filters.DeviceTypeFilter
filterset_class = filters.DeviceTypeFilterSet
#
@@ -245,49 +284,49 @@ class DeviceTypeViewSet(CustomFieldModelViewSet):
class ConsolePortTemplateViewSet(ModelViewSet):
queryset = ConsolePortTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.ConsolePortTemplateSerializer
filterset_class = filters.ConsolePortTemplateFilter
filterset_class = filters.ConsolePortTemplateFilterSet
class ConsoleServerPortTemplateViewSet(ModelViewSet):
queryset = ConsoleServerPortTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.ConsoleServerPortTemplateSerializer
filterset_class = filters.ConsoleServerPortTemplateFilter
filterset_class = filters.ConsoleServerPortTemplateFilterSet
class PowerPortTemplateViewSet(ModelViewSet):
queryset = PowerPortTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.PowerPortTemplateSerializer
filterset_class = filters.PowerPortTemplateFilter
filterset_class = filters.PowerPortTemplateFilterSet
class PowerOutletTemplateViewSet(ModelViewSet):
queryset = PowerOutletTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.PowerOutletTemplateSerializer
filterset_class = filters.PowerOutletTemplateFilter
filterset_class = filters.PowerOutletTemplateFilterSet
class InterfaceTemplateViewSet(ModelViewSet):
queryset = InterfaceTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.InterfaceTemplateSerializer
filterset_class = filters.InterfaceTemplateFilter
filterset_class = filters.InterfaceTemplateFilterSet
class FrontPortTemplateViewSet(ModelViewSet):
queryset = FrontPortTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.FrontPortTemplateSerializer
filterset_class = filters.FrontPortTemplateFilter
filterset_class = filters.FrontPortTemplateFilterSet
class RearPortTemplateViewSet(ModelViewSet):
queryset = RearPortTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.RearPortTemplateSerializer
filterset_class = filters.RearPortTemplateFilter
filterset_class = filters.RearPortTemplateFilterSet
class DeviceBayTemplateViewSet(ModelViewSet):
queryset = DeviceBayTemplate.objects.prefetch_related('device_type__manufacturer')
serializer_class = serializers.DeviceBayTemplateSerializer
filterset_class = filters.DeviceBayTemplateFilter
filterset_class = filters.DeviceBayTemplateFilterSet
#
@@ -300,7 +339,7 @@ class DeviceRoleViewSet(ModelViewSet):
virtualmachine_count=get_subquery(VirtualMachine, 'role')
)
serializer_class = serializers.DeviceRoleSerializer
filterset_class = filters.DeviceRoleFilter
filterset_class = filters.DeviceRoleFilterSet
#
@@ -313,7 +352,7 @@ class PlatformViewSet(ModelViewSet):
virtualmachine_count=get_subquery(VirtualMachine, 'platform')
)
serializer_class = serializers.PlatformSerializer
filterset_class = filters.PlatformFilter
filterset_class = filters.PlatformFilterSet
#
@@ -325,7 +364,7 @@ class DeviceViewSet(CustomFieldModelViewSet):
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay',
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
)
filterset_class = filters.DeviceFilter
filterset_class = filters.DeviceFilterSet
def get_serializer_class(self):
"""
@@ -353,11 +392,22 @@ class DeviceViewSet(CustomFieldModelViewSet):
A convenience method for rendering graphs for a particular Device.
"""
device = get_object_or_404(Device, pk=pk)
queryset = Graph.objects.filter(type=GRAPH_TYPE_DEVICE)
queryset = Graph.objects.filter(type__model='device')
serializer = RenderedGraphSerializer(queryset, many=True, context={'graphed_object': device})
return Response(serializer.data)
@swagger_auto_schema(
manual_parameters=[
Parameter(
name='method',
in_='query',
required=True,
type=openapi.TYPE_STRING
)
],
responses={'200': serializers.DeviceNAPALMSerializer}
)
@action(detail=True, url_path='napalm')
def napalm(self, request, pk):
"""
@@ -396,13 +446,29 @@ class DeviceViewSet(CustomFieldModelViewSet):
napalm_methods = request.GET.getlist('method')
response = OrderedDict([(m, None) for m in napalm_methods])
ip_address = str(device.primary_ip.address.ip)
username = settings.NAPALM_USERNAME
password = settings.NAPALM_PASSWORD
optional_args = settings.NAPALM_ARGS.copy()
if device.platform.napalm_args is not None:
optional_args.update(device.platform.napalm_args)
# Update NAPALM parameters according to the request headers
for header in request.headers:
if header[:9].lower() != 'x-napalm-':
continue
key = header[9:]
if key.lower() == 'username':
username = request.headers[header]
elif key.lower() == 'password':
password = request.headers[header]
elif key:
optional_args[key.lower()] = request.headers[header]
d = driver(
hostname=ip_address,
username=settings.NAPALM_USERNAME,
password=settings.NAPALM_PASSWORD,
username=username,
password=password,
timeout=settings.NAPALM_TIMEOUT,
optional_args=optional_args
)
@@ -437,13 +503,13 @@ class DeviceViewSet(CustomFieldModelViewSet):
class ConsolePortViewSet(CableTraceMixin, ModelViewSet):
queryset = ConsolePort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
serializer_class = serializers.ConsolePortSerializer
filterset_class = filters.ConsolePortFilter
filterset_class = filters.ConsolePortFilterSet
class ConsoleServerPortViewSet(CableTraceMixin, ModelViewSet):
queryset = ConsoleServerPort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
serializer_class = serializers.ConsoleServerPortSerializer
filterset_class = filters.ConsoleServerPortFilter
filterset_class = filters.ConsoleServerPortFilterSet
class PowerPortViewSet(CableTraceMixin, ModelViewSet):
@@ -451,13 +517,13 @@ class PowerPortViewSet(CableTraceMixin, ModelViewSet):
'device', '_connected_poweroutlet__device', '_connected_powerfeed', 'cable', 'tags'
)
serializer_class = serializers.PowerPortSerializer
filterset_class = filters.PowerPortFilter
filterset_class = filters.PowerPortFilterSet
class PowerOutletViewSet(CableTraceMixin, ModelViewSet):
queryset = PowerOutlet.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
serializer_class = serializers.PowerOutletSerializer
filterset_class = filters.PowerOutletFilter
filterset_class = filters.PowerOutletFilterSet
class InterfaceViewSet(CableTraceMixin, ModelViewSet):
@@ -467,7 +533,7 @@ class InterfaceViewSet(CableTraceMixin, ModelViewSet):
device__isnull=False
)
serializer_class = serializers.InterfaceSerializer
filterset_class = filters.InterfaceFilter
filterset_class = filters.InterfaceFilterSet
@action(detail=True)
def graphs(self, request, pk):
@@ -475,7 +541,7 @@ class InterfaceViewSet(CableTraceMixin, ModelViewSet):
A convenience method for rendering graphs for a particular interface.
"""
interface = get_object_or_404(Interface, pk=pk)
queryset = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE)
queryset = Graph.objects.filter(type__model='interface')
serializer = RenderedGraphSerializer(queryset, many=True, context={'graphed_object': interface})
return Response(serializer.data)
@@ -483,25 +549,25 @@ class InterfaceViewSet(CableTraceMixin, ModelViewSet):
class FrontPortViewSet(ModelViewSet):
queryset = FrontPort.objects.prefetch_related('device__device_type__manufacturer', 'rear_port', 'cable', 'tags')
serializer_class = serializers.FrontPortSerializer
filterset_class = filters.FrontPortFilter
filterset_class = filters.FrontPortFilterSet
class RearPortViewSet(ModelViewSet):
queryset = RearPort.objects.prefetch_related('device__device_type__manufacturer', 'cable', 'tags')
serializer_class = serializers.RearPortSerializer
filterset_class = filters.RearPortFilter
filterset_class = filters.RearPortFilterSet
class DeviceBayViewSet(ModelViewSet):
queryset = DeviceBay.objects.prefetch_related('installed_device').prefetch_related('tags')
serializer_class = serializers.DeviceBaySerializer
filterset_class = filters.DeviceBayFilter
filterset_class = filters.DeviceBayFilterSet
class InventoryItemViewSet(ModelViewSet):
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer').prefetch_related('tags')
serializer_class = serializers.InventoryItemSerializer
filterset_class = filters.InventoryItemFilter
filterset_class = filters.InventoryItemFilterSet
#
@@ -515,7 +581,7 @@ class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
connected_endpoint__isnull=False
)
serializer_class = serializers.ConsolePortSerializer
filterset_class = filters.ConsoleConnectionFilter
filterset_class = filters.ConsoleConnectionFilterSet
class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
@@ -525,7 +591,7 @@ class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
_connected_poweroutlet__isnull=False
)
serializer_class = serializers.PowerPortSerializer
filterset_class = filters.PowerConnectionFilter
filterset_class = filters.PowerConnectionFilterSet
class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet):
@@ -537,7 +603,7 @@ class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet):
pk__lt=F('_connected_interface')
)
serializer_class = serializers.InterfaceConnectionSerializer
filterset_class = filters.InterfaceConnectionFilter
filterset_class = filters.InterfaceConnectionFilterSet
#
@@ -549,7 +615,7 @@ class CableViewSet(ModelViewSet):
'termination_a', 'termination_b'
)
serializer_class = serializers.CableSerializer
filterset_class = filters.CableFilter
filterset_class = filters.CableFilterSet
#
@@ -561,7 +627,7 @@ class VirtualChassisViewSet(ModelViewSet):
member_count=Count('members')
)
serializer_class = serializers.VirtualChassisSerializer
filterset_class = filters.VirtualChassisFilter
filterset_class = filters.VirtualChassisFilterSet
#
@@ -575,7 +641,7 @@ class PowerPanelViewSet(ModelViewSet):
powerfeed_count=Count('powerfeeds')
)
serializer_class = serializers.PowerPanelSerializer
filterset_class = filters.PowerPanelFilter
filterset_class = filters.PowerPanelFilterSet
#
@@ -585,7 +651,7 @@ class PowerPanelViewSet(ModelViewSet):
class PowerFeedViewSet(CustomFieldModelViewSet):
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack', 'tags')
serializer_class = serializers.PowerFeedSerializer
filterset_class = filters.PowerFeedFilter
filterset_class = filters.PowerFeedFilterSet
#

1079
netbox/dcim/choices.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,361 +1,41 @@
from django.db.models import Q
# Rack types
RACK_TYPE_2POST = 100
RACK_TYPE_4POST = 200
RACK_TYPE_CABINET = 300
RACK_TYPE_WALLFRAME = 1000
RACK_TYPE_WALLCABINET = 1100
RACK_TYPE_CHOICES = (
(RACK_TYPE_2POST, '2-post frame'),
(RACK_TYPE_4POST, '4-post frame'),
(RACK_TYPE_CABINET, '4-post cabinet'),
(RACK_TYPE_WALLFRAME, 'Wall-mounted frame'),
(RACK_TYPE_WALLCABINET, 'Wall-mounted cabinet'),
)
from .choices import InterfaceTypeChoices
# Rack widths
RACK_WIDTH_19IN = 19
RACK_WIDTH_23IN = 23
RACK_WIDTH_CHOICES = (
(RACK_WIDTH_19IN, '19 inches'),
(RACK_WIDTH_23IN, '23 inches'),
)
# Rack faces
RACK_FACE_FRONT = 0
RACK_FACE_REAR = 1
RACK_FACE_CHOICES = [
[RACK_FACE_FRONT, 'Front'],
[RACK_FACE_REAR, 'Rear'],
]
#
# Rack elevation rendering
#
# Rack statuses
RACK_STATUS_RESERVED = 0
RACK_STATUS_AVAILABLE = 1
RACK_STATUS_PLANNED = 2
RACK_STATUS_ACTIVE = 3
RACK_STATUS_DEPRECATED = 4
RACK_STATUS_CHOICES = [
[RACK_STATUS_ACTIVE, 'Active'],
[RACK_STATUS_PLANNED, 'Planned'],
[RACK_STATUS_RESERVED, 'Reserved'],
[RACK_STATUS_AVAILABLE, 'Available'],
[RACK_STATUS_DEPRECATED, 'Deprecated'],
]
RACK_ELEVATION_UNIT_WIDTH_DEFAULT = 230
RACK_ELEVATION_UNIT_HEIGHT_DEFAULT = 20
# Device rack position
DEVICE_POSITION_CHOICES = [
# Rack.u_height is limited to 100
(i, 'Unit {}'.format(i)) for i in range(1, 101)
]
# Parent/child device roles
SUBDEVICE_ROLE_PARENT = True
SUBDEVICE_ROLE_CHILD = False
SUBDEVICE_ROLE_CHOICES = (
(None, 'None'),
(SUBDEVICE_ROLE_PARENT, 'Parent'),
(SUBDEVICE_ROLE_CHILD, 'Child'),
)
# Interface ordering schemes (for device types)
IFACE_ORDERING_POSITION = 1
IFACE_ORDERING_NAME = 2
IFACE_ORDERING_CHOICES = [
[IFACE_ORDERING_POSITION, 'Slot/position'],
[IFACE_ORDERING_NAME, 'Name (alphabetically)']
]
# Interface types
# Virtual
IFACE_TYPE_VIRTUAL = 0
IFACE_TYPE_LAG = 200
# Ethernet
IFACE_TYPE_100ME_FIXED = 800
IFACE_TYPE_1GE_FIXED = 1000
IFACE_TYPE_1GE_GBIC = 1050
IFACE_TYPE_1GE_SFP = 1100
IFACE_TYPE_2GE_FIXED = 1120
IFACE_TYPE_5GE_FIXED = 1130
IFACE_TYPE_10GE_FIXED = 1150
IFACE_TYPE_10GE_CX4 = 1170
IFACE_TYPE_10GE_SFP_PLUS = 1200
IFACE_TYPE_10GE_XFP = 1300
IFACE_TYPE_10GE_XENPAK = 1310
IFACE_TYPE_10GE_X2 = 1320
IFACE_TYPE_25GE_SFP28 = 1350
IFACE_TYPE_40GE_QSFP_PLUS = 1400
IFACE_TYPE_50GE_QSFP28 = 1420
IFACE_TYPE_100GE_CFP = 1500
IFACE_TYPE_100GE_CFP2 = 1510
IFACE_TYPE_100GE_CFP4 = 1520
IFACE_TYPE_100GE_CPAK = 1550
IFACE_TYPE_100GE_QSFP28 = 1600
IFACE_TYPE_200GE_CFP2 = 1650
IFACE_TYPE_200GE_QSFP56 = 1700
IFACE_TYPE_400GE_QSFP_DD = 1750
# Wireless
IFACE_TYPE_80211A = 2600
IFACE_TYPE_80211G = 2610
IFACE_TYPE_80211N = 2620
IFACE_TYPE_80211AC = 2630
IFACE_TYPE_80211AD = 2640
# Cellular
IFACE_TYPE_GSM = 2810
IFACE_TYPE_CDMA = 2820
IFACE_TYPE_LTE = 2830
# SONET
IFACE_TYPE_SONET_OC3 = 6100
IFACE_TYPE_SONET_OC12 = 6200
IFACE_TYPE_SONET_OC48 = 6300
IFACE_TYPE_SONET_OC192 = 6400
IFACE_TYPE_SONET_OC768 = 6500
IFACE_TYPE_SONET_OC1920 = 6600
IFACE_TYPE_SONET_OC3840 = 6700
# Fibrechannel
IFACE_TYPE_1GFC_SFP = 3010
IFACE_TYPE_2GFC_SFP = 3020
IFACE_TYPE_4GFC_SFP = 3040
IFACE_TYPE_8GFC_SFP_PLUS = 3080
IFACE_TYPE_16GFC_SFP_PLUS = 3160
IFACE_TYPE_32GFC_SFP28 = 3320
IFACE_TYPE_128GFC_QSFP28 = 3400
# Serial
IFACE_TYPE_T1 = 4000
IFACE_TYPE_E1 = 4010
IFACE_TYPE_T3 = 4040
IFACE_TYPE_E3 = 4050
# Stacking
IFACE_TYPE_STACKWISE = 5000
IFACE_TYPE_STACKWISE_PLUS = 5050
IFACE_TYPE_FLEXSTACK = 5100
IFACE_TYPE_FLEXSTACK_PLUS = 5150
IFACE_TYPE_JUNIPER_VCP = 5200
IFACE_TYPE_SUMMITSTACK = 5300
IFACE_TYPE_SUMMITSTACK128 = 5310
IFACE_TYPE_SUMMITSTACK256 = 5320
IFACE_TYPE_SUMMITSTACK512 = 5330
# Other
IFACE_TYPE_OTHER = 32767
IFACE_TYPE_CHOICES = [
[
'Virtual interfaces',
[
[IFACE_TYPE_VIRTUAL, 'Virtual'],
[IFACE_TYPE_LAG, 'Link Aggregation Group (LAG)'],
],
],
[
'Ethernet (fixed)',
[
[IFACE_TYPE_100ME_FIXED, '100BASE-TX (10/100ME)'],
[IFACE_TYPE_1GE_FIXED, '1000BASE-T (1GE)'],
[IFACE_TYPE_2GE_FIXED, '2.5GBASE-T (2.5GE)'],
[IFACE_TYPE_5GE_FIXED, '5GBASE-T (5GE)'],
[IFACE_TYPE_10GE_FIXED, '10GBASE-T (10GE)'],
[IFACE_TYPE_10GE_CX4, '10GBASE-CX4 (10GE)'],
]
],
[
'Ethernet (modular)',
[
[IFACE_TYPE_1GE_GBIC, 'GBIC (1GE)'],
[IFACE_TYPE_1GE_SFP, 'SFP (1GE)'],
[IFACE_TYPE_10GE_SFP_PLUS, 'SFP+ (10GE)'],
[IFACE_TYPE_10GE_XFP, 'XFP (10GE)'],
[IFACE_TYPE_10GE_XENPAK, 'XENPAK (10GE)'],
[IFACE_TYPE_10GE_X2, 'X2 (10GE)'],
[IFACE_TYPE_25GE_SFP28, 'SFP28 (25GE)'],
[IFACE_TYPE_40GE_QSFP_PLUS, 'QSFP+ (40GE)'],
[IFACE_TYPE_50GE_QSFP28, 'QSFP28 (50GE)'],
[IFACE_TYPE_100GE_CFP, 'CFP (100GE)'],
[IFACE_TYPE_100GE_CFP2, 'CFP2 (100GE)'],
[IFACE_TYPE_200GE_CFP2, 'CFP2 (200GE)'],
[IFACE_TYPE_100GE_CFP4, 'CFP4 (100GE)'],
[IFACE_TYPE_100GE_CPAK, 'Cisco CPAK (100GE)'],
[IFACE_TYPE_100GE_QSFP28, 'QSFP28 (100GE)'],
[IFACE_TYPE_200GE_QSFP56, 'QSFP56 (200GE)'],
[IFACE_TYPE_400GE_QSFP_DD, 'QSFP-DD (400GE)'],
]
],
[
'Wireless',
[
[IFACE_TYPE_80211A, 'IEEE 802.11a'],
[IFACE_TYPE_80211G, 'IEEE 802.11b/g'],
[IFACE_TYPE_80211N, 'IEEE 802.11n'],
[IFACE_TYPE_80211AC, 'IEEE 802.11ac'],
[IFACE_TYPE_80211AD, 'IEEE 802.11ad'],
]
],
[
'Cellular',
[
[IFACE_TYPE_GSM, 'GSM'],
[IFACE_TYPE_CDMA, 'CDMA'],
[IFACE_TYPE_LTE, 'LTE'],
]
],
[
'SONET',
[
[IFACE_TYPE_SONET_OC3, 'OC-3/STM-1'],
[IFACE_TYPE_SONET_OC12, 'OC-12/STM-4'],
[IFACE_TYPE_SONET_OC48, 'OC-48/STM-16'],
[IFACE_TYPE_SONET_OC192, 'OC-192/STM-64'],
[IFACE_TYPE_SONET_OC768, 'OC-768/STM-256'],
[IFACE_TYPE_SONET_OC1920, 'OC-1920/STM-640'],
[IFACE_TYPE_SONET_OC3840, 'OC-3840/STM-1234'],
]
],
[
'FibreChannel',
[
[IFACE_TYPE_1GFC_SFP, 'SFP (1GFC)'],
[IFACE_TYPE_2GFC_SFP, 'SFP (2GFC)'],
[IFACE_TYPE_4GFC_SFP, 'SFP (4GFC)'],
[IFACE_TYPE_8GFC_SFP_PLUS, 'SFP+ (8GFC)'],
[IFACE_TYPE_16GFC_SFP_PLUS, 'SFP+ (16GFC)'],
[IFACE_TYPE_32GFC_SFP28, 'SFP28 (32GFC)'],
[IFACE_TYPE_128GFC_QSFP28, 'QSFP28 (128GFC)'],
]
],
[
'Serial',
[
[IFACE_TYPE_T1, 'T1 (1.544 Mbps)'],
[IFACE_TYPE_E1, 'E1 (2.048 Mbps)'],
[IFACE_TYPE_T3, 'T3 (45 Mbps)'],
[IFACE_TYPE_E3, 'E3 (34 Mbps)'],
]
],
[
'Stacking',
[
[IFACE_TYPE_STACKWISE, 'Cisco StackWise'],
[IFACE_TYPE_STACKWISE_PLUS, 'Cisco StackWise Plus'],
[IFACE_TYPE_FLEXSTACK, 'Cisco FlexStack'],
[IFACE_TYPE_FLEXSTACK_PLUS, 'Cisco FlexStack Plus'],
[IFACE_TYPE_JUNIPER_VCP, 'Juniper VCP'],
[IFACE_TYPE_SUMMITSTACK, 'Extreme SummitStack'],
[IFACE_TYPE_SUMMITSTACK128, 'Extreme SummitStack-128'],
[IFACE_TYPE_SUMMITSTACK256, 'Extreme SummitStack-256'],
[IFACE_TYPE_SUMMITSTACK512, 'Extreme SummitStack-512'],
]
],
[
'Other',
[
[IFACE_TYPE_OTHER, 'Other'],
]
],
]
#
# Interface type groups
#
VIRTUAL_IFACE_TYPES = [
IFACE_TYPE_VIRTUAL,
IFACE_TYPE_LAG,
InterfaceTypeChoices.TYPE_VIRTUAL,
InterfaceTypeChoices.TYPE_LAG,
]
WIRELESS_IFACE_TYPES = [
IFACE_TYPE_80211A,
IFACE_TYPE_80211G,
IFACE_TYPE_80211N,
IFACE_TYPE_80211AC,
IFACE_TYPE_80211AD,
InterfaceTypeChoices.TYPE_80211A,
InterfaceTypeChoices.TYPE_80211G,
InterfaceTypeChoices.TYPE_80211N,
InterfaceTypeChoices.TYPE_80211AC,
InterfaceTypeChoices.TYPE_80211AD,
]
NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES
IFACE_MODE_ACCESS = 100
IFACE_MODE_TAGGED = 200
IFACE_MODE_TAGGED_ALL = 300
IFACE_MODE_CHOICES = [
[IFACE_MODE_ACCESS, 'Access'],
[IFACE_MODE_TAGGED, 'Tagged'],
[IFACE_MODE_TAGGED_ALL, 'Tagged All'],
]
# Pass-through port types
PORT_TYPE_8P8C = 1000
PORT_TYPE_110_PUNCH = 1100
PORT_TYPE_BNC = 1200
PORT_TYPE_ST = 2000
PORT_TYPE_SC = 2100
PORT_TYPE_SC_APC = 2110
PORT_TYPE_FC = 2200
PORT_TYPE_LC = 2300
PORT_TYPE_LC_APC = 2310
PORT_TYPE_MTRJ = 2400
PORT_TYPE_MPO = 2500
PORT_TYPE_LSH = 2600
PORT_TYPE_LSH_APC = 2610
PORT_TYPE_CHOICES = [
[
'Copper',
[
[PORT_TYPE_8P8C, '8P8C'],
[PORT_TYPE_110_PUNCH, '110 Punch'],
[PORT_TYPE_BNC, 'BNC'],
],
],
[
'Fiber Optic',
[
[PORT_TYPE_FC, 'FC'],
[PORT_TYPE_LC, 'LC'],
[PORT_TYPE_LC_APC, 'LC/APC'],
[PORT_TYPE_LSH, 'LSH'],
[PORT_TYPE_LSH_APC, 'LSH/APC'],
[PORT_TYPE_MPO, 'MPO'],
[PORT_TYPE_MTRJ, 'MTRJ'],
[PORT_TYPE_SC, 'SC'],
[PORT_TYPE_SC_APC, 'SC/APC'],
[PORT_TYPE_ST, 'ST'],
]
]
]
# Device statuses
DEVICE_STATUS_OFFLINE = 0
DEVICE_STATUS_ACTIVE = 1
DEVICE_STATUS_PLANNED = 2
DEVICE_STATUS_STAGED = 3
DEVICE_STATUS_FAILED = 4
DEVICE_STATUS_INVENTORY = 5
DEVICE_STATUS_DECOMMISSIONING = 6
DEVICE_STATUS_CHOICES = [
[DEVICE_STATUS_ACTIVE, 'Active'],
[DEVICE_STATUS_OFFLINE, 'Offline'],
[DEVICE_STATUS_PLANNED, 'Planned'],
[DEVICE_STATUS_STAGED, 'Staged'],
[DEVICE_STATUS_FAILED, 'Failed'],
[DEVICE_STATUS_INVENTORY, 'Inventory'],
[DEVICE_STATUS_DECOMMISSIONING, 'Decommissioning'],
]
# Site statuses
SITE_STATUS_ACTIVE = 1
SITE_STATUS_PLANNED = 2
SITE_STATUS_RETIRED = 4
SITE_STATUS_CHOICES = [
[SITE_STATUS_ACTIVE, 'Active'],
[SITE_STATUS_PLANNED, 'Planned'],
[SITE_STATUS_RETIRED, 'Retired'],
]
# Bootstrap CSS classes for device/rack statuses
STATUS_CLASSES = {
0: 'warning',
1: 'success',
2: 'info',
3: 'primary',
4: 'danger',
5: 'default',
6: 'warning',
}
#
# Cabling and connections
#
# TODO: Replace with CableStatusChoices?
# Console/power/interface connection statuses
CONNECTION_STATUS_PLANNED = False
CONNECTION_STATUS_CONNECTED = True
@@ -365,71 +45,22 @@ CONNECTION_STATUS_CHOICES = [
]
# Cable endpoint types
CABLE_TERMINATION_TYPES = [
'consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination',
]
# Cable types
CABLE_TYPE_CAT3 = 1300
CABLE_TYPE_CAT5 = 1500
CABLE_TYPE_CAT5E = 1510
CABLE_TYPE_CAT6 = 1600
CABLE_TYPE_CAT6A = 1610
CABLE_TYPE_CAT7 = 1700
CABLE_TYPE_DAC_ACTIVE = 1800
CABLE_TYPE_DAC_PASSIVE = 1810
CABLE_TYPE_COAXIAL = 1900
CABLE_TYPE_MMF = 3000
CABLE_TYPE_MMF_OM1 = 3010
CABLE_TYPE_MMF_OM2 = 3020
CABLE_TYPE_MMF_OM3 = 3030
CABLE_TYPE_MMF_OM4 = 3040
CABLE_TYPE_SMF = 3500
CABLE_TYPE_SMF_OS1 = 3510
CABLE_TYPE_SMF_OS2 = 3520
CABLE_TYPE_AOC = 3800
CABLE_TYPE_POWER = 5000
CABLE_TYPE_CHOICES = (
(
'Copper', (
(CABLE_TYPE_CAT3, 'CAT3'),
(CABLE_TYPE_CAT5, 'CAT5'),
(CABLE_TYPE_CAT5E, 'CAT5e'),
(CABLE_TYPE_CAT6, 'CAT6'),
(CABLE_TYPE_CAT6A, 'CAT6a'),
(CABLE_TYPE_CAT7, 'CAT7'),
(CABLE_TYPE_DAC_ACTIVE, 'Direct Attach Copper (Active)'),
(CABLE_TYPE_DAC_PASSIVE, 'Direct Attach Copper (Passive)'),
(CABLE_TYPE_COAXIAL, 'Coaxial'),
),
),
(
'Fiber', (
(CABLE_TYPE_MMF, 'Multimode Fiber'),
(CABLE_TYPE_MMF_OM1, 'Multimode Fiber (OM1)'),
(CABLE_TYPE_MMF_OM2, 'Multimode Fiber (OM2)'),
(CABLE_TYPE_MMF_OM3, 'Multimode Fiber (OM3)'),
(CABLE_TYPE_MMF_OM4, 'Multimode Fiber (OM4)'),
(CABLE_TYPE_SMF, 'Singlemode Fiber'),
(CABLE_TYPE_SMF_OS1, 'Singlemode Fiber (OS1)'),
(CABLE_TYPE_SMF_OS2, 'Singlemode Fiber (OS2)'),
(CABLE_TYPE_AOC, 'Active Optical Cabling (AOC)'),
),
),
(CABLE_TYPE_POWER, 'Power'),
CABLE_TERMINATION_MODELS = Q(
Q(app_label='circuits', model__in=(
'circuittermination',
)) |
Q(app_label='dcim', model__in=(
'consoleport',
'consoleserverport',
'frontport',
'interface',
'powerfeed',
'poweroutlet',
'powerport',
'rearport',
))
)
CABLE_TERMINATION_TYPE_CHOICES = {
# (API endpoint, human-friendly name)
'consoleport': ('console-ports', 'Console port'),
'consoleserverport': ('console-server-ports', 'Console server port'),
'powerport': ('power-ports', 'Power port'),
'poweroutlet': ('power-outlets', 'Power outlet'),
'interface': ('interfaces', 'Interface'),
'frontport': ('front-ports', 'Front panel port'),
'rearport': ('rear-ports', 'Rear panel port'),
}
COMPATIBLE_TERMINATION_TYPES = {
'consoleport': ['consoleserverport', 'frontport', 'rearport'],
'consoleserverport': ['consoleport', 'frontport', 'rearport'],
@@ -440,57 +71,3 @@ COMPATIBLE_TERMINATION_TYPES = {
'rearport': ['consoleport', 'consoleserverport', 'interface', 'frontport', 'rearport', 'circuittermination'],
'circuittermination': ['interface', 'frontport', 'rearport'],
}
LENGTH_UNIT_METER = 1200
LENGTH_UNIT_CENTIMETER = 1100
LENGTH_UNIT_MILLIMETER = 1000
LENGTH_UNIT_FOOT = 2100
LENGTH_UNIT_INCH = 2000
CABLE_LENGTH_UNIT_CHOICES = (
(LENGTH_UNIT_METER, 'Meters'),
(LENGTH_UNIT_CENTIMETER, 'Centimeters'),
(LENGTH_UNIT_FOOT, 'Feet'),
(LENGTH_UNIT_INCH, 'Inches'),
)
RACK_DIMENSION_UNIT_CHOICES = (
(LENGTH_UNIT_MILLIMETER, 'Millimeters'),
(LENGTH_UNIT_INCH, 'Inches'),
)
# Power feeds
POWERFEED_TYPE_PRIMARY = 1
POWERFEED_TYPE_REDUNDANT = 2
POWERFEED_TYPE_CHOICES = (
(POWERFEED_TYPE_PRIMARY, 'Primary'),
(POWERFEED_TYPE_REDUNDANT, 'Redundant'),
)
POWERFEED_SUPPLY_AC = 1
POWERFEED_SUPPLY_DC = 2
POWERFEED_SUPPLY_CHOICES = (
(POWERFEED_SUPPLY_AC, 'AC'),
(POWERFEED_SUPPLY_DC, 'DC'),
)
POWERFEED_PHASE_SINGLE = 1
POWERFEED_PHASE_3PHASE = 3
POWERFEED_PHASE_CHOICES = (
(POWERFEED_PHASE_SINGLE, 'Single phase'),
(POWERFEED_PHASE_3PHASE, 'Three-phase'),
)
POWERFEED_STATUS_OFFLINE = 0
POWERFEED_STATUS_ACTIVE = 1
POWERFEED_STATUS_PLANNED = 2
POWERFEED_STATUS_FAILED = 4
POWERFEED_STATUS_CHOICES = (
(POWERFEED_STATUS_ACTIVE, 'Active'),
(POWERFEED_STATUS_OFFLINE, 'Offline'),
(POWERFEED_STATUS_PLANNED, 'Planned'),
(POWERFEED_STATUS_FAILED, 'Failed'),
)
POWERFEED_LEG_A = 1
POWERFEED_LEG_B = 2
POWERFEED_LEG_C = 3
POWERFEED_LEG_CHOICES = (
(POWERFEED_LEG_A, 'A'),
(POWERFEED_LEG_B, 'B'),
(POWERFEED_LEG_C, 'C'),
)

View File

@@ -3,14 +3,24 @@ from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from netaddr import AddrFormatError, EUI, mac_unix_expanded
from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
class ASNField(models.BigIntegerField):
description = "32-bit ASN field"
default_validators = [
MinValueValidator(1),
MaxValueValidator(4294967295),
MinValueValidator(BGP_ASN_MIN),
MaxValueValidator(BGP_ASN_MAX),
]
def formfield(self, **kwargs):
defaults = {
'min_value': BGP_ASN_MIN,
'max_value': BGP_ASN_MAX,
}
defaults.update(**kwargs)
return super().formfield(**defaults)
class mac_unix_expanded_uppercase(mac_unix_expanded):
word_fmt = '%.2X'
@@ -22,7 +32,7 @@ class MACAddressField(models.Field):
def python_type(self):
return EUI
def from_db_value(self, value, expression, connection, context):
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def to_python(self, value):

View File

@@ -1,17 +1,16 @@
import django_filters
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from extras.filters import CustomFieldFilterSet, LocalConfigContextFilter
from tenancy.filtersets import TenancyFilterSet
from extras.filters import CustomFieldFilterSet, LocalConfigContextFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet
from tenancy.models import Tenant
from utilities.constants import COLOR_CHOICES
from utilities.filters import (
MultiValueMACAddressFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter,
TreeNodeMultipleChoiceFilter,
MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter,
TagFilter, TreeNodeMultipleChoiceFilter,
)
from virtualization.models import Cluster
from .choices import *
from .constants import *
from .models import (
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
@@ -22,7 +21,46 @@ from .models import (
)
class RegionFilter(NameSlugSearchFilterSet):
__all__ = (
'CableFilterSet',
'ConsoleConnectionFilterSet',
'ConsolePortFilterSet',
'ConsolePortTemplateFilterSet',
'ConsoleServerPortFilterSet',
'ConsoleServerPortTemplateFilterSet',
'DeviceBayFilterSet',
'DeviceBayTemplateFilterSet',
'DeviceFilterSet',
'DeviceRoleFilterSet',
'DeviceTypeFilterSet',
'FrontPortFilterSet',
'FrontPortTemplateFilterSet',
'InterfaceConnectionFilterSet',
'InterfaceFilterSet',
'InterfaceTemplateFilterSet',
'InventoryItemFilterSet',
'ManufacturerFilterSet',
'PlatformFilterSet',
'PowerConnectionFilterSet',
'PowerFeedFilterSet',
'PowerOutletFilterSet',
'PowerOutletTemplateFilterSet',
'PowerPanelFilterSet',
'PowerPortFilterSet',
'PowerPortTemplateFilterSet',
'RackFilterSet',
'RackGroupFilterSet',
'RackReservationFilterSet',
'RackRoleFilterSet',
'RearPortFilterSet',
'RearPortTemplateFilterSet',
'RegionFilterSet',
'SiteFilterSet',
'VirtualChassisFilterSet',
)
class RegionFilterSet(NameSlugSearchFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=Region.objects.all(),
label='Parent region (ID)',
@@ -39,7 +77,7 @@ class RegionFilter(NameSlugSearchFilterSet):
fields = ['id', 'name', 'slug']
class SiteFilter(TenancyFilterSet, CustomFieldFilterSet):
class SiteFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -49,7 +87,7 @@ class SiteFilter(TenancyFilterSet, CustomFieldFilterSet):
label='Search',
)
status = django_filters.MultipleChoiceFilter(
choices=SITE_STATUS_CHOICES,
choices=SiteStatusChoices,
null_value=None
)
region_id = TreeNodeMultipleChoiceFilter(
@@ -93,7 +131,18 @@ class SiteFilter(TenancyFilterSet, CustomFieldFilterSet):
return queryset.filter(qs_filter)
class RackGroupFilter(NameSlugSearchFilterSet):
class RackGroupFilterSet(NameSlugSearchFilterSet):
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
queryset=Site.objects.all(),
label='Site (ID)',
@@ -110,14 +159,14 @@ class RackGroupFilter(NameSlugSearchFilterSet):
fields = ['id', 'name', 'slug']
class RackRoleFilter(NameSlugSearchFilterSet):
class RackRoleFilterSet(NameSlugSearchFilterSet):
class Meta:
model = RackRole
fields = ['id', 'name', 'slug', 'color']
class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
class RackFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -126,6 +175,17 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
queryset=Site.objects.all(),
label='Site (ID)',
@@ -147,7 +207,7 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
label='Group',
)
status = django_filters.MultipleChoiceFilter(
choices=RACK_STATUS_CHOICES,
choices=RackStatusChoices,
null_value=None
)
role_id = django_filters.ModelMultipleChoiceFilter(
@@ -184,7 +244,7 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
)
class RackReservationFilter(TenancyFilterSet):
class RackReservationFilterSet(TenancyFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -245,14 +305,14 @@ class RackReservationFilter(TenancyFilterSet):
)
class ManufacturerFilter(NameSlugSearchFilterSet):
class ManufacturerFilterSet(NameSlugSearchFilterSet):
class Meta:
model = Manufacturer
fields = ['id', 'name', 'slug']
class DeviceTypeFilter(CustomFieldFilterSet):
class DeviceTypeFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -295,6 +355,10 @@ class DeviceTypeFilter(CustomFieldFilterSet):
method='_pass_through_ports',
label='Has pass-through ports',
)
device_bays = django_filters.BooleanFilter(
method='_device_bays',
label='Has device bays',
)
tag = TagFilter()
class Meta:
@@ -334,6 +398,9 @@ class DeviceTypeFilter(CustomFieldFilterSet):
rearport_templates__isnull=value
)
def _device_bays(self, queryset, name, value):
return queryset.exclude(device_bay_templates__isnull=value)
class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
devicetype_id = django_filters.ModelMultipleChoiceFilter(
@@ -343,70 +410,70 @@ class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
)
class ConsolePortTemplateFilter(DeviceTypeComponentFilterSet):
class ConsolePortTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = ConsolePortTemplate
fields = ['id', 'name']
fields = ['id', 'name', 'type']
class ConsoleServerPortTemplateFilter(DeviceTypeComponentFilterSet):
class ConsoleServerPortTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = ConsoleServerPortTemplate
fields = ['id', 'name']
fields = ['id', 'name', 'type']
class PowerPortTemplateFilter(DeviceTypeComponentFilterSet):
class PowerPortTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = PowerPortTemplate
fields = ['id', 'name', 'maximum_draw', 'allocated_draw']
fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw']
class PowerOutletTemplateFilter(DeviceTypeComponentFilterSet):
class PowerOutletTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = PowerOutletTemplate
fields = ['id', 'name', 'feed_leg']
fields = ['id', 'name', 'type', 'feed_leg']
class InterfaceTemplateFilter(DeviceTypeComponentFilterSet):
class InterfaceTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = InterfaceTemplate
fields = ['id', 'name', 'type', 'mgmt_only']
class FrontPortTemplateFilter(DeviceTypeComponentFilterSet):
class FrontPortTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = FrontPortTemplate
fields = ['id', 'name', 'type']
class RearPortTemplateFilter(DeviceTypeComponentFilterSet):
class RearPortTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = RearPortTemplate
fields = ['id', 'name', 'type', 'positions']
class DeviceBayTemplateFilter(DeviceTypeComponentFilterSet):
class DeviceBayTemplateFilterSet(DeviceTypeComponentFilterSet):
class Meta:
model = DeviceBayTemplate
fields = ['id', 'name']
class DeviceRoleFilter(NameSlugSearchFilterSet):
class DeviceRoleFilterSet(NameSlugSearchFilterSet):
class Meta:
model = DeviceRole
fields = ['id', 'name', 'slug', 'color', 'vm_role']
class PlatformFilter(NameSlugSearchFilterSet):
class PlatformFilterSet(NameSlugSearchFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter(
field_name='manufacturer',
queryset=Manufacturer.objects.all(),
@@ -424,7 +491,7 @@ class PlatformFilter(NameSlugSearchFilterSet):
fields = ['id', 'name', 'slug', 'napalm_driver']
class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilterSet):
class DeviceFilterSet(LocalConfigContextFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -511,7 +578,7 @@ class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilter
label='Device model (slug)',
)
status = django_filters.MultipleChoiceFilter(
choices=DEVICE_STATUS_CHOICES,
choices=DeviceStatusChoices,
null_value=None
)
is_full_depth = django_filters.BooleanFilter(
@@ -562,6 +629,10 @@ class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilter
method='_pass_through_ports',
label='Has pass-through ports',
)
device_bays = django_filters.BooleanFilter(
method='_device_bays',
label='Has device bays',
)
tag = TagFilter()
class Meta:
@@ -615,17 +686,43 @@ class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilter
rearports__isnull=value
)
def _device_bays(self, queryset, name, value):
return queryset.exclude(device_bays__isnull=value)
class DeviceComponentFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site',
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site name (slug)',
)
device_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(),
label='Device (ID)',
)
device = django_filters.ModelChoiceFilter(
device = django_filters.ModelMultipleChoiceFilter(
field_name='device__name',
queryset=Device.objects.all(),
to_field_name='name',
label='Device (name)',
@@ -641,7 +738,11 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
)
class ConsolePortFilter(DeviceComponentFilterSet):
class ConsolePortFilterSet(DeviceComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices,
null_value=None
)
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -653,7 +754,11 @@ class ConsolePortFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'description', 'connection_status']
class ConsoleServerPortFilter(DeviceComponentFilterSet):
class ConsoleServerPortFilterSet(DeviceComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices,
null_value=None
)
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -665,7 +770,11 @@ class ConsoleServerPortFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'description', 'connection_status']
class PowerPortFilter(DeviceComponentFilterSet):
class PowerPortFilterSet(DeviceComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PowerPortTypeChoices,
null_value=None
)
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -677,7 +786,11 @@ class PowerPortFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'maximum_draw', 'allocated_draw', 'description', 'connection_status']
class PowerOutletFilter(DeviceComponentFilterSet):
class PowerOutletFilterSet(DeviceComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PowerOutletTypeChoices,
null_value=None
)
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -689,15 +802,14 @@ class PowerOutletFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'feed_leg', 'description', 'connection_status']
class InterfaceFilter(django_filters.FilterSet):
"""
Not using DeviceComponentFilterSet for Interfaces because we need to check for VirtualChassis membership.
"""
class InterfaceFilterSet(DeviceComponentFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
device = django_filters.CharFilter(
# Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
# members
device = MultiValueCharFilter(
method='filter_device',
field_name='name',
label='Device',
@@ -732,7 +844,7 @@ class InterfaceFilter(django_filters.FilterSet):
label='Assigned VID'
)
type = django_filters.MultipleChoiceFilter(
choices=IFACE_TYPE_CHOICES,
choices=InterfaceTypeChoices,
null_value=None
)
@@ -740,18 +852,12 @@ class InterfaceFilter(django_filters.FilterSet):
model = Interface
fields = ['id', 'name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'description']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value)
).distinct()
def filter_device(self, queryset, name, value):
try:
device = Device.objects.get(**{name: value})
vc_interface_ids = device.vc_interfaces.values_list('id', flat=True)
devices = Device.objects.filter(**{'{}__in'.format(name): value})
vc_interface_ids = []
for device in devices:
vc_interface_ids.extend(device.vc_interfaces.values_list('id', flat=True))
return queryset.filter(pk__in=vc_interface_ids)
except Device.DoesNotExist:
return queryset.none()
@@ -794,7 +900,7 @@ class InterfaceFilter(django_filters.FilterSet):
}.get(value, queryset.none())
class FrontPortFilter(DeviceComponentFilterSet):
class FrontPortFilterSet(DeviceComponentFilterSet):
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -806,7 +912,7 @@ class FrontPortFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'type', 'description']
class RearPortFilter(DeviceComponentFilterSet):
class RearPortFilterSet(DeviceComponentFilterSet):
cabled = django_filters.BooleanFilter(
field_name='cable',
lookup_expr='isnull',
@@ -818,18 +924,40 @@ class RearPortFilter(DeviceComponentFilterSet):
fields = ['id', 'name', 'type', 'positions', 'description']
class DeviceBayFilter(DeviceComponentFilterSet):
class DeviceBayFilterSet(DeviceComponentFilterSet):
class Meta:
model = DeviceBay
fields = ['id', 'name', 'description']
class InventoryItemFilter(DeviceComponentFilterSet):
class InventoryItemFilterSet(DeviceComponentFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site',
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site name (slug)',
)
device_id = django_filters.ModelChoiceFilter(
queryset=Device.objects.all(),
label='Device (ID)',
@@ -867,18 +995,29 @@ class InventoryItemFilter(DeviceComponentFilterSet):
qs_filter = (
Q(name__icontains=value) |
Q(part_id__icontains=value) |
Q(serial__iexact=value) |
Q(asset_tag__iexact=value) |
Q(serial__icontains=value) |
Q(asset_tag__icontains=value) |
Q(description__icontains=value)
)
return queryset.filter(qs_filter)
class VirtualChassisFilter(django_filters.FilterSet):
class VirtualChassisFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='master__site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='master__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='master__site',
queryset=Site.objects.all(),
@@ -917,27 +1056,50 @@ class VirtualChassisFilter(django_filters.FilterSet):
return queryset.filter(qs_filter)
class CableFilter(django_filters.FilterSet):
class CableFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
type = django_filters.MultipleChoiceFilter(
choices=CABLE_TYPE_CHOICES
choices=CableTypeChoices
)
status = django_filters.MultipleChoiceFilter(
choices=CONNECTION_STATUS_CHOICES
choices=CableStatusChoices
)
color = django_filters.MultipleChoiceFilter(
choices=COLOR_CHOICES
)
device = django_filters.CharFilter(
method='filter_connected_device',
field_name='name'
device_id = MultiValueNumberFilter(
method='filter_device'
)
device_id = django_filters.CharFilter(
method='filter_connected_device',
field_name='pk'
device = MultiValueCharFilter(
method='filter_device',
field_name='device__name'
)
rack_id = MultiValueNumberFilter(
method='filter_device',
field_name='device__rack_id'
)
rack = MultiValueNumberFilter(
method='filter_device',
field_name='device__rack__name'
)
site_id = MultiValueNumberFilter(
method='filter_device',
field_name='device__site_id'
)
site = MultiValueNumberFilter(
method='filter_device',
field_name='device__site__slug'
)
tenant_id = MultiValueNumberFilter(
method='filter_device',
field_name='device__tenant_id'
)
tenant = MultiValueNumberFilter(
method='filter_device',
field_name='device__tenant__slug'
)
class Meta:
@@ -949,25 +1111,25 @@ class CableFilter(django_filters.FilterSet):
return queryset
return queryset.filter(label__icontains=value)
def filter_connected_device(self, queryset, name, value):
if not value.strip():
return queryset
try:
device = Device.objects.get(**{name: value})
except ObjectDoesNotExist:
return queryset.none()
cable_pks = device.get_cables(pk_list=True)
return queryset.filter(pk__in=cable_pks)
def filter_device(self, queryset, name, value):
queryset = queryset.filter(
Q(**{'_termination_a_{}__in'.format(name): value}) |
Q(**{'_termination_b_{}__in'.format(name): value})
)
return queryset
class ConsoleConnectionFilter(django_filters.FilterSet):
class ConsoleConnectionFilterSet(django_filters.FilterSet):
site = django_filters.CharFilter(
method='filter_site',
label='Site (slug)',
)
device = django_filters.CharFilter(
device_id = MultiValueNumberFilter(
method='filter_device'
)
device = MultiValueCharFilter(
method='filter_device',
label='Device',
field_name='device__name'
)
class Meta:
@@ -980,22 +1142,25 @@ class ConsoleConnectionFilter(django_filters.FilterSet):
return queryset.filter(connected_endpoint__device__site__slug=value)
def filter_device(self, queryset, name, value):
if not value.strip():
if not value:
return queryset
return queryset.filter(
Q(device__name__icontains=value) |
Q(connected_endpoint__device__name__icontains=value)
Q(**{'{}__in'.format(name): value}) |
Q(**{'connected_endpoint__{}__in'.format(name): value})
)
class PowerConnectionFilter(django_filters.FilterSet):
class PowerConnectionFilterSet(django_filters.FilterSet):
site = django_filters.CharFilter(
method='filter_site',
label='Site (slug)',
)
device = django_filters.CharFilter(
device_id = MultiValueNumberFilter(
method='filter_device'
)
device = MultiValueCharFilter(
method='filter_device',
label='Device',
field_name='device__name'
)
class Meta:
@@ -1008,22 +1173,25 @@ class PowerConnectionFilter(django_filters.FilterSet):
return queryset.filter(_connected_poweroutlet__device__site__slug=value)
def filter_device(self, queryset, name, value):
if not value.strip():
if not value:
return queryset
return queryset.filter(
Q(device__name__icontains=value) |
Q(_connected_poweroutlet__device__name__icontains=value)
Q(**{'{}__in'.format(name): value}) |
Q(**{'_connected_poweroutlet__{}__in'.format(name): value})
)
class InterfaceConnectionFilter(django_filters.FilterSet):
class InterfaceConnectionFilterSet(django_filters.FilterSet):
site = django_filters.CharFilter(
method='filter_site',
label='Site (slug)',
)
device = django_filters.CharFilter(
device_id = MultiValueNumberFilter(
method='filter_device'
)
device = MultiValueCharFilter(
method='filter_device',
label='Device',
field_name='device__name'
)
class Meta:
@@ -1039,15 +1207,15 @@ class InterfaceConnectionFilter(django_filters.FilterSet):
)
def filter_device(self, queryset, name, value):
if not value.strip():
if not value:
return queryset
return queryset.filter(
Q(device__name__icontains=value) |
Q(_connected_interface__device__name__icontains=value)
Q(**{'{}__in'.format(name): value}) |
Q(**{'_connected_interface__{}__in'.format(name): value})
)
class PowerPanelFilter(django_filters.FilterSet):
class PowerPanelFilterSet(django_filters.FilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -1056,6 +1224,17 @@ class PowerPanelFilter(django_filters.FilterSet):
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
queryset=Site.objects.all(),
label='Site (ID)',
@@ -1085,7 +1264,7 @@ class PowerPanelFilter(django_filters.FilterSet):
return queryset.filter(qs_filter)
class PowerFeedFilter(CustomFieldFilterSet):
class PowerFeedFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
@@ -1094,6 +1273,17 @@ class PowerFeedFilter(CustomFieldFilterSet):
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='power_panel__site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='power_panel__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='power_panel__site',
queryset=Site.objects.all(),

View File

@@ -1910,7 +1910,7 @@
"site": 1,
"rack": 1,
"position": 1,
"face": 0,
"face": "front",
"status": true,
"primary_ip4": 1,
"primary_ip6": null,
@@ -1931,7 +1931,7 @@
"site": 1,
"rack": 1,
"position": 17,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 5,
"primary_ip6": null,
@@ -1952,7 +1952,7 @@
"site": 1,
"rack": 1,
"position": 33,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -1973,7 +1973,7 @@
"site": 1,
"rack": 1,
"position": 34,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -1994,7 +1994,7 @@
"site": 1,
"rack": 2,
"position": 34,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -2015,7 +2015,7 @@
"site": 1,
"rack": 2,
"position": 33,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -2036,7 +2036,7 @@
"site": 1,
"rack": 2,
"position": 1,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 3,
"primary_ip6": null,
@@ -2057,7 +2057,7 @@
"site": 1,
"rack": 2,
"position": 17,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 19,
"primary_ip6": null,
@@ -2078,7 +2078,7 @@
"site": 1,
"rack": 1,
"position": 42,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -2099,7 +2099,7 @@
"site": 1,
"rack": 1,
"position": null,
"face": null,
"face": "",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@@ -2120,7 +2120,7 @@
"site": 1,
"rack": 2,
"position": null,
"face": null,
"face": "",
"status": true,
"primary_ip4": null,
"primary_ip6": null,

View File

@@ -1,195 +0,0 @@
[
{
"model": "dcim.devicerole",
"pk": 1,
"fields": {
"name": "Console Server",
"slug": "console-server",
"color": "009688"
}
},
{
"model": "dcim.devicerole",
"pk": 2,
"fields": {
"name": "Core Switch",
"slug": "core-switch",
"color": "2196f3"
}
},
{
"model": "dcim.devicerole",
"pk": 3,
"fields": {
"name": "Distribution Switch",
"slug": "distribution-switch",
"color": "2196f3"
}
},
{
"model": "dcim.devicerole",
"pk": 4,
"fields": {
"name": "Access Switch",
"slug": "access-switch",
"color": "2196f3"
}
},
{
"model": "dcim.devicerole",
"pk": 5,
"fields": {
"name": "Management Switch",
"slug": "management-switch",
"color": "ff9800"
}
},
{
"model": "dcim.devicerole",
"pk": 6,
"fields": {
"name": "Firewall",
"slug": "firewall",
"color": "f44336"
}
},
{
"model": "dcim.devicerole",
"pk": 7,
"fields": {
"name": "Router",
"slug": "router",
"color": "9c27b0"
}
},
{
"model": "dcim.devicerole",
"pk": 8,
"fields": {
"name": "Server",
"slug": "server",
"color": "9e9e9e"
}
},
{
"model": "dcim.devicerole",
"pk": 9,
"fields": {
"name": "PDU",
"slug": "pdu",
"color": "607d8b"
}
},
{
"model": "dcim.manufacturer",
"pk": 1,
"fields": {
"name": "APC",
"slug": "apc"
}
},
{
"model": "dcim.manufacturer",
"pk": 2,
"fields": {
"name": "Cisco",
"slug": "cisco"
}
},
{
"model": "dcim.manufacturer",
"pk": 3,
"fields": {
"name": "Dell",
"slug": "dell"
}
},
{
"model": "dcim.manufacturer",
"pk": 4,
"fields": {
"name": "HP",
"slug": "hp"
}
},
{
"model": "dcim.manufacturer",
"pk": 5,
"fields": {
"name": "Juniper",
"slug": "juniper"
}
},
{
"model": "dcim.manufacturer",
"pk": 6,
"fields": {
"name": "Arista",
"slug": "arista"
}
},
{
"model": "dcim.manufacturer",
"pk": 7,
"fields": {
"name": "Opengear",
"slug": "opengear"
}
},
{
"model": "dcim.manufacturer",
"pk": 8,
"fields": {
"name": "Super Micro",
"slug": "super-micro"
}
},
{
"model": "dcim.platform",
"pk": 1,
"fields": {
"name": "Cisco IOS",
"slug": "cisco-ios"
}
},
{
"model": "dcim.platform",
"pk": 2,
"fields": {
"name": "Cisco NX-OS",
"slug": "cisco-nx-os"
}
},
{
"model": "dcim.platform",
"pk": 3,
"fields": {
"name": "Juniper Junos",
"slug": "juniper-junos"
}
},
{
"model": "dcim.platform",
"pk": 4,
"fields": {
"name": "Arista EOS",
"slug": "arista-eos"
}
},
{
"model": "dcim.platform",
"pk": 5,
"fields": {
"name": "Linux",
"slug": "linux"
}
},
{
"model": "dcim.platform",
"pk": 6,
"fields": {
"name": "Opengear",
"slug": "opengear"
}
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,259 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-07-31 02:06
import dcim.fields
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import utilities.fields
class Migration(migrations.Migration):
replaces = [('dcim', '0002_auto_20160622_1821'), ('dcim', '0003_auto_20160628_1721'), ('dcim', '0004_auto_20160701_2049'), ('dcim', '0005_auto_20160706_1722'), ('dcim', '0006_add_device_primary_ip4_ip6'), ('dcim', '0007_device_copy_primary_ip'), ('dcim', '0008_device_remove_primary_ip'), ('dcim', '0009_site_32bit_asn_support'), ('dcim', '0010_devicebay_installed_device_set_null'), ('dcim', '0011_devicetype_part_number'), ('dcim', '0012_site_rack_device_add_tenant'), ('dcim', '0013_add_interface_form_factors'), ('dcim', '0014_rack_add_type_width'), ('dcim', '0015_rack_add_u_height_validator'), ('dcim', '0016_module_add_manufacturer'), ('dcim', '0017_rack_add_role'), ('dcim', '0018_device_add_asset_tag'), ('dcim', '0019_new_iface_form_factors'), ('dcim', '0020_rack_desc_units'), ('dcim', '0021_add_ff_flexstack'), ('dcim', '0022_color_names_to_rgb')]
dependencies = [
('dcim', '0001_initial'),
('ipam', '0001_initial'),
('tenancy', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='device',
name='rack',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.Rack'),
),
migrations.AddField(
model_name='consoleserverporttemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cs_port_templates', to='dcim.DeviceType'),
),
migrations.AddField(
model_name='consoleserverport',
name='device',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cs_ports', to='dcim.Device'),
),
migrations.AddField(
model_name='consoleporttemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='console_port_templates', to='dcim.DeviceType'),
),
migrations.AddField(
model_name='consoleport',
name='cs_port',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connected_console', to='dcim.ConsoleServerPort', verbose_name=b'Console server port'),
),
migrations.AddField(
model_name='consoleport',
name='device',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='console_ports', to='dcim.Device'),
),
migrations.AlterUniqueTogether(
name='rackgroup',
unique_together=set([('site', 'name'), ('site', 'slug')]),
),
migrations.AlterUniqueTogether(
name='rack',
unique_together=set([('site', 'facility_id'), ('site', 'name')]),
),
migrations.AlterUniqueTogether(
name='powerporttemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AlterUniqueTogether(
name='powerport',
unique_together=set([('device', 'name')]),
),
migrations.AlterUniqueTogether(
name='poweroutlettemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AlterUniqueTogether(
name='poweroutlet',
unique_together=set([('device', 'name')]),
),
migrations.AlterUniqueTogether(
name='module',
unique_together=set([('device', 'parent', 'name')]),
),
migrations.AlterUniqueTogether(
name='interfacetemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AddField(
model_name='interface',
name='mac_address',
field=dcim.fields.MACAddressField(blank=True, null=True, verbose_name=b'MAC Address'),
),
migrations.AlterUniqueTogether(
name='interface',
unique_together=set([('device', 'name')]),
),
migrations.AddField(
model_name='devicetype',
name='subdevice_role',
field=models.NullBooleanField(choices=[(None, b'None'), (True, b'Parent'), (False, b'Child')], default=None, help_text=b'Parent devices house child devices in device bays. Select "None" if this device type is neither a parent nor a child.', verbose_name=b'Parent/child status'),
),
migrations.AlterUniqueTogether(
name='devicetype',
unique_together=set([('manufacturer', 'slug'), ('manufacturer', 'model')]),
),
migrations.AlterUniqueTogether(
name='device',
unique_together=set([('rack', 'position', 'face')]),
),
migrations.AlterUniqueTogether(
name='consoleserverporttemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AlterUniqueTogether(
name='consoleserverport',
unique_together=set([('device', 'name')]),
),
migrations.AlterUniqueTogether(
name='consoleporttemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AlterUniqueTogether(
name='consoleport',
unique_together=set([('device', 'name')]),
),
migrations.CreateModel(
name='DeviceBay',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, verbose_name=b'Name')),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_bays', to='dcim.Device')),
('installed_device', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='parent_bay', to='dcim.Device')),
],
options={
'ordering': ['device', 'name'],
},
),
migrations.CreateModel(
name='DeviceBayTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_bay_templates', to='dcim.DeviceType')),
],
options={
'ordering': ['device_type', 'name'],
},
),
migrations.AlterUniqueTogether(
name='devicebaytemplate',
unique_together=set([('device_type', 'name')]),
),
migrations.AlterUniqueTogether(
name='devicebay',
unique_together=set([('device', 'name')]),
),
migrations.AddField(
model_name='device',
name='primary_ip4',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip4_for', to='ipam.IPAddress', verbose_name=b'Primary IPv4'),
),
migrations.AddField(
model_name='device',
name='primary_ip6',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip6_for', to='ipam.IPAddress', verbose_name=b'Primary IPv6'),
),
migrations.AlterField(
model_name='site',
name='asn',
field=dcim.fields.ASNField(blank=True, null=True, verbose_name=b'ASN'),
),
migrations.AlterField(
model_name='devicebay',
name='installed_device',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.Device'),
),
migrations.AddField(
model_name='devicetype',
name='part_number',
field=models.CharField(blank=True, help_text=b'Discrete part number (optional)', max_length=50),
),
migrations.AddField(
model_name='device',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.Tenant'),
),
migrations.AddField(
model_name='rack',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.Tenant'),
),
migrations.AddField(
model_name='site',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.Tenant'),
),
migrations.AddField(
model_name='rack',
name='type',
field=models.PositiveSmallIntegerField(blank=True, choices=[(100, b'2-post frame'), (200, b'4-post frame'), (300, b'4-post cabinet'), (1000, b'Wall-mounted frame'), (1100, b'Wall-mounted cabinet')], null=True, verbose_name=b'Type'),
),
migrations.AddField(
model_name='rack',
name='width',
field=models.PositiveSmallIntegerField(choices=[(19, b'19 inches'), (23, b'23 inches')], default=19, help_text=b'Rail-to-rail width', verbose_name=b'Width'),
),
migrations.AlterField(
model_name='rack',
name='u_height',
field=models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)], verbose_name=b'Height (U)'),
),
migrations.AddField(
model_name='module',
name='manufacturer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='modules', to='dcim.Manufacturer'),
),
migrations.CreateModel(
name='RackRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)),
('slug', models.SlugField(unique=True)),
('color', utilities.fields.ColorField(max_length=6)),
],
options={
'ordering': ['name'],
},
),
migrations.AddField(
model_name='rack',
name='role',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.RackRole'),
),
migrations.AddField(
model_name='device',
name='asset_tag',
field=utilities.fields.NullableCharField(blank=True, help_text=b'A unique tag used to identify this device', max_length=50, null=True, unique=True, verbose_name=b'Asset tag'),
),
migrations.AddField(
model_name='rack',
name='desc_units',
field=models.BooleanField(default=False, help_text=b'Units are numbered top-to-bottom', verbose_name=b'Descending units'),
),
migrations.AlterField(
model_name='device',
name='position',
field=models.PositiveSmallIntegerField(blank=True, help_text=b'The lowest-numbered unit occupied by the device', null=True, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Position (U)'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='devicerole',
name='color',
field=utilities.fields.ColorField(max_length=6),
),
]

View File

@@ -0,0 +1,101 @@
import django.db.models.deletion
from django.db import migrations, models
import dcim.fields
def copy_primary_ip(apps, schema_editor):
Device = apps.get_model('dcim', 'Device')
for d in Device.objects.select_related('primary_ip'):
if not d.primary_ip:
continue
if d.primary_ip.family == 4:
d.primary_ip4 = d.primary_ip
elif d.primary_ip.family == 6:
d.primary_ip6 = d.primary_ip
d.save()
class Migration(migrations.Migration):
replaces = [('dcim', '0003_auto_20160628_1721'), ('dcim', '0004_auto_20160701_2049'), ('dcim', '0005_auto_20160706_1722'), ('dcim', '0006_add_device_primary_ip4_ip6'), ('dcim', '0007_device_copy_primary_ip'), ('dcim', '0008_device_remove_primary_ip'), ('dcim', '0009_site_32bit_asn_support'), ('dcim', '0010_devicebay_installed_device_set_null')]
dependencies = [
('ipam', '0001_initial'),
('dcim', '0002_auto_20160622_1821'),
]
operations = [
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[0, b'Virtual'], [800, b'10/100M (100BASE-TX)'], [1000, b'1GE (1000BASE-T)'], [1100, b'1GE (SFP)'], [1150, b'10GE (10GBASE-T)'], [1200, b'10GE (SFP+)'], [1300, b'10GE (XFP)'], [1400, b'40GE (QSFP+)']], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[0, b'Virtual'], [800, b'10/100M (100BASE-TX)'], [1000, b'1GE (1000BASE-T)'], [1100, b'1GE (SFP)'], [1150, b'10GE (10GBASE-T)'], [1200, b'10GE (SFP+)'], [1300, b'10GE (XFP)'], [1400, b'40GE (QSFP+)']], default=1200),
),
migrations.AddField(
model_name='devicetype',
name='subdevice_role',
field=models.NullBooleanField(choices=[(None, b'None'), (True, b'Parent'), (False, b'Child')], default=None, help_text=b'Parent devices house child devices in device bays. Select "None" if this device type is neither a parent nor a child.', verbose_name=b'Parent/child status'),
),
migrations.CreateModel(
name='DeviceBayTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_bay_templates', to='dcim.DeviceType')),
],
options={
'ordering': ['device_type', 'name'],
'unique_together': {('device_type', 'name')},
},
),
migrations.CreateModel(
name='DeviceBay',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, verbose_name=b'Name')),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_bays', to='dcim.Device')),
('installed_device', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='parent_bay', to='dcim.Device')),
],
options={
'ordering': ['device', 'name'],
'unique_together': {('device', 'name')},
},
),
migrations.AddField(
model_name='interface',
name='mac_address',
field=dcim.fields.MACAddressField(blank=True, null=True, verbose_name=b'MAC Address'),
),
migrations.AddField(
model_name='device',
name='primary_ip4',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip4_for', to='ipam.IPAddress', verbose_name=b'Primary IPv4'),
),
migrations.AddField(
model_name='device',
name='primary_ip6',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip6_for', to='ipam.IPAddress', verbose_name=b'Primary IPv6'),
),
migrations.RunPython(
code=copy_primary_ip,
),
migrations.RemoveField(
model_name='device',
name='primary_ip',
),
migrations.AlterField(
model_name='site',
name='asn',
field=dcim.fields.ASNField(blank=True, null=True, verbose_name=b'ASN'),
),
migrations.AlterField(
model_name='devicebay',
name='installed_device',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.Device'),
),
]

View File

@@ -0,0 +1,154 @@
import django.core.validators
import django.db.models.deletion
from django.db import migrations, models
import utilities.fields
COLOR_CONVERSION = {
'teal': '009688',
'green': '4caf50',
'blue': '2196f3',
'purple': '9c27b0',
'yellow': 'ffeb3b',
'orange': 'ff9800',
'red': 'f44336',
'light_gray': 'c0c0c0',
'medium_gray': '9e9e9e',
'dark_gray': '607d8b',
}
def color_names_to_rgb(apps, schema_editor):
RackRole = apps.get_model('dcim', 'RackRole')
DeviceRole = apps.get_model('dcim', 'DeviceRole')
for color_name, color_rgb in COLOR_CONVERSION.items():
RackRole.objects.filter(color=color_name).update(color=color_rgb)
DeviceRole.objects.filter(color=color_name).update(color=color_rgb)
class Migration(migrations.Migration):
replaces = [('dcim', '0011_devicetype_part_number'), ('dcim', '0012_site_rack_device_add_tenant'), ('dcim', '0013_add_interface_form_factors'), ('dcim', '0014_rack_add_type_width'), ('dcim', '0015_rack_add_u_height_validator'), ('dcim', '0016_module_add_manufacturer'), ('dcim', '0017_rack_add_role'), ('dcim', '0018_device_add_asset_tag'), ('dcim', '0019_new_iface_form_factors'), ('dcim', '0020_rack_desc_units'), ('dcim', '0021_add_ff_flexstack'), ('dcim', '0022_color_names_to_rgb')]
dependencies = [
('dcim', '0010_devicebay_installed_device_set_null'),
('tenancy', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='devicetype',
name='part_number',
field=models.CharField(blank=True, help_text=b'Discrete part number (optional)', max_length=50),
),
migrations.AddField(
model_name='device',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.Tenant'),
),
migrations.AddField(
model_name='rack',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.Tenant'),
),
migrations.AddField(
model_name='site',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.Tenant'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet', [[800, b'100BASE-TX (10/100M)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Modular', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1300, b'XFP (10GE)'], [1200, b'SFP+ (10GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet', [[800, b'100BASE-TX (10/100M)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Modular', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1300, b'XFP (10GE)'], [1200, b'SFP+ (10GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]]], default=1200),
),
migrations.AddField(
model_name='rack',
name='type',
field=models.PositiveSmallIntegerField(blank=True, choices=[(100, b'2-post frame'), (200, b'4-post frame'), (300, b'4-post cabinet'), (1000, b'Wall-mounted frame'), (1100, b'Wall-mounted cabinet')], null=True, verbose_name=b'Type'),
),
migrations.AddField(
model_name='rack',
name='width',
field=models.PositiveSmallIntegerField(choices=[(19, b'19 inches'), (23, b'23 inches')], default=19, help_text=b'Rail-to-rail width', verbose_name=b'Width'),
),
migrations.AlterField(
model_name='rack',
name='u_height',
field=models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)], verbose_name=b'Height (U)'),
),
migrations.AddField(
model_name='module',
name='manufacturer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='modules', to='dcim.Manufacturer'),
),
migrations.CreateModel(
name='RackRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)),
('slug', models.SlugField(unique=True)),
('color', models.CharField(choices=[[b'teal', b'Teal'], [b'green', b'Green'], [b'blue', b'Blue'], [b'purple', b'Purple'], [b'yellow', b'Yellow'], [b'orange', b'Orange'], [b'red', b'Red'], [b'light_gray', b'Light Gray'], [b'medium_gray', b'Medium Gray'], [b'dark_gray', b'Dark Gray']], max_length=30)),
],
options={
'ordering': ['name'],
},
),
migrations.AddField(
model_name='rack',
name='role',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.RackRole'),
),
migrations.AddField(
model_name='device',
name='asset_tag',
field=utilities.fields.NullableCharField(blank=True, help_text=b'A unique tag used to identify this device', max_length=50, null=True, unique=True, verbose_name=b'Asset tag'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AddField(
model_name='rack',
name='desc_units',
field=models.BooleanField(default=False, help_text=b'Units are numbered top-to-bottom', verbose_name=b'Descending units'),
),
migrations.AlterField(
model_name='device',
name='position',
field=models.PositiveSmallIntegerField(blank=True, help_text=b'The lowest-numbered unit occupied by the device', null=True, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Position (U)'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.RunPython(
code=color_names_to_rgb,
),
migrations.AlterField(
model_name='devicerole',
name='color',
field=utilities.fields.ColorField(max_length=6),
),
migrations.AlterField(
model_name='rackrole',
name='color',
field=utilities.fields.ColorField(max_length=6),
),
]

View File

@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-07-31 02:13
import dcim.fields
from django.conf import settings
import django.contrib.postgres.fields
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
from django.conf import settings
from django.db import migrations, models
import dcim.fields
import utilities.fields
@@ -32,8 +31,8 @@ class Migration(migrations.Migration):
replaces = [('dcim', '0023_devicetype_comments'), ('dcim', '0024_site_add_contact_fields'), ('dcim', '0025_devicetype_add_interface_ordering'), ('dcim', '0026_add_rack_reservations'), ('dcim', '0027_device_add_site'), ('dcim', '0028_device_copy_rack_to_site'), ('dcim', '0029_allow_rackless_devices'), ('dcim', '0030_interface_add_lag'), ('dcim', '0031_regions'), ('dcim', '0032_device_increase_name_length'), ('dcim', '0033_rackreservation_rack_editable'), ('dcim', '0034_rename_module_to_inventoryitem'), ('dcim', '0035_device_expand_status_choices'), ('dcim', '0036_add_ff_juniper_vcp'), ('dcim', '0037_unicode_literals'), ('dcim', '0038_wireless_interfaces'), ('dcim', '0039_interface_add_enabled_mtu'), ('dcim', '0040_inventoryitem_add_asset_tag_description'), ('dcim', '0041_napalm_integration'), ('dcim', '0042_interface_ff_10ge_cx4'), ('dcim', '0043_device_component_name_lengths')]
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('dcim', '0022_color_names_to_rgb'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
@@ -94,10 +93,15 @@ class Migration(migrations.Migration):
name='site',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.Site'),
),
migrations.AddField(
migrations.AlterField(
model_name='interface',
name='lag',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.Interface', verbose_name='Parent LAG'),
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual'], [200, b'Link Aggregation Group (LAG)']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual'], [200, b'Link Aggregation Group (LAG)']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.CreateModel(
name='Region',
@@ -157,7 +161,17 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='device',
name='status',
field=models.PositiveSmallIntegerField(choices=[[1, 'Active'], [0, 'Offline'], [2, 'Planned'], [3, 'Staged'], [4, 'Failed'], [5, 'Inventory']], default=1, verbose_name='Status'),
field=models.PositiveSmallIntegerField(choices=[[1, b'Active'], [0, b'Offline'], [2, b'Planned'], [3, b'Staged'], [4, b'Failed'], [5, b'Inventory']], default=1, verbose_name=b'Status'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual'], [200, b'Link Aggregation Group (LAG)']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus'], [5200, b'Juniper VCP']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual'], [200, b'Link Aggregation Group (LAG)']]], [b'Ethernet (fixed)', [[800, b'100BASE-TX (10/100ME)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Ethernet (modular)', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1200, b'SFP+ (10GE)'], [1300, b'XFP (10GE)'], [1310, b'XENPAK (10GE)'], [1320, b'X2 (10GE)'], [1350, b'SFP28 (25GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'FibreChannel', [[3010, b'SFP (1GFC)'], [3020, b'SFP (2GFC)'], [3040, b'SFP (4GFC)'], [3080, b'SFP+ (8GFC)'], [3160, b'SFP+ (16GFC)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus'], [5100, b'Cisco FlexStack'], [5150, b'Cisco FlexStack Plus'], [5200, b'Juniper VCP']]], [b'Other', [[32767, b'Other']]]], default=1200),
),
migrations.AlterField(
model_name='consoleport',
@@ -199,6 +213,11 @@ class Migration(migrations.Migration):
name='serial',
field=models.CharField(blank=True, max_length=50, verbose_name='Serial number'),
),
migrations.AlterField(
model_name='device',
name='status',
field=models.PositiveSmallIntegerField(choices=[[1, 'Active'], [0, 'Offline'], [2, 'Planned'], [3, 'Staged'], [4, 'Failed'], [5, 'Inventory']], default=1, verbose_name='Status'),
),
migrations.AlterField(
model_name='devicebay',
name='name',
@@ -244,6 +263,16 @@ class Migration(migrations.Migration):
name='u_height',
field=models.PositiveSmallIntegerField(default=1, verbose_name='Height (U)'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1600, 'QSFP28 (100GE)']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AddField(
model_name='interface',
name='lag',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.Interface', verbose_name='Parent LAG'),
),
migrations.AlterField(
model_name='interface',
name='mac_address',
@@ -259,6 +288,11 @@ class Migration(migrations.Migration):
name='connection_status',
field=models.BooleanField(choices=[[False, 'Planned'], [True, 'Connected']], default=True, verbose_name='Status'),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1600, 'QSFP28 (100GE)']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='mgmt_only',
@@ -329,6 +363,16 @@ class Migration(migrations.Migration):
name='contact_email',
field=models.EmailField(blank=True, max_length=254, verbose_name='Contact E-mail'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AddField(
model_name='interface',
name='enabled',

View File

@@ -1,144 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-07-31 02:17
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import timezone_field.fields
import utilities.fields
class Migration(migrations.Migration):
replaces = [('dcim', '0044_virtualization'), ('dcim', '0045_devicerole_vm_role'), ('dcim', '0046_rack_lengthen_facility_id'), ('dcim', '0047_more_100ge_form_factors'), ('dcim', '0048_rack_serial'), ('dcim', '0049_rackreservation_change_user'), ('dcim', '0050_interface_vlan_tagging'), ('dcim', '0051_rackreservation_tenant'), ('dcim', '0052_virtual_chassis'), ('dcim', '0053_platform_manufacturer'), ('dcim', '0054_site_status_timezone_description'), ('dcim', '0055_virtualchassis_ordering')]
dependencies = [
('dcim', '0043_device_component_name_lengths'),
('ipam', '0020_ipaddress_add_role_carp'),
('virtualization', '0001_virtualization'),
('tenancy', '0003_unicode_literals'),
]
operations = [
migrations.AddField(
model_name='device',
name='cluster',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.Cluster'),
),
migrations.AddField(
model_name='interface',
name='virtual_machine',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.VirtualMachine'),
),
migrations.AlterField(
model_name='interface',
name='device',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='dcim.Device'),
),
migrations.AddField(
model_name='devicerole',
name='vm_role',
field=models.BooleanField(default=True, help_text='Virtual machines may be assigned to this role', verbose_name='VM Role'),
),
migrations.AlterField(
model_name='rack',
name='facility_id',
field=utilities.fields.NullableCharField(blank=True, max_length=50, null=True, verbose_name='Facility ID'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AddField(
model_name='rack',
name='serial',
field=models.CharField(blank=True, max_length=50, verbose_name='Serial number'),
),
migrations.AlterField(
model_name='rackreservation',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='interface',
name='mode',
field=models.PositiveSmallIntegerField(blank=True, choices=[[100, 'Access'], [200, 'Tagged'], [300, 'Tagged All']], null=True),
),
migrations.AddField(
model_name='interface',
name='tagged_vlans',
field=models.ManyToManyField(blank=True, related_name='interfaces_as_tagged', to='ipam.VLAN', verbose_name='Tagged VLANs'),
),
migrations.AddField(
model_name='interface',
name='untagged_vlan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interfaces_as_untagged', to='ipam.VLAN', verbose_name='Untagged VLAN'),
),
migrations.AddField(
model_name='rackreservation',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.Tenant'),
),
migrations.CreateModel(
name='VirtualChassis',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(blank=True, max_length=30)),
('master', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.Device')),
],
options={
'verbose_name_plural': 'virtual chassis',
'ordering': ['master'],
},
),
migrations.AddField(
model_name='device',
name='virtual_chassis',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.VirtualChassis'),
),
migrations.AddField(
model_name='device',
name='vc_position',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]),
),
migrations.AddField(
model_name='device',
name='vc_priority',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]),
),
migrations.AlterUniqueTogether(
name='device',
unique_together=set([('rack', 'position', 'face'), ('virtual_chassis', 'vc_position')]),
),
migrations.AddField(
model_name='platform',
name='manufacturer',
field=models.ForeignKey(blank=True, help_text='Optionally limit this platform to devices of a certain manufacturer', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='platforms', to='dcim.Manufacturer'),
),
migrations.AlterField(
model_name='platform',
name='napalm_driver',
field=models.CharField(blank=True, help_text='The name of the NAPALM driver to use when interacting with devices', max_length=50, verbose_name='NAPALM driver'),
),
migrations.AddField(
model_name='site',
name='description',
field=models.CharField(blank=True, max_length=100),
),
migrations.AddField(
model_name='site',
name='status',
field=models.PositiveSmallIntegerField(choices=[[1, 'Active'], [2, 'Planned'], [4, 'Retired']], default=1),
),
migrations.AddField(
model_name='site',
name='time_zone',
field=timezone_field.fields.TimeZoneField(blank=True),
),
]

View File

@@ -0,0 +1,354 @@
import django.contrib.postgres.fields.jsonb
import django.core.validators
import django.db.models.deletion
import taggit.managers
import timezone_field.fields
from django.conf import settings
from django.db import migrations, models
import utilities.fields
class Migration(migrations.Migration):
replaces = [('dcim', '0044_virtualization'), ('dcim', '0045_devicerole_vm_role'), ('dcim', '0046_rack_lengthen_facility_id'), ('dcim', '0047_more_100ge_form_factors'), ('dcim', '0048_rack_serial'), ('dcim', '0049_rackreservation_change_user'), ('dcim', '0050_interface_vlan_tagging'), ('dcim', '0051_rackreservation_tenant'), ('dcim', '0052_virtual_chassis'), ('dcim', '0053_platform_manufacturer'), ('dcim', '0054_site_status_timezone_description'), ('dcim', '0055_virtualchassis_ordering'), ('dcim', '0056_django2'), ('dcim', '0057_tags'), ('dcim', '0058_relax_rack_naming_constraints'), ('dcim', '0059_site_latitude_longitude'), ('dcim', '0060_change_logging'), ('dcim', '0061_platform_napalm_args')]
dependencies = [
('virtualization', '0001_virtualization'),
('tenancy', '0003_unicode_literals'),
('ipam', '0020_ipaddress_add_role_carp'),
('dcim', '0043_device_component_name_lengths'),
('taggit', '0002_auto_20150616_2121'),
]
operations = [
migrations.AddField(
model_name='device',
name='cluster',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.Cluster'),
),
migrations.AddField(
model_name='interface',
name='virtual_machine',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.VirtualMachine'),
),
migrations.AlterField(
model_name='interface',
name='device',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='dcim.Device'),
),
migrations.AddField(
model_name='devicerole',
name='vm_role',
field=models.BooleanField(default=True, help_text='Virtual machines may be assigned to this role', verbose_name='VM Role'),
),
migrations.AlterField(
model_name='rack',
name='facility_id',
field=utilities.fields.NullableCharField(blank=True, max_length=50, null=True, verbose_name='Facility ID'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AddField(
model_name='rack',
name='serial',
field=models.CharField(blank=True, max_length=50, verbose_name='Serial number'),
),
migrations.AlterField(
model_name='rackreservation',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='interface',
name='mode',
field=models.PositiveSmallIntegerField(blank=True, choices=[[100, 'Access'], [200, 'Tagged'], [300, 'Tagged All']], null=True),
),
migrations.AddField(
model_name='interface',
name='tagged_vlans',
field=models.ManyToManyField(blank=True, related_name='interfaces_as_tagged', to='ipam.VLAN', verbose_name='Tagged VLANs'),
),
migrations.AddField(
model_name='rackreservation',
name='tenant',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.Tenant'),
),
migrations.CreateModel(
name='VirtualChassis',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(blank=True, max_length=30)),
('master', models.OneToOneField(default=1, on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.Device')),
],
options={
'ordering': ['master'],
'verbose_name_plural': 'virtual chassis',
},
),
migrations.AddField(
model_name='device',
name='virtual_chassis',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.VirtualChassis'),
),
migrations.AddField(
model_name='device',
name='vc_position',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]),
),
migrations.AddField(
model_name='device',
name='vc_priority',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]),
),
migrations.AlterUniqueTogether(
name='device',
unique_together={('rack', 'position', 'face'), ('virtual_chassis', 'vc_position')},
),
migrations.AlterField(
model_name='platform',
name='napalm_driver',
field=models.CharField(blank=True, help_text='The name of the NAPALM driver to use when interacting with devices', max_length=50, verbose_name='NAPALM driver'),
),
migrations.AddField(
model_name='site',
name='description',
field=models.CharField(blank=True, max_length=100),
),
migrations.AddField(
model_name='site',
name='status',
field=models.PositiveSmallIntegerField(choices=[[1, 'Active'], [2, 'Planned'], [4, 'Retired']], default=1),
),
migrations.AddField(
model_name='site',
name='time_zone',
field=timezone_field.fields.TimeZoneField(blank=True),
),
migrations.AlterField(
model_name='virtualchassis',
name='master',
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.Device'),
),
migrations.AddField(
model_name='interface',
name='untagged_vlan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces_as_untagged', to='ipam.VLAN', verbose_name='Untagged VLAN'),
),
migrations.AddField(
model_name='platform',
name='manufacturer',
field=models.ForeignKey(blank=True, help_text='Optionally limit this platform to devices of a certain manufacturer', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='dcim.Manufacturer'),
),
migrations.AddField(
model_name='device',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='devicetype',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='rack',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='site',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='consoleport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='consoleserverport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='devicebay',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='interface',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='inventoryitem',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='poweroutlet',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='powerport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AddField(
model_name='virtualchassis',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
),
migrations.AlterModelOptions(
name='rack',
options={'ordering': ['site', 'group', 'name']},
),
migrations.AlterUniqueTogether(
name='rack',
unique_together={('group', 'name'), ('group', 'facility_id')},
),
migrations.AddField(
model_name='site',
name='latitude',
field=models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True),
),
migrations.AddField(
model_name='site',
name='longitude',
field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True),
),
migrations.AddField(
model_name='devicerole',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='devicerole',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='devicetype',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='devicetype',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='manufacturer',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='manufacturer',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='platform',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='platform',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='rackgroup',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='rackgroup',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='rackreservation',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='rackrole',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='rackrole',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='region',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='region',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='virtualchassis',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='virtualchassis',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AlterField(
model_name='device',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='device',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AlterField(
model_name='rack',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='rack',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AlterField(
model_name='rackreservation',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='site',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='site',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='platform',
name='napalm_args',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, help_text='Additional arguments to pass when initiating the NAPALM driver (JSON format)', null=True, verbose_name='NAPALM arguments'),
),
]

View File

@@ -0,0 +1,124 @@
import django.contrib.postgres.fields.jsonb
import django.core.validators
import django.db.models.deletion
import taggit.managers
from django.db import migrations, models
class Migration(migrations.Migration):
replaces = [('dcim', '0062_interface_mtu'), ('dcim', '0063_device_local_context_data'), ('dcim', '0064_remove_platform_rpc_client'), ('dcim', '0065_front_rear_ports')]
dependencies = [
('taggit', '0002_auto_20150616_2121'),
('dcim', '0061_platform_napalm_args'),
]
operations = [
migrations.AlterField(
model_name='interface',
name='mtu',
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)], verbose_name='MTU'),
),
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['SONET', [[6100, 'OC-3/STM-1'], [6200, 'OC-12/STM-4'], [6300, 'OC-48/STM-16'], [6400, 'OC-192/STM-64'], [6500, 'OC-768/STM-256'], [6600, 'OC-1920/STM-640'], [6700, 'OC-3840/STM-1234']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)'], [3320, 'SFP28 (32GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP'], [5300, 'Extreme SummitStack'], [5310, 'Extreme SummitStack-128'], [5320, 'Extreme SummitStack-256'], [5330, 'Extreme SummitStack-512']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[['Virtual interfaces', [[0, 'Virtual'], [200, 'Link Aggregation Group (LAG)']]], ['Ethernet (fixed)', [[800, '100BASE-TX (10/100ME)'], [1000, '1000BASE-T (1GE)'], [1150, '10GBASE-T (10GE)'], [1170, '10GBASE-CX4 (10GE)']]], ['Ethernet (modular)', [[1050, 'GBIC (1GE)'], [1100, 'SFP (1GE)'], [1200, 'SFP+ (10GE)'], [1300, 'XFP (10GE)'], [1310, 'XENPAK (10GE)'], [1320, 'X2 (10GE)'], [1350, 'SFP28 (25GE)'], [1400, 'QSFP+ (40GE)'], [1500, 'CFP (100GE)'], [1510, 'CFP2 (100GE)'], [1520, 'CFP4 (100GE)'], [1550, 'Cisco CPAK (100GE)'], [1600, 'QSFP28 (100GE)']]], ['Wireless', [[2600, 'IEEE 802.11a'], [2610, 'IEEE 802.11b/g'], [2620, 'IEEE 802.11n'], [2630, 'IEEE 802.11ac'], [2640, 'IEEE 802.11ad']]], ['SONET', [[6100, 'OC-3/STM-1'], [6200, 'OC-12/STM-4'], [6300, 'OC-48/STM-16'], [6400, 'OC-192/STM-64'], [6500, 'OC-768/STM-256'], [6600, 'OC-1920/STM-640'], [6700, 'OC-3840/STM-1234']]], ['FibreChannel', [[3010, 'SFP (1GFC)'], [3020, 'SFP (2GFC)'], [3040, 'SFP (4GFC)'], [3080, 'SFP+ (8GFC)'], [3160, 'SFP+ (16GFC)'], [3320, 'SFP28 (32GFC)']]], ['Serial', [[4000, 'T1 (1.544 Mbps)'], [4010, 'E1 (2.048 Mbps)'], [4040, 'T3 (45 Mbps)'], [4050, 'E3 (34 Mbps)']]], ['Stacking', [[5000, 'Cisco StackWise'], [5050, 'Cisco StackWise Plus'], [5100, 'Cisco FlexStack'], [5150, 'Cisco FlexStack Plus'], [5200, 'Juniper VCP'], [5300, 'Extreme SummitStack'], [5310, 'Extreme SummitStack-128'], [5320, 'Extreme SummitStack-256'], [5330, 'Extreme SummitStack-512']]], ['Other', [[32767, 'Other']]]], default=1200),
),
migrations.AddField(
model_name='device',
name='local_context_data',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True),
),
migrations.RemoveField(
model_name='platform',
name='rpc_client',
),
migrations.CreateModel(
name='RearPort',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64)),
('type', models.PositiveSmallIntegerField()),
('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(64)])),
('description', models.CharField(blank=True, max_length=100)),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rearports', to='dcim.Device')),
('tags', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
],
options={
'ordering': ['device', 'name'],
'unique_together': {('device', 'name')},
},
),
migrations.CreateModel(
name='RearPortTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64)),
('type', models.PositiveSmallIntegerField()),
('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(64)])),
('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rearport_templates', to='dcim.DeviceType')),
],
options={
'ordering': ['device_type', 'name'],
'unique_together': {('device_type', 'name')},
},
),
migrations.CreateModel(
name='FrontPortTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64)),
('type', models.PositiveSmallIntegerField()),
('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(64)])),
('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.DeviceType')),
('rear_port', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.RearPortTemplate')),
],
options={
'ordering': ['device_type', 'name'],
'unique_together': {('rear_port', 'rear_port_position'), ('device_type', 'name')},
},
),
migrations.CreateModel(
name='FrontPort',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64)),
('type', models.PositiveSmallIntegerField()),
('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(64)])),
('description', models.CharField(blank=True, max_length=100)),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.Device')),
('rear_port', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.RearPort')),
('tags', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
],
options={
'ordering': ['device', 'name'],
'unique_together': {('device', 'name'), ('rear_port', 'rear_port_position')},
},
),
migrations.AlterField(
model_name='consoleporttemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleport_templates', to='dcim.DeviceType'),
),
migrations.AlterField(
model_name='consoleserverporttemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverport_templates', to='dcim.DeviceType'),
),
migrations.AlterField(
model_name='poweroutlettemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlet_templates', to='dcim.DeviceType'),
),
migrations.AlterField(
model_name='powerporttemplate',
name='device_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='powerport_templates', to='dcim.DeviceType'),
),
]

View File

@@ -174,8 +174,8 @@ class Migration(migrations.Migration):
('length', models.PositiveSmallIntegerField(blank=True, null=True)),
('length_unit', models.PositiveSmallIntegerField(blank=True, null=True)),
('_abs_length', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)),
('termination_a_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_b_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_a_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination', 'powerfeed']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_b_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination', 'powerfeed']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
],
),
migrations.AlterUniqueTogether(

View File

@@ -0,0 +1,146 @@
import taggit.managers
from django.db import migrations, models
class Migration(migrations.Migration):
replaces = [('dcim', '0067_device_type_remove_qualifiers'), ('dcim', '0068_rack_new_fields'), ('dcim', '0069_deprecate_nullablecharfield'), ('dcim', '0070_custom_tag_models')]
dependencies = [
('extras', '0019_tag_taggeditem'),
('dcim', '0066_cables'),
]
operations = [
migrations.RemoveField(
model_name='devicetype',
name='is_console_server',
),
migrations.RemoveField(
model_name='devicetype',
name='is_network_device',
),
migrations.RemoveField(
model_name='devicetype',
name='is_pdu',
),
migrations.RemoveField(
model_name='devicetype',
name='interface_ordering',
),
migrations.AddField(
model_name='rack',
name='status',
field=models.PositiveSmallIntegerField(default=3),
),
migrations.AddField(
model_name='rack',
name='outer_depth',
field=models.PositiveSmallIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='rack',
name='outer_unit',
field=models.PositiveSmallIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='rack',
name='outer_width',
field=models.PositiveSmallIntegerField(blank=True, null=True),
),
migrations.AlterField(
model_name='device',
name='asset_tag',
field=models.CharField(blank=True, max_length=50, null=True, unique=True),
),
migrations.AlterField(
model_name='device',
name='name',
field=models.CharField(blank=True, max_length=64, null=True, unique=True),
),
migrations.AlterField(
model_name='inventoryitem',
name='asset_tag',
field=models.CharField(blank=True, max_length=50, null=True, unique=True),
),
migrations.AddField(
model_name='rack',
name='asset_tag',
field=models.CharField(blank=True, max_length=50, null=True, unique=True),
),
migrations.AlterField(
model_name='rack',
name='facility_id',
field=models.CharField(blank=True, max_length=50, null=True),
),
migrations.AlterField(
model_name='consoleport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='consoleserverport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='device',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='devicebay',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='devicetype',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='frontport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='interface',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='inventoryitem',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='poweroutlet',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='powerport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='rack',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='rearport',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='site',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
migrations.AlterField(
model_name='virtualchassis',
name='tags',
field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='extras.TaggedItem', to='extras.Tag', verbose_name='Tags'),
),
]

Some files were not shown because too many files have changed in this diff Show More