Skip to content

Commit 2d68b7d

Browse files
authored
Merge pull request #364 from nautobot/release/v2.1.2
Release v2.1.2
2 parents 2e2643a + ba8e107 commit 2d68b7d

14 files changed

+275
-41
lines changed

changes/323.housekeeping

-1
This file was deleted.

development/towncrier_template.j2

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
{% if render_title %}
3-
## [v{{ versiondata.version }} ({{ versiondata.date }})]({{ cookiecutter.repo_url }}/releases/tag/v{{ versiondata.version}})
3+
## [v{{ versiondata.version }} ({{ versiondata.date }})](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/releases/tag/v{{ versiondata.version}})
44

55
{% endif %}
66
{% for section, _ in sections.items() %}
@@ -27,4 +27,3 @@ No significant changes.
2727

2828
{% endif %}
2929
{% endfor %}
30-

docs/admin/compatibility_matrix.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
| Device Lifecycle Management Version | Nautobot First Support Version | Nautobot Last Support Version |
44
| ------------- | -------------------- | ------------- |
5-
| 2.1.X | 2.0.0 | 2.99.99 |
6-
| 2.0.X | 2.0.0 | 2.99.99 |
5+
| 2.1.2-2.1.X | 2.0.0 | 2.99.99 |
6+
| 2.1.0-2.1.1 | 2.0.0 | 2.2.99 |
7+
| 2.0.X | 2.0.0 | 2.2.99 |
78
| 1.6.X | 1.4.0 | 1.6.X |
89
| 1.3.X | 1.4.0 | 1.X.X |
910
| 1.2.X | 1.4.0 | 1.X.X |
10-
| 1.1.X | 1.2.0 | 1.5.9 |
11-
| 1.0.X | 1.1.6 | 1.5.9 |
12-
| 0.4.X | 1.1.6 | 1.4.0 |
11+
| 1.1.X | 1.2.0 | 1.5.9 |
12+
| 1.0.X | 1.1.6 | 1.5.9 |
13+
| 0.4.X | 1.1.6 | 1.4.0 |

docs/admin/release_notes/version_2.1.md

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ This document describes all new features and changes in the release `2.1`. The f
66

77
This release adds support for various improvements, bug fixes, and performance improvements.
88

9+
<!-- towncrier release notes start -->
10+
## [v2.1.2 (2024-08-08)](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/releases/tag/v2.1.2)
11+
12+
### Added
13+
14+
- [#344](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/344) - Added number field to Contract retrieve template.
15+
- [#348](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/348) - Updated Device Software Validation Reports Bar Graph x-axis label modification.
16+
- [#360](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/360) - Added support for Django 4.
17+
18+
### Changed
19+
20+
- [#328](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/328) - Updated the max character length on majority of text fields.
21+
22+
### Fixed
23+
24+
- [#346](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/346) - Fixed documentation view missing.
25+
- [#360](https://github.com/nautobot/nautobot-app-device-lifecycle-mgmt/issues/360) - Fixed Nautobot v2.3 incompatibility.
26+
927
## [v2.1.1] - 2024-04-08
1028

1129
### Fixed

nautobot_device_lifecycle_mgmt/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class NautobotDeviceLifecycleManagementConfig(NautobotAppConfig):
2727
"barchart_height": 5,
2828
}
2929
caching_config = {}
30+
docs_view_name = "plugins:nautobot_device_lifecycle_mgmt:docs"
3031

3132
def ready(self):
3233
"""Register custom signals."""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Generated by Django 3.2.21 on 2024-04-27 19:03
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("nautobot_device_lifecycle_mgmt", "0020_alter_created_tags"),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name="contactlcm",
14+
name="address",
15+
field=models.CharField(blank=True, max_length=255),
16+
),
17+
migrations.AlterField(
18+
model_name="contactlcm",
19+
name="name",
20+
field=models.CharField(max_length=255, null=True),
21+
),
22+
migrations.AlterField(
23+
model_name="contactlcm",
24+
name="phone",
25+
field=models.CharField(blank=True, max_length=255),
26+
),
27+
migrations.AlterField(
28+
model_name="contactlcm",
29+
name="type",
30+
field=models.CharField(default="Unassigned", max_length=255),
31+
),
32+
migrations.AlterField(
33+
model_name="contractlcm",
34+
name="contract_type",
35+
field=models.CharField(blank=True, default="", max_length=255),
36+
),
37+
migrations.AlterField(
38+
model_name="contractlcm",
39+
name="name",
40+
field=models.CharField(max_length=255, unique=True),
41+
),
42+
migrations.AlterField(
43+
model_name="contractlcm",
44+
name="number",
45+
field=models.CharField(blank=True, default="", max_length=255),
46+
),
47+
migrations.AlterField(
48+
model_name="contractlcm",
49+
name="support_level",
50+
field=models.CharField(blank=True, default="", max_length=255),
51+
),
52+
migrations.AlterField(
53+
model_name="cvelcm",
54+
name="name",
55+
field=models.CharField(max_length=255, unique=True),
56+
),
57+
migrations.AlterField(
58+
model_name="cvelcm",
59+
name="severity",
60+
field=models.CharField(default="None", max_length=255),
61+
),
62+
migrations.AlterField(
63+
model_name="devicesoftwarevalidationresult",
64+
name="run_type",
65+
field=models.CharField(max_length=255),
66+
),
67+
migrations.AlterField(
68+
model_name="inventoryitemsoftwarevalidationresult",
69+
name="run_type",
70+
field=models.CharField(max_length=255),
71+
),
72+
migrations.AlterField(
73+
model_name="providerlcm",
74+
name="description",
75+
field=models.CharField(blank=True, max_length=255),
76+
),
77+
migrations.AlterField(
78+
model_name="providerlcm",
79+
name="name",
80+
field=models.CharField(max_length=255, unique=True),
81+
),
82+
migrations.AlterField(
83+
model_name="providerlcm",
84+
name="phone",
85+
field=models.CharField(blank=True, max_length=255),
86+
),
87+
migrations.AlterField(
88+
model_name="providerlcm",
89+
name="physical_address",
90+
field=models.CharField(blank=True, max_length=255),
91+
),
92+
migrations.AlterField(
93+
model_name="softwareimagelcm",
94+
name="hashing_algorithm",
95+
field=models.CharField(blank=True, default="", max_length=255),
96+
),
97+
migrations.AlterField(
98+
model_name="softwareimagelcm",
99+
name="image_file_name",
100+
field=models.CharField(max_length=255),
101+
),
102+
migrations.AlterField(
103+
model_name="softwarelcm",
104+
name="alias",
105+
field=models.CharField(blank=True, default="", max_length=255),
106+
),
107+
migrations.AlterField(
108+
model_name="softwarelcm",
109+
name="version",
110+
field=models.CharField(max_length=255),
111+
),
112+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Generated by Django 4.2.14 on 2024-08-05 22:28
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("nautobot_device_lifecycle_mgmt", "0021_update_max_char_length"),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name="softwareimagelcm",
14+
name="inventory_items",
15+
field=models.ManyToManyField(blank=True, related_name="+", to="dcim.inventoryitem"),
16+
),
17+
migrations.AlterField(
18+
model_name="softwareimagelcm",
19+
name="object_tags",
20+
field=models.ManyToManyField(blank=True, related_name="+", to="extras.tag"),
21+
),
22+
migrations.AlterField(
23+
model_name="validatedsoftwarelcm",
24+
name="device_roles",
25+
field=models.ManyToManyField(blank=True, related_name="+", to="extras.role"),
26+
),
27+
migrations.AlterField(
28+
model_name="validatedsoftwarelcm",
29+
name="device_types",
30+
field=models.ManyToManyField(blank=True, related_name="+", to="dcim.devicetype"),
31+
),
32+
migrations.AlterField(
33+
model_name="validatedsoftwarelcm",
34+
name="devices",
35+
field=models.ManyToManyField(blank=True, related_name="+", to="dcim.device"),
36+
),
37+
migrations.AlterField(
38+
model_name="validatedsoftwarelcm",
39+
name="inventory_items",
40+
field=models.ManyToManyField(blank=True, related_name="+", to="dcim.inventoryitem"),
41+
),
42+
migrations.AlterField(
43+
model_name="validatedsoftwarelcm",
44+
name="object_tags",
45+
field=models.ManyToManyField(blank=True, related_name="+", to="extras.tag"),
46+
),
47+
]

nautobot_device_lifecycle_mgmt/models.py

+34-22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
# from django.urls import reverse
88
from django.core.exceptions import ValidationError
99
from django.db import models
10+
11+
try:
12+
from nautobot.apps.constants import CHARFIELD_MAX_LENGTH
13+
except ImportError:
14+
CHARFIELD_MAX_LENGTH = 255
15+
1016
from nautobot.core.models.generics import OrganizationalModel, PrimaryModel
1117
from nautobot.core.models.querysets import RestrictedQuerySet
1218
from nautobot.dcim.models import Device, DeviceType, InventoryItem
@@ -45,7 +51,7 @@ class HardwareLCM(PrimaryModel):
4551
null=True,
4652
)
4753
inventory_item = models.CharField( # pylint: disable=nb-string-field-blank-null
48-
verbose_name="Inventory Item Part", max_length=255, blank=True, null=True
54+
verbose_name="Inventory Item Part", max_length=CHARFIELD_MAX_LENGTH, blank=True, null=True
4955
)
5056
release_date = models.DateField(null=True, blank=True, verbose_name="Release Date")
5157
end_of_sale = models.DateField(null=True, blank=True, verbose_name="End of Sale")
@@ -157,8 +163,8 @@ class SoftwareLCM(PrimaryModel):
157163
"""Software Life-Cycle Management model."""
158164

159165
device_platform = models.ForeignKey(to="dcim.Platform", on_delete=models.CASCADE, verbose_name="Device Platform")
160-
version = models.CharField(max_length=50)
161-
alias = models.CharField(max_length=50, blank=True, default="")
166+
version = models.CharField(max_length=CHARFIELD_MAX_LENGTH)
167+
alias = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True, default="")
162168
release_date = models.DateField(null=True, blank=True, verbose_name="Release Date")
163169
end_of_support = models.DateField(null=True, blank=True, verbose_name="End of Software Support")
164170
documentation_url = models.URLField(blank=True, verbose_name="Documentation URL")
@@ -212,7 +218,7 @@ def get_for_object(self, obj):
212218
class SoftwareImageLCM(PrimaryModel):
213219
"""SoftwareImageLCM model."""
214220

215-
image_file_name = models.CharField(blank=False, max_length=100, verbose_name="Image File Name")
221+
image_file_name = models.CharField(blank=False, max_length=CHARFIELD_MAX_LENGTH, verbose_name="Image File Name")
216222
software = models.ForeignKey(
217223
to="SoftwareLCM", on_delete=models.CASCADE, related_name="software_images", verbose_name="Software Version"
218224
)
@@ -221,7 +227,9 @@ class SoftwareImageLCM(PrimaryModel):
221227
object_tags = models.ManyToManyField(to="extras.Tag", related_name="+", blank=True)
222228
download_url = models.URLField(blank=True, verbose_name="Download URL")
223229
image_file_checksum = models.CharField(blank=True, max_length=256, verbose_name="Image File Checksum")
224-
hashing_algorithm = models.CharField(default="", blank=True, max_length=32, verbose_name="Hashing Algorithm")
230+
hashing_algorithm = models.CharField(
231+
default="", blank=True, max_length=CHARFIELD_MAX_LENGTH, verbose_name="Hashing Algorithm"
232+
)
225233
default_image = models.BooleanField(verbose_name="Default Image", default=False)
226234

227235
class Meta:
@@ -341,7 +349,7 @@ class DeviceSoftwareValidationResult(PrimaryModel):
341349
)
342350
is_validated = models.BooleanField(null=True, blank=True)
343351
last_run = models.DateTimeField(null=True, blank=True)
344-
run_type = models.CharField(max_length=50, choices=choices.ReportRunTypeChoices)
352+
run_type = models.CharField(max_length=CHARFIELD_MAX_LENGTH, choices=choices.ReportRunTypeChoices)
345353
valid_software = models.ManyToManyField(
346354
to="ValidatedSoftwareLCM", related_name="device_software_validation_results"
347355
)
@@ -378,7 +386,7 @@ class InventoryItemSoftwareValidationResult(PrimaryModel):
378386
)
379387
is_validated = models.BooleanField(null=True, blank=True)
380388
last_run = models.DateTimeField(null=True, blank=True)
381-
run_type = models.CharField(max_length=50, choices=choices.ReportRunTypeChoices)
389+
run_type = models.CharField(max_length=CHARFIELD_MAX_LENGTH, choices=choices.ReportRunTypeChoices)
382390
valid_software = models.ManyToManyField(
383391
to="ValidatedSoftwareLCM", related_name="inventory_item_software_validation_results"
384392
)
@@ -421,14 +429,18 @@ class ContractLCM(PrimaryModel):
421429
blank=True,
422430
null=True,
423431
)
424-
name = models.CharField(max_length=100, unique=True)
425-
number = models.CharField(max_length=100, blank=True, default="")
432+
name = models.CharField(max_length=CHARFIELD_MAX_LENGTH, unique=True)
433+
number = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True, default="")
426434
start = models.DateField(null=True, blank=True, verbose_name="Contract Start Date")
427435
end = models.DateField(null=True, blank=True, verbose_name="Contract End Date")
428436
cost = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=15, verbose_name="Contract Cost")
429-
support_level = models.CharField(verbose_name="Support Level", max_length=64, blank=True, default="")
437+
support_level = models.CharField(
438+
verbose_name="Support Level", max_length=CHARFIELD_MAX_LENGTH, blank=True, default=""
439+
)
430440
currency = models.CharField(verbose_name="Currency", max_length=4, blank=True, default="")
431-
contract_type = models.CharField(verbose_name="Contract Type", max_length=32, blank=True, default="")
441+
contract_type = models.CharField(
442+
verbose_name="Contract Type", max_length=CHARFIELD_MAX_LENGTH, blank=True, default=""
443+
)
432444
devices = models.ManyToManyField(to="dcim.Device", related_name="device_contracts", blank=True)
433445
comments = models.TextField(blank=True, default="")
434446

@@ -477,11 +489,11 @@ class ProviderLCM(OrganizationalModel):
477489
"""ProviderLCM model for app."""
478490

479491
# Set model columns
480-
name = models.CharField(max_length=100, unique=True)
481-
description = models.CharField(max_length=200, blank=True)
482-
physical_address = models.CharField(max_length=200, blank=True)
492+
name = models.CharField(max_length=CHARFIELD_MAX_LENGTH, unique=True)
493+
description = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True)
494+
physical_address = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True)
483495
country = models.CharField(max_length=3, blank=True)
484-
phone = models.CharField(max_length=20, blank=True)
496+
phone = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True)
485497
email = models.EmailField(blank=True, verbose_name="E-mail")
486498
portal_url = models.URLField(blank=True, verbose_name="Portal URL")
487499
comments = models.TextField(blank=True, default="")
@@ -515,13 +527,13 @@ def save(self, *args, **kwargs):
515527
class ContactLCM(PrimaryModel):
516528
"""ContactLCM is a model representation of a contact used in Contracts."""
517529

518-
name = models.CharField(max_length=80, null=True)
519-
address = models.CharField(max_length=200, blank=True)
520-
phone = models.CharField(max_length=20, blank=True)
530+
name = models.CharField(max_length=CHARFIELD_MAX_LENGTH, null=True)
531+
address = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True)
532+
phone = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True)
521533
email = models.EmailField(blank=True, verbose_name="Contact E-mail")
522534
comments = models.TextField(blank=True, default="")
523535
priority = models.PositiveIntegerField(default=100)
524-
type = models.CharField(max_length=50, default=choices.PoCTypeChoices.UNASSIGNED)
536+
type = models.CharField(max_length=CHARFIELD_MAX_LENGTH, default=choices.PoCTypeChoices.UNASSIGNED)
525537
contract = models.ForeignKey(
526538
to="nautobot_device_lifecycle_mgmt.ContractLCM", on_delete=models.CASCADE, verbose_name="Contract", null=True
527539
)
@@ -566,7 +578,7 @@ def __str__(self):
566578
class CVELCM(PrimaryModel):
567579
"""CVELCM is a model representation of a cve vulnerability record."""
568580

569-
name = models.CharField(max_length=16, blank=False, unique=True)
581+
name = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=False, unique=True)
570582
published_date = models.DateField(verbose_name="Published Date")
571583
link = models.URLField()
572584
status = StatusField(
@@ -575,9 +587,9 @@ class CVELCM(PrimaryModel):
575587
on_delete=models.PROTECT,
576588
to="extras.status",
577589
)
578-
description = models.CharField(max_length=255, blank=True, default="")
590+
description = models.CharField(max_length=CHARFIELD_MAX_LENGTH, blank=True, default="")
579591
severity = models.CharField(
580-
max_length=50, choices=choices.CVESeverityChoices, default=choices.CVESeverityChoices.NONE
592+
max_length=CHARFIELD_MAX_LENGTH, choices=choices.CVESeverityChoices, default=choices.CVESeverityChoices.NONE
581593
)
582594
cvss = models.FloatField(blank=True, null=True, verbose_name="CVSS Base Score")
583595
cvss_v2 = models.FloatField(blank=True, null=True, verbose_name="CVSSv2 Score")

0 commit comments

Comments
 (0)