mirror of
https://github.com/netbox-community/netbox.git
synced 2025-09-06 14:23:36 -06:00
parent
a175030655
commit
cd3f930e19
@ -1,4 +1,3 @@
|
|||||||
import logging
|
|
||||||
import sys
|
import sys
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
@ -17,8 +16,6 @@ from utilities.proxy import resolve_proxies
|
|||||||
from .choices import DataSourceStatusChoices, JobIntervalChoices
|
from .choices import DataSourceStatusChoices, JobIntervalChoices
|
||||||
from .models import DataSource
|
from .models import DataSource
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class SyncDataSourceJob(JobRunner):
|
class SyncDataSourceJob(JobRunner):
|
||||||
"""
|
"""
|
||||||
@ -69,7 +66,11 @@ class SystemHousekeepingJob(JobRunner):
|
|||||||
|
|
||||||
def run(self, *args, **kwargs):
|
def run(self, *args, **kwargs):
|
||||||
# Skip if running in development or test mode
|
# Skip if running in development or test mode
|
||||||
if settings.DEBUG or 'test' in sys.argv:
|
if settings.DEBUG:
|
||||||
|
self.logger.warning("Aborting execution: Debug is enabled")
|
||||||
|
return
|
||||||
|
if 'test' in sys.argv:
|
||||||
|
self.logger.warning("Aborting execution: Tests are running")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.send_census_report()
|
self.send_census_report()
|
||||||
@ -78,17 +79,16 @@ class SystemHousekeepingJob(JobRunner):
|
|||||||
self.delete_expired_jobs()
|
self.delete_expired_jobs()
|
||||||
self.check_for_new_releases()
|
self.check_for_new_releases()
|
||||||
|
|
||||||
@staticmethod
|
def send_census_report(self):
|
||||||
def send_census_report():
|
|
||||||
"""
|
"""
|
||||||
Send a census report (if enabled).
|
Send a census report (if enabled).
|
||||||
"""
|
"""
|
||||||
logging.info("Reporting census data...")
|
self.logger.info("Reporting census data...")
|
||||||
if settings.ISOLATED_DEPLOYMENT:
|
if settings.ISOLATED_DEPLOYMENT:
|
||||||
logging.info("ISOLATED_DEPLOYMENT is enabled; skipping")
|
self.logger.info("ISOLATED_DEPLOYMENT is enabled; skipping")
|
||||||
return
|
return
|
||||||
if not settings.CENSUS_REPORTING_ENABLED:
|
if not settings.CENSUS_REPORTING_ENABLED:
|
||||||
logging.info("CENSUS_REPORTING_ENABLED is disabled; skipping")
|
self.logger.info("CENSUS_REPORTING_ENABLED is disabled; skipping")
|
||||||
return
|
return
|
||||||
|
|
||||||
census_data = {
|
census_data = {
|
||||||
@ -106,73 +106,71 @@ class SystemHousekeepingJob(JobRunner):
|
|||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
def clear_expired_sessions(self):
|
||||||
def clear_expired_sessions():
|
|
||||||
"""
|
"""
|
||||||
Clear any expired sessions from the database.
|
Clear any expired sessions from the database.
|
||||||
"""
|
"""
|
||||||
logging.info("Clearing expired sessions...")
|
self.logger.info("Clearing expired sessions...")
|
||||||
engine = import_module(settings.SESSION_ENGINE)
|
engine = import_module(settings.SESSION_ENGINE)
|
||||||
try:
|
try:
|
||||||
engine.SessionStore.clear_expired()
|
engine.SessionStore.clear_expired()
|
||||||
logging.info("Sessions cleared.")
|
self.logger.info("Sessions cleared.")
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
logging.warning(
|
self.logger.warning(
|
||||||
f"The configured session engine ({settings.SESSION_ENGINE}) does not support "
|
f"The configured session engine ({settings.SESSION_ENGINE}) does not support "
|
||||||
f"clearing sessions; skipping."
|
f"clearing sessions; skipping."
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
def prune_changelog(self):
|
||||||
def prune_changelog():
|
|
||||||
"""
|
"""
|
||||||
Delete any ObjectChange records older than the configured changelog retention time (if any).
|
Delete any ObjectChange records older than the configured changelog retention time (if any).
|
||||||
"""
|
"""
|
||||||
logging.info("Pruning old changelog entries...")
|
self.logger.info("Pruning old changelog entries...")
|
||||||
config = Config()
|
config = Config()
|
||||||
if not config.CHANGELOG_RETENTION:
|
if not config.CHANGELOG_RETENTION:
|
||||||
logging.info("No retention period specified; skipping.")
|
self.logger.info("No retention period specified; skipping.")
|
||||||
return
|
return
|
||||||
|
|
||||||
cutoff = timezone.now() - timedelta(days=config.CHANGELOG_RETENTION)
|
cutoff = timezone.now() - timedelta(days=config.CHANGELOG_RETENTION)
|
||||||
logging.debug(f"Retention period: {config.CHANGELOG_RETENTION} days")
|
self.logger.debug(
|
||||||
logging.debug(f"Cut-off time: {cutoff}")
|
f"Changelog retention period: {config.CHANGELOG_RETENTION} days ({cutoff:%Y-%m-%d %H:%M:%S})"
|
||||||
|
)
|
||||||
|
|
||||||
count = ObjectChange.objects.filter(time__lt=cutoff).delete()[0]
|
count = ObjectChange.objects.filter(time__lt=cutoff).delete()[0]
|
||||||
logging.info(f"Deleted {count} expired records")
|
self.logger.info(f"Deleted {count} expired changelog records")
|
||||||
|
|
||||||
@staticmethod
|
def delete_expired_jobs(self):
|
||||||
def delete_expired_jobs():
|
|
||||||
"""
|
"""
|
||||||
Delete any jobs older than the configured retention period (if any).
|
Delete any jobs older than the configured retention period (if any).
|
||||||
"""
|
"""
|
||||||
logging.info("Deleting expired jobs...")
|
self.logger.info("Deleting expired jobs...")
|
||||||
config = Config()
|
config = Config()
|
||||||
if not config.JOB_RETENTION:
|
if not config.JOB_RETENTION:
|
||||||
logging.info("No retention period specified; skipping.")
|
self.logger.info("No retention period specified; skipping.")
|
||||||
return
|
return
|
||||||
|
|
||||||
cutoff = timezone.now() - timedelta(days=config.JOB_RETENTION)
|
cutoff = timezone.now() - timedelta(days=config.JOB_RETENTION)
|
||||||
logging.debug(f"Retention period: {config.CHANGELOG_RETENTION} days")
|
self.logger.debug(
|
||||||
logging.debug(f"Cut-off time: {cutoff}")
|
f"Job retention period: {config.JOB_RETENTION} days ({cutoff:%Y-%m-%d %H:%M:%S})"
|
||||||
|
)
|
||||||
|
|
||||||
count = Job.objects.filter(created__lt=cutoff).delete()[0]
|
count = Job.objects.filter(created__lt=cutoff).delete()[0]
|
||||||
logging.info(f"Deleted {count} expired records")
|
self.logger.info(f"Deleted {count} expired jobs")
|
||||||
|
|
||||||
@staticmethod
|
def check_for_new_releases(self):
|
||||||
def check_for_new_releases():
|
|
||||||
"""
|
"""
|
||||||
Check for new releases and cache the latest release.
|
Check for new releases and cache the latest release.
|
||||||
"""
|
"""
|
||||||
logging.info("Checking for new releases...")
|
self.logger.info("Checking for new releases...")
|
||||||
if settings.ISOLATED_DEPLOYMENT:
|
if settings.ISOLATED_DEPLOYMENT:
|
||||||
logging.info("ISOLATED_DEPLOYMENT is enabled; skipping")
|
self.logger.info("ISOLATED_DEPLOYMENT is enabled; skipping")
|
||||||
return
|
return
|
||||||
if not settings.RELEASE_CHECK_URL:
|
if not settings.RELEASE_CHECK_URL:
|
||||||
logging.info("RELEASE_CHECK_URL is not set; skipping")
|
self.logger.info("RELEASE_CHECK_URL is not set; skipping")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Fetch the latest releases
|
# Fetch the latest releases
|
||||||
logging.debug(f"Release check URL: {settings.RELEASE_CHECK_URL}")
|
self.logger.debug(f"Release check URL: {settings.RELEASE_CHECK_URL}")
|
||||||
try:
|
try:
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
url=settings.RELEASE_CHECK_URL,
|
url=settings.RELEASE_CHECK_URL,
|
||||||
@ -181,7 +179,7 @@ class SystemHousekeepingJob(JobRunner):
|
|||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except requests.exceptions.RequestException as exc:
|
except requests.exceptions.RequestException as exc:
|
||||||
logging.error(f"Error fetching release: {exc}")
|
self.logger.error(f"Error fetching release: {exc}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Determine the most recent stable release
|
# Determine the most recent stable release
|
||||||
@ -191,8 +189,8 @@ class SystemHousekeepingJob(JobRunner):
|
|||||||
continue
|
continue
|
||||||
releases.append((version.parse(release['tag_name']), release.get('html_url')))
|
releases.append((version.parse(release['tag_name']), release.get('html_url')))
|
||||||
latest_release = max(releases)
|
latest_release = max(releases)
|
||||||
logging.debug(f"Found {len(response.json())} releases; {len(releases)} usable")
|
self.logger.debug(f"Found {len(response.json())} releases; {len(releases)} usable")
|
||||||
logging.info(f"Latest release: {latest_release[0]}")
|
self.logger.info(f"Latest release: {latest_release[0]}")
|
||||||
|
|
||||||
# Cache the most recent release
|
# Cache the most recent release
|
||||||
cache.set('latest_release', latest_release, None)
|
cache.set('latest_release', latest_release, None)
|
||||||
|
@ -67,9 +67,7 @@
|
|||||||
<div class="col col-12">
|
<div class="col col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2 class="card-header">{% trans "Data" %}</h2>
|
<h2 class="card-header">{% trans "Data" %}</h2>
|
||||||
<div class="card-body">
|
<pre class="card-body m-0">{{ object.data|json }}</pre>
|
||||||
<pre>{{ object.data|json }}</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user