mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-18 14:34:24 +02:00
Solved None key bugs and implemented tests to prevent it in the future
This commit is contained in:
parent
9159a0c7d3
commit
e729706ec6
@ -8,7 +8,6 @@ features:
|
|||||||
css: true
|
css: true
|
||||||
portfolio_iframe: true
|
portfolio_iframe: true
|
||||||
central_database: true
|
central_database: true
|
||||||
credentials:
|
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "accounting.{{ primary_domain }}"
|
- "accounting.{{ primary_domain }}"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
image:
|
image:
|
||||||
web: "attendize_web:latest"
|
web: "attendize_web:latest"
|
||||||
worker: "attendize_worker:latest"
|
worker: "attendize_worker:latest"
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
enable_greenlight: "true"
|
enable_greenlight: "true"
|
||||||
setup: false
|
setup: false
|
||||||
credentials:
|
|
||||||
database:
|
database:
|
||||||
name: "multiple_databases"
|
name: "multiple_databases"
|
||||||
username: "postgres2"
|
username: "postgres2"
|
||||||
|
@ -2,7 +2,6 @@ images:
|
|||||||
pds: "ghcr.io/bluesky-social/pds:latest"
|
pds: "ghcr.io/bluesky-social/pds:latest"
|
||||||
pds:
|
pds:
|
||||||
version: "latest"
|
version: "latest"
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
network: "discourse_default" # Name of the docker network
|
network: "discourse_default" # Name of the docker network
|
||||||
container: "discourse_application" # Name of the container application
|
container: "discourse_application" # Name of the container application
|
||||||
repository: "discourse_repository" # Name of the repository folder
|
repository: "discourse_repository" # Name of the repository folder
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -24,8 +24,8 @@ oauth2_proxy:
|
|||||||
application: "application"
|
application: "application"
|
||||||
port: "80"
|
port: "80"
|
||||||
addons:
|
addons:
|
||||||
keycloakpassword:
|
keycloakpassword: {}
|
||||||
ldapauth:
|
ldapauth: {}
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -19,7 +19,6 @@ features:
|
|||||||
ldap: true
|
ldap: true
|
||||||
central_database: true
|
central_database: true
|
||||||
oauth2: false # Doesn't make sense to activate it atm, because login is possible on homepage
|
oauth2: false # Doesn't make sense to activate it atm, because login is possible on homepage
|
||||||
credentials:
|
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "audio.{{ primary_domain }}"
|
- "audio.{{ primary_domain }}"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
images:
|
images:
|
||||||
keycloak: "quay.io/keycloak/keycloak:latest"
|
keycloak: "quay.io/keycloak/keycloak:latest"
|
||||||
import_realm: True # If True realm will be imported. If false skip.
|
import_realm: True # If True realm will be imported. If false skip.
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: false
|
css: false
|
||||||
|
@ -3,7 +3,6 @@ images:
|
|||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
application: application
|
application: application
|
||||||
port: 80
|
port: 80
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -6,6 +6,5 @@ network:
|
|||||||
public: False # Set to true in inventory file if you want to expose the LDAP port to the internet
|
public: False # Set to true in inventory file if you want to expose the LDAP port to the internet
|
||||||
hostname: "ldap" # Hostname of the LDAP Server in the central_ldap network
|
hostname: "ldap" # Hostname of the LDAP Server in the central_ldap network
|
||||||
webinterface: "lam" # The webinterface which should be used. Possible: lam and phpldapadmin
|
webinterface: "lam" # The webinterface which should be used. Possible: lam and phpldapadmin
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
ldap: true
|
ldap: true
|
@ -3,7 +3,6 @@ oidc:
|
|||||||
email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used
|
email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used
|
||||||
enable_user_creation: true # Users will be created if not existing
|
enable_user_creation: true # Users will be created if not existing
|
||||||
domain: "{{primary_domain}}" # The main domain from which mails will be send \ email suffix behind @
|
domain: "{{primary_domain}}" # The main domain from which mails will be send \ email suffix behind @
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: false
|
css: false
|
||||||
|
@ -3,7 +3,6 @@ images:
|
|||||||
streaming: "ghcr.io/mastodon/mastodon-streaming:latest"
|
streaming: "ghcr.io/mastodon/mastodon-streaming:latest"
|
||||||
single_user_mode: false # Set true for initial setup
|
single_user_mode: false # Set true for initial setup
|
||||||
setup: false # Set true in inventory file to execute the setup and initializing procedures
|
setup: false # Set true in inventory file to execute the setup and initializing procedures
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -24,7 +24,6 @@ oidc:
|
|||||||
# @see https://apps.nextcloud.com/apps/oidc_login
|
# @see https://apps.nextcloud.com/apps/oidc_login
|
||||||
# @see https://apps.nextcloud.com/apps/sociallogin
|
# @see https://apps.nextcloud.com/apps/sociallogin
|
||||||
flavor: "oidc_login" # Keeping on sociallogin because the other option is not implemented yet
|
flavor: "oidc_login" # Keeping on sociallogin because the other option is not implemented yet
|
||||||
credentials:
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: false
|
css: false
|
||||||
|
@ -16,7 +16,7 @@ features:
|
|||||||
central_database: false # Enable Central Database Network
|
central_database: false # Enable Central Database Network
|
||||||
recaptcha: false # Enable ReCaptcha
|
recaptcha: false # Enable ReCaptcha
|
||||||
oauth2: false # Enable the OAuth2-Proy
|
oauth2: false # Enable the OAuth2-Proy
|
||||||
csp:
|
csp: {}
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "icons.{{ primary_domain }}"
|
- "icons.{{ primary_domain }}"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
version: "latest"
|
version: "latest"
|
||||||
oidc:
|
oidc: {}
|
||||||
# Taiga doesn't have a functioning oidc support at the moment
|
# Taiga doesn't have a functioning oidc support at the moment
|
||||||
# See
|
# See
|
||||||
# - https://community.taiga.io/t/taiga-and-oidc-plugin/4866
|
# - https://community.taiga.io/t/taiga-and-oidc-plugin/4866
|
||||||
|
61
tests/integration/test_configuration_non_empty.py
Normal file
61
tests/integration/test_configuration_non_empty.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import yaml
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def find_none_values(data, prefix=None):
|
||||||
|
"""
|
||||||
|
Recursively find keys with None values in a nested dict or list.
|
||||||
|
Returns a list of (path, value) tuples where value is None.
|
||||||
|
"""
|
||||||
|
errors = []
|
||||||
|
if prefix is None:
|
||||||
|
prefix = []
|
||||||
|
|
||||||
|
if isinstance(data, dict):
|
||||||
|
for key, value in data.items():
|
||||||
|
path = prefix + [str(key)]
|
||||||
|
if value is None:
|
||||||
|
errors.append((".".join(path), value))
|
||||||
|
elif isinstance(value, (dict, list)):
|
||||||
|
errors.extend(find_none_values(value, path))
|
||||||
|
elif isinstance(data, list):
|
||||||
|
for idx, item in enumerate(data):
|
||||||
|
path = prefix + [f"[{idx}]"]
|
||||||
|
if item is None:
|
||||||
|
errors.append((".".join(path), item))
|
||||||
|
elif isinstance(item, (dict, list)):
|
||||||
|
errors.extend(find_none_values(item, path))
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigurationNoNone(unittest.TestCase):
|
||||||
|
def test_configuration_files_have_no_none_values(self):
|
||||||
|
# Find all configuration.yml files under roles/*/vars
|
||||||
|
pattern = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
os.pardir, os.pardir,
|
||||||
|
'roles', '*', 'vars', 'configuration.yml'
|
||||||
|
)
|
||||||
|
files = glob.glob(pattern)
|
||||||
|
self.assertTrue(files, f"No configuration.yml files found with pattern: {pattern}")
|
||||||
|
|
||||||
|
all_errors = []
|
||||||
|
for filepath in files:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
try:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
self.fail(f"Failed to parse YAML in {filepath}: {e}")
|
||||||
|
errors = find_none_values(data)
|
||||||
|
for path, value in errors:
|
||||||
|
all_errors.append(f"{filepath}: Key '{path}' is None")
|
||||||
|
|
||||||
|
if all_errors:
|
||||||
|
self.fail("None values found in configuration files:\n" + "\n".join(all_errors))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user