From 81ca9e4127e4b6ba959f907f0871967d4e485d0c Mon Sep 17 00:00:00 2001 From: baloola Date: Wed, 2 Aug 2023 11:14:56 +0200 Subject: [PATCH 1/4] correctly reading environment variables in conf --- eoxserver/core/config.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/eoxserver/core/config.py b/eoxserver/core/config.py index 6037b8ea4..518c450e9 100644 --- a/eoxserver/core/config.py +++ b/eoxserver/core/config.py @@ -32,6 +32,7 @@ """ import imp +import os from os.path import join, getmtime from sys import prefix import threading @@ -39,9 +40,9 @@ from time import time try: - from ConfigParser import RawConfigParser + from ConfigParser import SafeConfigParser except ImportError: - from configparser import RawConfigParser + from configparser import SafeConfigParser from django.conf import settings @@ -56,7 +57,7 @@ def get_eoxserver_config(): - """ Returns the EOxServer config as a :class:`ConfigParser.RawConfigParser` + """ Returns the EOxServer config as a :class:`ConfigParser.SafeConfigParser` """ with config_lock: if not _cached_config or \ @@ -68,7 +69,7 @@ def get_eoxserver_config(): def reload_eoxserver_config(): """ Triggers the loading or reloading of the EOxServer config as a - :class:`ConfigParser.RawConfigParser`. + :class:`ConfigParser.SafeConfigParser`. """ global _cached_config, _last_access_time _, eoxs_path, _ = imp.find_module("eoxserver") @@ -84,7 +85,7 @@ def reload_eoxserver_config(): ) with config_lock: - _cached_config = RawConfigParser() + _cached_config = SafeConfigParser(os.environ) _cached_config.read(paths) _last_access_time = time() From 9ac5bb5eb858e2c1b56e06ac3f0dd526f4eec763 Mon Sep 17 00:00:00 2001 From: Bernhard Mallinger Date: Wed, 16 Aug 2023 15:58:06 +0200 Subject: [PATCH 2/4] SafeConfigParser was renamed to ConfigParser SafeConfigParser will be removed in python 3.12 --- eoxserver/core/config.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/eoxserver/core/config.py b/eoxserver/core/config.py index 518c450e9..1bb19d8b9 100644 --- a/eoxserver/core/config.py +++ b/eoxserver/core/config.py @@ -39,10 +39,7 @@ import logging from time import time -try: - from ConfigParser import SafeConfigParser -except ImportError: - from configparser import SafeConfigParser +from configparser import ConfigParser from django.conf import settings @@ -57,7 +54,7 @@ def get_eoxserver_config(): - """ Returns the EOxServer config as a :class:`ConfigParser.SafeConfigParser` + """ Returns the EOxServer config as a :class:`ConfigParser.ConfigParser` """ with config_lock: if not _cached_config or \ @@ -69,7 +66,7 @@ def get_eoxserver_config(): def reload_eoxserver_config(): """ Triggers the loading or reloading of the EOxServer config as a - :class:`ConfigParser.SafeConfigParser`. + :class:`configparser.ConfigParser`. """ global _cached_config, _last_access_time _, eoxs_path, _ = imp.find_module("eoxserver") @@ -85,7 +82,7 @@ def reload_eoxserver_config(): ) with config_lock: - _cached_config = SafeConfigParser(os.environ) + _cached_config = ConfigParser(os.environ) _cached_config.read(paths) _last_access_time = time() From 24ed5e4925ee47be60a0313213e7b7701a504453 Mon Sep 17 00:00:00 2001 From: Bernhard Mallinger Date: Wed, 16 Aug 2023 16:38:49 +0200 Subject: [PATCH 3/4] Actually interpolate an example value in the config file --- .github/workflows/ci.yml | 1 + autotest/autotest/conf/eoxserver.conf | 2 +- eoxserver/core/config.py | 20 +++++++++++-- eoxserver/core/test_config.py | 28 +++++++++++++++++++ .../project_name/conf/eoxserver.conf | 2 +- 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 eoxserver/core/test_config.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 238c819b4..ab156a0aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,7 @@ jobs: command: - "-m eoxserver.services.ows.wps.test_data_types" - "-m eoxserver.services.ows.wps.test_allowed_values" + - "-m eoxserver.core.test_config" - "manage.py test --pythonpath=./eoxserver/ eoxserver.core -v2" - "manage.py test --pythonpath=./eoxserver/ eoxserver.backends -v2" - "manage.py test --pythonpath=./eoxserver/ eoxserver.services -v2" diff --git a/autotest/autotest/conf/eoxserver.conf b/autotest/autotest/conf/eoxserver.conf index a7e3d0433..68feb7259 100644 --- a/autotest/autotest/conf/eoxserver.conf +++ b/autotest/autotest/conf/eoxserver.conf @@ -40,7 +40,7 @@ instance_id=autotest [services.owscommon] #http_service_url (mandatory) the URL where GET KVP and POST XML # OWS requests are expected -http_service_url=http://testserver/ows +http_service_url = ${DEFAULT:HTTP_SERVICE_URL} # time_interval_interpretation (optional) How to interpret time intervals. # Allowed values are 'closed' and diff --git a/eoxserver/core/config.py b/eoxserver/core/config.py index 1bb19d8b9..ec8f41dd9 100644 --- a/eoxserver/core/config.py +++ b/eoxserver/core/config.py @@ -39,7 +39,7 @@ import logging from time import time -from configparser import ConfigParser +from configparser import ConfigParser, ExtendedInterpolation from django.conf import settings @@ -53,6 +53,14 @@ _last_access_time = None +# NOTE: Previously these values were hardcoded in the config. +# Now they are interpolated from env vars, but we keep +# these defautls here for backwards compatibility +DEFAULTS = { + "HTTP_SERVICE_URL": "http://localhost:8000/ows?" +} + + def get_eoxserver_config(): """ Returns the EOxServer config as a :class:`ConfigParser.ConfigParser` """ @@ -81,8 +89,16 @@ def reload_eoxserver_config(): % ("Rel" if _cached_config else "L", ", ".join(paths)) ) + env_vars = { + **DEFAULTS, + **os.environ, + } + with config_lock: - _cached_config = ConfigParser(os.environ) + _cached_config = ConfigParser( + env_vars, + interpolation=ExtendedInterpolation(), + ) _cached_config.read(paths) _last_access_time = time() diff --git a/eoxserver/core/test_config.py b/eoxserver/core/test_config.py new file mode 100644 index 000000000..d44652347 --- /dev/null +++ b/eoxserver/core/test_config.py @@ -0,0 +1,28 @@ +import os +from unittest import mock + +from django.test import TestCase + +from eoxserver.core.config import get_eoxserver_config, reload_eoxserver_config + + +class TestConfig(TestCase): + def test_config_interpolates_env_vars(self): + new_url = "https://example.com/myows" + # force reload because it's cached + with mock.patch.dict(os.environ, {"HTTP_SERVICE_URL": new_url}): + reload_eoxserver_config() + current_config = get_eoxserver_config() + + self.assertEqual( + current_config.get("services.owscommon", "http_service_url"), + new_url, + ) + + def test_config_has_default_values(self): + reload_eoxserver_config() + current_config = get_eoxserver_config() + self.assertEqual( + current_config.get("services.owscommon", "http_service_url"), + "http://localhost:8000/ows?", + ) diff --git a/eoxserver/instance_template/project_name/conf/eoxserver.conf b/eoxserver/instance_template/project_name/conf/eoxserver.conf index 1790ff473..6d6219762 100644 --- a/eoxserver/instance_template/project_name/conf/eoxserver.conf +++ b/eoxserver/instance_template/project_name/conf/eoxserver.conf @@ -40,7 +40,7 @@ instance_id={{ project_name }} [services.owscommon] #http_service_url (mandatory) the URL where GET KVP and POST XML # OWS requests are expected -http_service_url=http://localhost:8000/ows? +http_service_url = ${DEFAULT:HTTP_SERVICE_URL} # time_interval_interpretation (optional) How to interpret time intervals. # Allowed values are 'closed' and From c46af4b0c3df892e1c8d8e045773c3c4e7be1095 Mon Sep 17 00:00:00 2001 From: Bernhard Mallinger Date: Thu, 17 Aug 2023 11:58:05 +0200 Subject: [PATCH 4/4] squash me --- autotest/autotest/conf/eoxserver.conf | 2 ++ eoxserver/core/config.py | 5 ++++- eoxserver/core/test_config.py | 9 +++++++++ .../instance_template/project_name/conf/eoxserver.conf | 4 ++-- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/autotest/autotest/conf/eoxserver.conf b/autotest/autotest/conf/eoxserver.conf index 68feb7259..08663a916 100644 --- a/autotest/autotest/conf/eoxserver.conf +++ b/autotest/autotest/conf/eoxserver.conf @@ -101,6 +101,8 @@ supported_formats=image/png,image/jpeg,image/gif,image/tiff mask_names=clouds +# min_render_zoom = ${DEFAULT:OWS_WMS_MINRENDER_ZOOM} + [services.ows.wcs] # CRSes supported by WCS (EPSG code; uncomment to set non-default values) diff --git a/eoxserver/core/config.py b/eoxserver/core/config.py index ec8f41dd9..dd4dd1cd8 100644 --- a/eoxserver/core/config.py +++ b/eoxserver/core/config.py @@ -57,7 +57,9 @@ # Now they are interpolated from env vars, but we keep # these defautls here for backwards compatibility DEFAULTS = { - "HTTP_SERVICE_URL": "http://localhost:8000/ows?" + "HTTP_SERVICE_URL": "http://localhost:8000/ows?", + "OWS_WCS_MAXSIZE": "2048", + "OWS_WMS_MINRENDER_ZOOM": "", } @@ -97,6 +99,7 @@ def reload_eoxserver_config(): with config_lock: _cached_config = ConfigParser( env_vars, + allow_no_value=True, interpolation=ExtendedInterpolation(), ) _cached_config.read(paths) diff --git a/eoxserver/core/test_config.py b/eoxserver/core/test_config.py index d44652347..b8a1d059f 100644 --- a/eoxserver/core/test_config.py +++ b/eoxserver/core/test_config.py @@ -4,6 +4,7 @@ from django.test import TestCase from eoxserver.core.config import get_eoxserver_config, reload_eoxserver_config +from eoxserver.services.ows.wms.layermapper import LayerMapperConfigReader class TestConfig(TestCase): @@ -26,3 +27,11 @@ def test_config_has_default_values(self): current_config.get("services.owscommon", "http_service_url"), "http://localhost:8000/ows?", ) + + def test_config_handles_empty_values(self): + reload_eoxserver_config() + current_config = get_eoxserver_config() + + + reader = LayerMapperConfigReader(current_config) + self.assertIsNone(reader.min_render_zoom) diff --git a/eoxserver/instance_template/project_name/conf/eoxserver.conf b/eoxserver/instance_template/project_name/conf/eoxserver.conf index 6d6219762..e422618ba 100644 --- a/eoxserver/instance_template/project_name/conf/eoxserver.conf +++ b/eoxserver/instance_template/project_name/conf/eoxserver.conf @@ -99,7 +99,7 @@ mask_names=clouds # limit_products = # limit_mode = hide -# min_render_zoom = +min_render_zoom = ${DEFAULT:OWS_WMS_MINRENDER_ZOOM} # fill_opacity = # color = grey @@ -128,7 +128,7 @@ mask_names=clouds supported_formats=image/tiff,image/jp2,application/x-netcdf,application/x-hdf # the maximum size of output coverages -# maxsize = 2048 +maxsize = ${DEFAULT:OWS_WCS_MAXSIZE} [services.ows.wcs20] #paging_count_default (optional) Number of maximum coverageDescriptions