mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Update release check to use django-redis
This commit is contained in:
parent
d9e27b6a82
commit
2c023ef7a0
@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from cacheops import CacheMiss, cache
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
from django_rq import get_queue
|
from django_rq import get_queue
|
||||||
|
|
||||||
from utilities.background_tasks import get_releases
|
from utilities.background_tasks import get_releases
|
||||||
@ -12,12 +12,11 @@ logger = logging.getLogger('netbox.releases')
|
|||||||
def get_latest_release(pre_releases=False):
|
def get_latest_release(pre_releases=False):
|
||||||
if settings.RELEASE_CHECK_URL:
|
if settings.RELEASE_CHECK_URL:
|
||||||
logger.debug("Checking for most recent release")
|
logger.debug("Checking for most recent release")
|
||||||
try:
|
latest_release = cache.get('latest_release')
|
||||||
latest_release = cache.get('latest_release')
|
if latest_release:
|
||||||
if latest_release:
|
logger.debug(f"Found cached release: {latest_release}")
|
||||||
logger.debug("Found cached release: {}".format(latest_release))
|
return latest_release
|
||||||
return latest_release
|
else:
|
||||||
except CacheMiss:
|
|
||||||
# Check for an existing job. This can happen if the RQ worker process is not running.
|
# Check for an existing job. This can happen if the RQ worker process is not running.
|
||||||
queue = get_queue('check_releases')
|
queue = get_queue('check_releases')
|
||||||
if queue.jobs:
|
if queue.jobs:
|
||||||
|
@ -3,8 +3,8 @@ from logging import ERROR
|
|||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from cacheops import CacheMiss, RedisCache
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from packaging.version import Version
|
from packaging.version import Version
|
||||||
from requests import Response
|
from requests import Response
|
||||||
@ -60,10 +60,8 @@ def unsuccessful_github_response(url, *_args, **_kwargs):
|
|||||||
@override_settings(RELEASE_CHECK_URL='https://localhost/unittest/releases', RELEASE_CHECK_TIMEOUT=160876)
|
@override_settings(RELEASE_CHECK_URL='https://localhost/unittest/releases', RELEASE_CHECK_TIMEOUT=160876)
|
||||||
class GetReleasesTestCase(SimpleTestCase):
|
class GetReleasesTestCase(SimpleTestCase):
|
||||||
@patch.object(requests, 'get')
|
@patch.object(requests, 'get')
|
||||||
@patch.object(RedisCache, 'set')
|
@patch.object(cache, 'set')
|
||||||
@patch.object(RedisCache, 'get')
|
def test_pre_releases(self, dummy_cache_set: Mock, dummy_request_get: Mock):
|
||||||
def test_pre_releases(self, dummy_cache_get: Mock, dummy_cache_set: Mock, dummy_request_get: Mock):
|
|
||||||
dummy_cache_get.side_effect = CacheMiss()
|
|
||||||
dummy_request_get.side_effect = successful_github_response
|
dummy_request_get.side_effect = successful_github_response
|
||||||
|
|
||||||
releases = get_releases(pre_releases=True)
|
releases = get_releases(pre_releases=True)
|
||||||
@ -90,10 +88,8 @@ class GetReleasesTestCase(SimpleTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@patch.object(requests, 'get')
|
@patch.object(requests, 'get')
|
||||||
@patch.object(RedisCache, 'set')
|
@patch.object(cache, 'set')
|
||||||
@patch.object(RedisCache, 'get')
|
def test_no_pre_releases(self, dummy_cache_set: Mock, dummy_request_get: Mock):
|
||||||
def test_no_pre_releases(self, dummy_cache_get: Mock, dummy_cache_set: Mock, dummy_request_get: Mock):
|
|
||||||
dummy_cache_get.side_effect = CacheMiss()
|
|
||||||
dummy_request_get.side_effect = successful_github_response
|
dummy_request_get.side_effect = successful_github_response
|
||||||
|
|
||||||
releases = get_releases(pre_releases=False)
|
releases = get_releases(pre_releases=False)
|
||||||
@ -119,10 +115,7 @@ class GetReleasesTestCase(SimpleTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@patch.object(requests, 'get')
|
@patch.object(requests, 'get')
|
||||||
@patch.object(RedisCache, 'set')
|
def test_failed_request(self, dummy_request_get: Mock):
|
||||||
@patch.object(RedisCache, 'get')
|
|
||||||
def test_failed_request(self, dummy_cache_get: Mock, dummy_cache_set: Mock, dummy_request_get: Mock):
|
|
||||||
dummy_cache_get.side_effect = CacheMiss()
|
|
||||||
dummy_request_get.side_effect = unsuccessful_github_response
|
dummy_request_get.side_effect = unsuccessful_github_response
|
||||||
|
|
||||||
with self.assertLogs(level=ERROR) as cm:
|
with self.assertLogs(level=ERROR) as cm:
|
||||||
@ -143,28 +136,3 @@ class GetReleasesTestCase(SimpleTestCase):
|
|||||||
headers={'Accept': 'application/vnd.github.v3+json'},
|
headers={'Accept': 'application/vnd.github.v3+json'},
|
||||||
proxies=settings.HTTP_PROXIES
|
proxies=settings.HTTP_PROXIES
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if failure is put in cache
|
|
||||||
dummy_cache_set.assert_called_once_with(
|
|
||||||
'latest_release_no_retry',
|
|
||||||
'https://localhost/unittest/releases',
|
|
||||||
900
|
|
||||||
)
|
|
||||||
|
|
||||||
@patch.object(requests, 'get')
|
|
||||||
@patch.object(RedisCache, 'set')
|
|
||||||
@patch.object(RedisCache, 'get')
|
|
||||||
def test_blocked_retry(self, dummy_cache_get: Mock, dummy_cache_set: Mock, dummy_request_get: Mock):
|
|
||||||
dummy_cache_get.return_value = 'https://localhost/unittest/releases'
|
|
||||||
dummy_request_get.side_effect = successful_github_response
|
|
||||||
|
|
||||||
releases = get_releases()
|
|
||||||
|
|
||||||
# Check result
|
|
||||||
self.assertListEqual(releases, [])
|
|
||||||
|
|
||||||
# Check if request is NOT made
|
|
||||||
dummy_request_get.assert_not_called()
|
|
||||||
|
|
||||||
# Check if cache is not updated
|
|
||||||
dummy_cache_set.assert_not_called()
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from cacheops.simple import cache, CacheMiss
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
from django_rq import job
|
from django_rq import job
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
@ -18,16 +18,8 @@ def get_releases(pre_releases=False):
|
|||||||
}
|
}
|
||||||
releases = []
|
releases = []
|
||||||
|
|
||||||
# Check whether this URL has failed recently and shouldn't be retried yet
|
|
||||||
try:
|
try:
|
||||||
if url == cache.get('latest_release_no_retry'):
|
logger.info(f"Fetching new releases from {url}")
|
||||||
logger.info("Skipping release check; URL failed recently: {}".format(url))
|
|
||||||
return []
|
|
||||||
except CacheMiss:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
logger.debug("Fetching new releases from {}".format(url))
|
|
||||||
response = requests.get(url, headers=headers, proxies=settings.HTTP_PROXIES)
|
response = requests.get(url, headers=headers, proxies=settings.HTTP_PROXIES)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
total_releases = len(response.json())
|
total_releases = len(response.json())
|
||||||
@ -38,12 +30,10 @@ def get_releases(pre_releases=False):
|
|||||||
if not pre_releases and (release.get('devrelease') or release.get('prerelease')):
|
if not pre_releases and (release.get('devrelease') or release.get('prerelease')):
|
||||||
continue
|
continue
|
||||||
releases.append((version.parse(release['tag_name']), release.get('html_url')))
|
releases.append((version.parse(release['tag_name']), release.get('html_url')))
|
||||||
logger.debug("Found {} releases; {} usable".format(total_releases, len(releases)))
|
logger.debug(f"Found {total_releases} releases; {len(releases)} usable")
|
||||||
|
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException as exc:
|
||||||
# The request failed. Set a flag in the cache to disable future checks to this URL for 15 minutes.
|
logger.exception(f"Error while fetching latest release from {url}: {exc}")
|
||||||
logger.exception("Error while fetching {}. Disabling checks for 15 minutes.".format(url))
|
|
||||||
cache.set('latest_release_no_retry', url, 900)
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Cache the most recent release
|
# Cache the most recent release
|
||||||
|
Loading…
Reference in New Issue
Block a user