netbox/netbox/utilities/release.py
Jeremy Stretch f829f34b43
Closes #18559: Add a build parameter to ReleaseInfo (#18560)
* Closes #18559: Add a build parameter to ReleaseInfo

* Adjust dataclass typing
2025-02-03 09:44:00 -05:00

81 lines
2.2 KiB
Python

import datetime
import os
from dataclasses import asdict, dataclass, field
from typing import Union
import yaml
from django.core.exceptions import ImproperlyConfigured
from utilities.datetime import datetime_from_timestamp
RELEASE_PATH = 'release.yaml'
LOCAL_RELEASE_PATH = 'local/release.yaml'
@dataclass
class FeatureSet:
"""
A map of all available NetBox features.
"""
# Commercial support is provided by NetBox Labs
commercial: bool = False
# Live help center is enabled
help_center: bool = False
@dataclass
class ReleaseInfo:
version: str
edition: str
published: Union[datetime.date, None] = None
designation: Union[str, None] = None
build: Union[str, None] = None
features: FeatureSet = field(default_factory=FeatureSet)
@property
def full_version(self):
output = self.version
if self.designation:
output = f"{output}-{self.designation}"
if self.build:
output = f"{output}-{self.build}"
return output
@property
def name(self):
return f"NetBox {self.edition} v{self.full_version}"
def asdict(self):
return asdict(self)
def load_release_data():
"""
Load any locally-defined release attributes and return a ReleaseInfo instance.
"""
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Load canonical release attributes
with open(os.path.join(base_path, RELEASE_PATH), 'r') as release_file:
data = yaml.safe_load(release_file)
# Overlay any local release date (if defined)
try:
with open(os.path.join(base_path, LOCAL_RELEASE_PATH), 'r') as release_file:
local_data = yaml.safe_load(release_file)
except FileNotFoundError:
local_data = {}
if local_data is not None:
if type(local_data) is not dict:
raise ImproperlyConfigured(
f"{LOCAL_RELEASE_PATH}: Local release data must be defined as a dictionary."
)
data.update(local_data)
# Convert the published date to a date object
if 'published' in data:
data['published'] = datetime_from_timestamp(data['published'])
return ReleaseInfo(**data)