Skip to content

Commit

Permalink
improve config with review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
mki-c2c committed Jan 28, 2025
1 parent 5359be8 commit 79099cf
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 6 deletions.
33 changes: 29 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,35 @@ Sources contains 2 list of servers: `geonetwork_instances` and `geoserver_instan

Destinations is a dict of geonetwork / geoserver combinations, each with their url and credentials.

The logics for credentials is by increasing order of importance:
- credentials defined at a higher level are applied to a lower level (e.g. common credentials can be defined for both geonetwork and geoserver in a destination item)
- credentials in the geoserver/geonetwork level are read from the keys "login", "password"
- if the keys "login_env_var" and/or "password_env_var" are found, the corrensponding environment variable is read, and if defined, overrides the credential
The logics for credentials is by decreasing order of importance:
1. env var: if the keys "login_env_var" and/or "password_env_var" are found in a single server definitions and if the corrensponding environment variable is defined, this value is read and applied as login /password
2. if no env vars are configured, the keys "login" and/or password for a single server instance are used
3. if still no login/password is found, the configuration file is parsed at the parent hierarchy level. First env vars are used like in 1.
4. Then constant login/password keys are read
5. I still either "login" or "password" is not defined, the credentials are considered invalid and anonymous acces is used for the instance without authentication

Example (see <backend/tests/doc_sample_config.yaml>):

```
sources:
login: admin
password_env_var: COMMON_PW
geonetwork_instances:
- name: "a"
password: "pwA"
- name: "b"
login: "B"
password: default_unused
password_env_var: "PASSWORD_B"
- name: "c"
login: "C"
```
where `COMMON_PW`is undefined and `PASSWORD_B=pwB`

in this case, the parsed credentials will be:
- instance a: login: admin, password: pwA
- instance b: login: B, password: pwB
- instance c: anonymous since no password is defined

### Access

Expand Down
8 changes: 6 additions & 2 deletions backend/maelstro/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ def __init__(self, config_file: str):
self.read_all_credentials()

def read_all_credentials(self) -> None:
common_credentials = substitute_single_credentials_from_env(
self.config["sources"]
)
for gn_instance in self.config["sources"]["geonetwork_instances"]:
substitute_single_credentials_from_env(gn_instance)
substitute_single_credentials_from_env(gn_instance, common_credentials)

for gs_instance in self.config["sources"]["geonetwork_instances"]:
substitute_single_credentials_from_env(gs_instance)
substitute_single_credentials_from_env(gs_instance, common_credentials)

for geor_instance in self.config["destinations"].values():
common_credentials = substitute_single_credentials_from_env(geor_instance)
Expand Down Expand Up @@ -112,3 +115,4 @@ def read_value_from_env(
env_value = os.environ.get(env_var)
if env_value is not None:
server_instance[value_type] = env_value
server_instance.pop(f"{value_type}_env_var")
14 changes: 14 additions & 0 deletions backend/tests/doc_sample_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sources:
login: admin
password_env_var: COMMON_PW
geonetwork_instances:
- name: "a"
password: "pwA"
- name: "b"
login: "B"
password: default_unused
password_env_var: "PASSWORD_B"
- name: "c"
login: "C"

destinations: {}
120 changes: 120 additions & 0 deletions backend/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import os
import pytest
from maelstro.config import Config, ConfigError


@pytest.fixture
def test_config_path():
return os.path.join(os.path.dirname(__file__), "test_config.yaml")


def test_init(test_config_path):
conf = Config(test_config_path)
assert conf.config == {
"sources": {
"geonetwork_instances": [
{
"name": "GeonetworkMaster",
"api_url": "https://demo.georchestra.org/geonetwork/srv/api",
}
],
"geoserver_instances": [
{
"url": "https://mastergs.rennesmetropole.fr/geoserver/",
"login": "test",
"password": 1234
},
{
"url": "https://mastergs.rennesmetropole.fr/geoserver-geofence/",
"login": "toto6",
"password": "Str0ng_passW0rd"
}
]
},
"destinations": {
"CompoLocale": {
"geonetwork": {
"api_url": "http://geonetwork:8080/geonetwork/srv/api",
},
"geoserver": {
"url": "https://georchestra-127-0-0-1.nip.io/geoserver"
}
},
"PlateformeProfessionnelle": {
"login": "toto",
"password": "passW0rd",
"geoserver": {
"url": "https://portail.sig.rennesmetropole.fr/geoserver",
"login": "toto",
"password": "overridePW"
},
"geonetwork": {
"api_url": "https://portail.sig.rennesmetropole.fr/geonetwork/srv/api",
"login": "toto",
"password": "passW0rd"
}
},
"PlateformePublique": {
"geoserver": {
"url": "https://public.sig.rennesmetropole.fr/geoserver",
"login": "toto2",
"password": "Str0ng_passW0rd"
},
"geonetwork": {
"api_url": "https://public.sig.rennesmetropole.fr/geonetwork/srv/api",
"login": "toto3",
"password": "Str0ng_passW0rd"
}
}
}
}


def test_subst_env(test_config_path):
os.environ["DEMO_LOGIN"] = "demo"
os.environ["LOCAL_LOGIN"] = "test"
conf = Config(test_config_path)
conf.config["sources"]["geonetwork_instances"][0]["login"] == "demo"
conf.config["sources"]["geonetwork_instances"][0]["password"] == "demo"
conf.config["destinations"]["CompoLocale"]["geonetwork"]["login"] == "test"
conf.config["destinations"]["CompoLocale"]["geonetwork"]["password"] == "test"


def test_get_info(test_config_path):
os.environ.pop("DEMO_LOGIN")
os.environ["DEMO_LOGIN"] = "demo"
conf = Config(test_config_path)
assert conf.get_access_info(True, True, "GeonetworkMaster") == {
"auth": ("demo", "demo"),
"url": "https://demo.georchestra.org/geonetwork/srv/api",
}
assert conf.get_access_info(True, False, "https://mastergs.rennesmetropole.fr/geoserver-geofence/") == {
"auth": ("toto6", "Str0ng_passW0rd"),
"url": "https://mastergs.rennesmetropole.fr/geoserver-geofence/",
}
assert conf.get_access_info(False, True, "PlateformeProfessionnelle") == {
"auth": ("toto", "passW0rd"),
"url": "https://portail.sig.rennesmetropole.fr/geonetwork/srv/api",
}
assert conf.get_access_info(False, False, "CompoLocale") == {
"auth": None,
"url": "https://georchestra-127-0-0-1.nip.io/geoserver",
}
with pytest.raises(ConfigError) as err:
conf.get_access_info(False, False, "MissingKey")


def test_doc_sample():
os.environ["PASSWORD_B"] = "pwB"
conf = Config(os.path.join(os.path.dirname(__file__), "doc_sample_config.yaml"))
assert conf.config == {
"sources": {
"login": "admin",
"geonetwork_instances": [
{"name": "a", "login": "admin", "password": "pwA"},
{"name": "b", "login": "B", "password": "pwB"},
{"name": "c", "login": "C"},
]
},
"destinations": {},
}

0 comments on commit 79099cf

Please sign in to comment.