From e4439390febc874823d5b65d6ee1529d19d80b0d Mon Sep 17 00:00:00 2001 From: jo Date: Mon, 6 Jun 2022 17:04:26 +0200 Subject: [PATCH] feat: change config file format to yaml - docs: add link to yaml.org BREAKING: The `ini` configuration file format changed to `yml`. Please rewrite your configuration file using the yaml format. --- api-client/tests/version2_test.py | 6 +- docs/admin-manual/custom-authentication.md | 32 ++--- docs/admin-manual/setup/configuration.md | 144 ++++++++++----------- docs/admin-manual/setup/reverse-proxy.md | 9 +- docs/releases/unreleased.md | 10 ++ legacy/application/configs/conf.php | 4 +- legacy/packages.ini | 3 + legacy/tests/config/airtime.conf | 11 -- legacy/tests/config/config.yml | 11 ++ shared/libretime_shared/config.py | 8 -- shared/tests/config_test.py | 22 ---- 11 files changed, 121 insertions(+), 139 deletions(-) delete mode 100644 legacy/tests/config/airtime.conf create mode 100644 legacy/tests/config/config.yml diff --git a/api-client/tests/version2_test.py b/api-client/tests/version2_test.py index 421f87cb3..a902d5cf0 100644 --- a/api-client/tests/version2_test.py +++ b/api-client/tests/version2_test.py @@ -10,9 +10,9 @@ def config_filepath(tmp_path: Path): filepath = tmp_path / "airtime.conf" filepath.write_text( """ -[general] -public_url = http://localhost/test -api_key = TEST_KEY +general: + public_url: http://localhost/test + api_key: TEST_KEY """ ) return filepath diff --git a/docs/admin-manual/custom-authentication.md b/docs/admin-manual/custom-authentication.md index b3808fdb3..ed8b8126e 100644 --- a/docs/admin-manual/custom-authentication.md +++ b/docs/admin-manual/custom-authentication.md @@ -60,7 +60,7 @@ set up beforehand. You can configure everything pertaining to how LibreTime accesses LDAP in `/etc/airtime/airtime.conf`. The default file has the following values you need to change. -```ini +```yml # # ---------------------------------------------------------------------- # L D A P @@ -83,27 +83,27 @@ You can configure everything pertaining to how LibreTime accesses LDAP in # Lets LibreTime assign user types based on the # group a given user is in. # -[ldap] -hostname = ldap.example.org -binddn = 'uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org' -password = hackme -account_domain = INT.EXAMPLE.ORG -basedn = 'cn=users,cn=accounts,dc=int,dc=example,dc=org' -filter_field = uid -groupmap_guest = 'cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_host = 'cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_program_manager = 'cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_admin = 'cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_superadmin = 'cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org' +ldap: + hostname: ldap.example.org + binddn: "uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org" + password: hackme + account_domain: INT.EXAMPLE.ORG + basedn: "cn=users,cn=accounts,dc=int,dc=example,dc=org" + filter_field: uid + groupmap_guest: "cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_host: "cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_program_manager: "cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_admin: "cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_superadmin: "cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org" ``` ### Enable FreeIPA authentication After everything is set up properly you can enable FreeIPA auth in `airtime.conf`: -``` -[general] -auth = LibreTime_Auth_Adaptor_FreeIpa +```yml +general: + auth: LibreTime_Auth_Adaptor_FreeIpa ``` You should now be able to use your FreeIPA credentials to log in to LibreTime. diff --git a/docs/admin-manual/setup/configuration.md b/docs/admin-manual/setup/configuration.md index c249136b6..3ada2afce 100644 --- a/docs/admin-manual/setup/configuration.md +++ b/docs/admin-manual/setup/configuration.md @@ -9,19 +9,19 @@ To configure LibreTime, you need to edit the `/etc/airtime/airtime.conf` file. T The `general` section configure anything related to the legacy and API services. -```ini -[general] -# The public url. This field is REQUIRED -public_url = https://example.com -# The internal API authentication key, this field is REQUIRED -api_key = some_random_generated_secret! +```yml +general: + # The public url. This field is REQUIRED + public_url: https://example.com + # The internal API authentication key, this field is REQUIRED + api_key: some_random_generated_secret! -# How many hours ahead Playout should cache scheduled media files, default is 1 -cache_ahead_hours = 1 + # How many hours ahead Playout should cache scheduled media files, default is 1 + cache_ahead_hours: 1 -# Authentication adaptor to use for the legacy service, default is local -# Specify a class like LibreTime_Auth_Adaptor_FreeIpa to replace the built-in adaptor -auth = local + # Authentication adaptor to use for the legacy service, default is local + # Specify a class like LibreTime_Auth_Adaptor_FreeIpa to replace the built-in adaptor + auth: local ``` In order to apply the changes made in this section, please restart the following services: @@ -45,18 +45,18 @@ Before editing this section be sure to update the PostgreSQL server with the des ::: -```ini -[database] -# The hostname of the PostgreSQL server, default is localhost -host = localhost -# The port of the PostgreSQL server, default is 5432 -port = 5432 -# The name of the PostgreSQL database, default is libretime -name = libretime -# The username of the PostgreSQL user, default is libretime -user = libretime -# The password of the PostgreSQL user, default is libretime -password = some_random_generated_secret! +```yml +database: + # The hostname of the PostgreSQL server, default is localhost + host: localhost + # The port of the PostgreSQL server, default is 5432 + port: 5432 + # The name of the PostgreSQL database, default is libretime + name: libretime + # The username of the PostgreSQL user, default is libretime + user: libretime + # The password of the PostgreSQL user, default is libretime + password: some_random_generated_secret! ``` In order to apply the changes made in this section, please restart the following services: @@ -77,18 +77,18 @@ Before editing this section be sure to update the RabbitMQ server with the desir ::: -```ini -[rabbitmq] -# The hostname of the RabbitMQ server, default is localhost -host = localhost -# The port of the RabbitMQ server, default is 5672 -port = 5672 -# The virtual host of RabbitMQ server, default is /libretime -vhost = /libretime -# The username of the RabbitMQ user, default is libretime -user = libretime -# The password of the RabbitMQ user, default is libretime -password = some_random_generated_secret! +```yml +rabbitmq: + # The hostname of the RabbitMQ server, default is localhost + host: localhost + # The port of the RabbitMQ server, default is 5672 + port: 5672 + # The virtual host of RabbitMQ server, default is /libretime + vhost: /libretime + # The username of the RabbitMQ user, default is libretime + user: libretime + # The password of the RabbitMQ user, default is libretime + password: some_random_generated_secret! ``` In order to apply the changes made in this section, please restart the following services: @@ -104,23 +104,23 @@ libretime-playout The `playout` section configure anything related to the playout service. -```ini -[playout] -# Liquidsoap connection host, default is localhost -liquidsoap_host = localhost -# Liquidsoap connection port, default is 1234 -liquidsoap_port = 1234 +```yml +playout: + # Liquidsoap connection host, default is localhost + liquidsoap_host: localhost + # Liquidsoap connection port, default is 1234 + liquidsoap_port: 1234 -# The format for recordings, allowed values are ogg,mp3, default is ogg -record_file_format = ogg -# The bitrate for recordings, default is 256 -record_bitrate = 256 -# The samplerate for recordings, default is 44100 -record_samplerate = 44100 -# The number of channels for recordings, default is 2 -record_channels = 2 -# The sample size for recordings, default is 16 -record_sample_size = 16 + # The format for recordings, allowed values are ogg,mp3, default is ogg + record_file_format: ogg + # The bitrate for recordings, default is 256 + record_bitrate: 256 + # The samplerate for recordings, default is 44100 + record_samplerate: 44100 + # The number of channels for recordings, default is 2 + record_channels: 2 + # The sample size for recordings, default is 16 + record_sample_size: 16 ``` In order to apply the changes made in this section, please restart the following services: @@ -133,26 +133,26 @@ libretime-playout The `ldap` section provide additional configuration for the authentication mechanism defined in `general.auth`, please see the [custom authentication documentation](../custom-authentication.md) for more details. -```ini -[ldap] -# Hostname of LDAP server -hostname = ldap.example.org -# Complete DN of user used to bind to LDAP -binddn = 'uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org' -# Password for binddn user -password = hackme -# Domain part of username -account_domain = INT.EXAMPLE.ORG -# Base search DN -basedn = 'cn=users,cn=accounts,dc=int,dc=example,dc=org' -# Name of the uid field for searching. Usually uid, may be cn -filter_field = uid +```yml +ldap: + # Hostname of LDAP server + hostname: ldap.example.org + # Complete DN of user used to bind to LDAP + binddn: "uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org" + # Password for binddn user + password: hackme + # Domain part of username + account_domain: INT.EXAMPLE.ORG + # Base search DN + basedn: "cn=users,cn=accounts,dc=int,dc=example,dc=org" + # Name of the uid field for searching. Usually uid, may be cn + filter_field: uid -# Map user types to LDAP groups. Assign user types based on the group of a given user -# Key format is groupmap_* -groupmap_superadmin = 'cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_admin = 'cn=admin,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_program_manager = 'cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_host = 'cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org' -groupmap_guest = 'cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org' + # Map user types to LDAP groups. Assign user types based on the group of a given user + # Key format is groupmap_* + groupmap_superadmin: "cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_admin: "cn=admin,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_program_manager: "cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_host: "cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org" + groupmap_guest: "cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org" ``` diff --git a/docs/admin-manual/setup/reverse-proxy.md b/docs/admin-manual/setup/reverse-proxy.md index 4ca358d08..71f1410bd 100644 --- a/docs/admin-manual/setup/reverse-proxy.md +++ b/docs/admin-manual/setup/reverse-proxy.md @@ -100,13 +100,12 @@ https://localhost http://localhost ``` -Finally, the configuration file needs updating. Under `[general]`, `force_ssl` +Finally, the configuration file needs updating. Under `general.force_ssl` needs to be set to true: -```ini -[general] -... -force_ssl = true +```yml +general: + force_ssl: true ``` ## SSL Configuration diff --git a/docs/releases/unreleased.md b/docs/releases/unreleased.md index e0c573b33..82872a5f0 100644 --- a/docs/releases/unreleased.md +++ b/docs/releases/unreleased.md @@ -18,6 +18,16 @@ The LibreTime project wants to thank the following contributors for authoring PR ## :arrow_up: Upgrading +### New configuration file + +:::caution + +Please run this **before the upgrade procedure**! + +::: + +The configuration file format changed to `yml`. Please rewrite your [configuration file](../admin-manual/setup/configuration.md) using the [yaml format](https://yaml.org/). + ### Apache and PHP configuration files :::caution diff --git a/legacy/application/configs/conf.php b/legacy/application/configs/conf.php index 0ca62d51e..f1cd1638d 100644 --- a/legacy/application/configs/conf.php +++ b/legacy/application/configs/conf.php @@ -17,7 +17,7 @@ class Config public static function loadConfig() { $filename = $_SERVER['LIBRETIME_CONFIG_FILEPATH'] ?? LIBRETIME_CONFIG_FILEPATH; - $values = parse_ini_file($filename, true); + $values = yaml_parse_file($filename); $CC_CONFIG = []; @@ -28,7 +28,7 @@ class Config // Explode public_url into multiple component with possible defaults for required fields try { $public_url = Uri::createFromString($values['general']['public_url']); - } catch (UriException $e) { + } catch (UriException|TypeError $e) { echo 'could not parse configuration field general.public_url: ' . $e->getMessage(); exit; diff --git a/legacy/packages.ini b/legacy/packages.ini index feb069f56..92256bded 100644 --- a/legacy/packages.ini +++ b/legacy/packages.ini @@ -29,6 +29,7 @@ php7.2-gd = bionic php7.2-mbstring = bionic php7.2-pgsql = bionic php7.2-xml = bionic +php7.2-yaml = bionic # Buster [php7.3] @@ -44,6 +45,7 @@ php7.3-gd = buster php7.3-mbstring = buster php7.3-pgsql = buster php7.3-xml = buster +php7.3-yaml = buster # Bullseye, Focal [php7.4] @@ -59,3 +61,4 @@ php7.4-gd = bullseye, focal php7.4-mbstring = bullseye, focal php7.4-pgsql = bullseye, focal php7.4-xml = bullseye, focal +php7.4-yaml = bullseye, focal diff --git a/legacy/tests/config/airtime.conf b/legacy/tests/config/airtime.conf deleted file mode 100644 index a25e4c448..000000000 --- a/legacy/tests/config/airtime.conf +++ /dev/null @@ -1,11 +0,0 @@ -[general] -dev_env = testing -public_url = http://localhost -api_key = H2NRICX6CM8F50CU123C - -[database] -host = localhost -port = 5432 -name = libretime_test -user = libretime -password = libretime diff --git a/legacy/tests/config/config.yml b/legacy/tests/config/config.yml new file mode 100644 index 000000000..64b6121e8 --- /dev/null +++ b/legacy/tests/config/config.yml @@ -0,0 +1,11 @@ +general: + dev_env: testing + public_url: http://localhost + api_key: H2NRICX6CM8F50CU123C + +database: + host: localhost + port: 5432 + name: libretime_test + user: libretime + password: libretime diff --git a/shared/libretime_shared/config.py b/shared/libretime_shared/config.py index e8940daba..5dd2fefc9 100644 --- a/shared/libretime_shared/config.py +++ b/shared/libretime_shared/config.py @@ -1,5 +1,4 @@ import sys -from configparser import ConfigParser from os import environ from pathlib import Path from typing import Any, Dict, List, Optional, Union @@ -96,13 +95,6 @@ class BaseConfig(BaseModel): logger.warning(f"provided config filepath '{filepath}' is not a file") return {} - # pylint: disable=fixme - # TODO: Remove ability to load ini files once yaml if fully supported. - if filepath.suffix == ".conf": - config = ConfigParser() - config.read_string(filepath.read_text(encoding="utf-8")) - return {s: dict(config.items(s)) for s in config.sections()} - try: return safe_load(filepath.read_text(encoding="utf-8")) except YAMLError as error: diff --git a/shared/tests/config_test.py b/shared/tests/config_test.py index 7897ad0bd..f83f811fd 100644 --- a/shared/tests/config_test.py +++ b/shared/tests/config_test.py @@ -134,28 +134,6 @@ def test_base_config_required_submodel(tmp_path: Path): FixtureWithRequiredSubmodelConfig(filepath=None) -FIXTURE_CONFIG_RAW_INI = """ -[database] -host = changed -port = 6666 -""" - - -def test_base_config_ini(tmp_path: Path): - config_filepath = tmp_path / "config.conf" - config_filepath.write_text(FIXTURE_CONFIG_RAW_INI) - - with mock.patch.dict( - environ, - {"LIBRETIME_API_KEY": "f3bf04fc"}, - ): - config = FixtureConfig(filepath=config_filepath) - - assert config.api_key == "f3bf04fc" - assert config.database.host == "changed" - assert config.database.port == 6666 - - FIXTURE_CONFIG_RAW_MISSING = """ database: host: "localhost"