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..08663a916 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 @@ -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 6037b8ea4..dd4dd1cd8 100644 --- a/eoxserver/core/config.py +++ b/eoxserver/core/config.py @@ -32,16 +32,14 @@ """ import imp +import os from os.path import join, getmtime from sys import prefix import threading import logging from time import time -try: - from ConfigParser import RawConfigParser -except ImportError: - from configparser import RawConfigParser +from configparser import ConfigParser, ExtendedInterpolation from django.conf import settings @@ -55,8 +53,18 @@ _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?", + "OWS_WCS_MAXSIZE": "2048", + "OWS_WMS_MINRENDER_ZOOM": "", +} + + def get_eoxserver_config(): - """ Returns the EOxServer config as a :class:`ConfigParser.RawConfigParser` + """ Returns the EOxServer config as a :class:`ConfigParser.ConfigParser` """ with config_lock: if not _cached_config or \ @@ -68,7 +76,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.ConfigParser`. """ global _cached_config, _last_access_time _, eoxs_path, _ = imp.find_module("eoxserver") @@ -83,8 +91,17 @@ def reload_eoxserver_config(): % ("Rel" if _cached_config else "L", ", ".join(paths)) ) + env_vars = { + **DEFAULTS, + **os.environ, + } + with config_lock: - _cached_config = RawConfigParser() + _cached_config = ConfigParser( + env_vars, + allow_no_value=True, + 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..b8a1d059f --- /dev/null +++ b/eoxserver/core/test_config.py @@ -0,0 +1,37 @@ +import os +from unittest import mock + +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): + 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?", + ) + + 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 1790ff473..e422618ba 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 @@ -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