netbox-docker/docker/configuration.docker.py

80 lines
2.1 KiB
Python
Raw Normal View History

## Generic Parts
# These functions are providing the functionality to load
# arbitrary configuration files.
#
# They can be imported by other code (see `ldap_config.py` for an example).
2020-10-17 19:34:45 -05:00
from os.path import abspath, isfile
from os import scandir
import importlib.util
import sys
2020-10-17 19:34:45 -05:00
def _filename(f):
return f.name
def _import(module_name, path, loaded_configurations):
2020-10-17 19:34:45 -05:00
spec = importlib.util.spec_from_file_location('', path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
2020-10-17 19:34:45 -05:00
sys.modules[module_name] = module
loaded_configurations.insert(0, module)
2020-10-17 19:34:45 -05:00
print(f"🧬 loaded config '{path}'")
def read_configurations(config_module, config_dir, main_config):
loaded_configurations = []
main_config_path = abspath(f'{config_dir}/{main_config}.py')
if isfile(main_config_path):
_import(f'{config_module}.{main_config}', main_config_path, loaded_configurations)
else:
print(f"⚠️ Main configuration '{main_config_path}' not found.")
with scandir(config_dir) as it:
for f in sorted(it, key=_filename):
if not f.is_file():
continue
2020-10-17 19:34:45 -05:00
if f.name.startswith('__'):
continue
2020-10-17 19:34:45 -05:00
if not f.name.endswith('.py'):
continue
2020-10-17 19:34:45 -05:00
if f.name == f'{config_dir}.py':
continue
2020-10-17 19:34:45 -05:00
module_name = f"{config_module}.{f.name[:-len('.py')]}".replace(".", "_")
_import(module_name, f.path, loaded_configurations)
2020-10-17 19:34:45 -05:00
if len(loaded_configurations) == 0:
print(f"‼️ No configuration files found in '{config_dir}'.")
raise ImportError(f"No configuration files found in '{config_dir}'.")
2020-10-17 19:34:45 -05:00
return loaded_configurations
## Specific Parts
# This section's code actually loads the various configuration files
# into the module with the given name.
# It contains the logic to resolve arbitrary configuration options by
# levaraging dynamic programming using `__getattr__`.
_loaded_configurations = read_configurations(
config_dir = '/etc/netbox/config/',
config_module = 'netbox.configuration',
main_config = 'configuration')
def __getattr__(name):
for config in _loaded_configurations:
try:
return getattr(config, name)
except:
pass
raise AttributeError