-
Notifications
You must be signed in to change notification settings - Fork 725
/
Copy pathevaluate_config.py
156 lines (132 loc) · 6 KB
/
evaluate_config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2025, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
import os
import sys
import keyring
import importlib.util
# User configs loaded from config_local, config_distro etc.
custom_config_settings = {}
# Function to Extract settings from config_local, config_distro etc.
def get_variables_from_module(module_name):
module = globals().get(module_name, None)
variables = {}
if module:
variables = {key: value for key, value in module.__dict__.items()
if not (key.startswith('__') or key.startswith('_')) and
validate_config_variable(key, value)}
return variables
# Function to load config_distro at custom path
def import_module_from_path(module_name, file_path):
# Create a module spec
spec = importlib.util.spec_from_file_location(module_name, file_path)
# Create the module based on the spec
module = importlib.util.module_from_spec(spec)
# Execute the module (this loads it)
spec.loader.exec_module(module)
return module
def validate_config_variable(key, value):
boolean_keys = ['SERVER_MODE', 'ENHANCED_COOKIE_PROTECTION',
'SUPPORT_SSH_TUNNEL', 'ALLOW_SAVE_TUNNEL_PASSWORD',
'MASTER_PASSWORD_REQUIRED']
integer_keys = ['DEFAULT_SERVER_PORT', 'SERVER_HEARTBEAT_TIMEOUT',
'LOG_ROTATION_SIZE', 'LOG_ROTATION_AGE',
'LOG_ROTATION_MAX_LOG_FILES', 'MAX_SESSION_IDLE_TIME']
if key in boolean_keys and not isinstance(value, bool):
exception_msg = 'Expected boolean value for %s; got %r' % (key, value)
raise ValueError(exception_msg)
elif key in integer_keys and not isinstance(value, int):
exception_msg = 'Expected integer value for %s; got %r' % (key, value)
raise ValueError(exception_msg)
else:
# Do not validate
return True
# Load distribution-specific config overrides
try:
if 'CONFIG_DISTRO_FILE_PATH' in os.environ:
config_distro_path = os.environ['CONFIG_DISTRO_FILE_PATH']
config_distro = import_module_from_path('config_distro',
config_distro_path)
else:
import config_distro
config_distro_settings = get_variables_from_module('config_distro')
custom_config_settings.update(config_distro_settings)
except ImportError:
pass
# Load local config overrides
try:
import config_local
config_local_settings = get_variables_from_module('config_local')
custom_config_settings.update(config_local_settings)
except ImportError:
pass
# Load system config overrides. We do this last, so that the sysadmin can
# override anything they want from a config file that's in a protected system
# directory and away from pgAdmin to avoid invalidating signatures.
system_config_dir = '/etc/pgadmin'
if sys.platform.startswith('win32'):
system_config_dir = os.environ['CommonProgramFiles'] + '/pgadmin'
elif sys.platform.startswith('darwin'):
system_config_dir = '/Library/Preferences/pgadmin'
if os.path.exists(system_config_dir + '/config_system.py'):
try:
sys.path.insert(0, system_config_dir)
import config_system
config_system_settings = get_variables_from_module('config_system')
custom_config_settings.update(config_system_settings)
except ImportError:
pass
def evaluate_and_patch_config(config: dict) -> dict:
# Update settings for 'LOG_FILE', 'SQLITE_PATH', 'SESSION_DB_PATH',
# 'AZURE_CREDENTIAL_CACHE_DIR', 'KERBEROS_CCACHE_DIR', 'STORAGE_DIR'
# of DATA_DIR is user defined
data_dir_dependent_settings = \
['LOG_FILE', 'SQLITE_PATH', 'SESSION_DB_PATH',
'AZURE_CREDENTIAL_CACHE_DIR', 'KERBEROS_CCACHE_DIR', 'STORAGE_DIR']
if 'DATA_DIR' in custom_config_settings:
for setting in data_dir_dependent_settings:
if setting not in custom_config_settings:
data_dir = custom_config_settings['DATA_DIR']
file_dir_name = os.path.basename(config.get(setting))
config.update(
{setting: os.path.join(data_dir, file_dir_name)})
# To use psycopg3 driver, need to specify +psycopg in conn URI
if 'CONFIG_DATABASE_URI' in custom_config_settings:
db_uri = custom_config_settings['CONFIG_DATABASE_URI']
if db_uri.startswith('postgresql:'):
custom_config_settings['CONFIG_DATABASE_URI'] = \
'postgresql+psycopg:{0}'.format(db_uri[db_uri.find(':') + 1:])
# Finally update config user configs
config.update(custom_config_settings)
# Override DEFAULT_SERVER value from environment variable.
if 'PGADMIN_CONFIG_DEFAULT_SERVER' in os.environ:
config['DEFAULT_SERVER'] = os.environ['PGADMIN_CONFIG_DEFAULT_SERVER']
# Disable USER_INACTIVITY_TIMEOUT when SERVER_MODE=False
if not config.get('SERVER_MODE'):
config['USER_INACTIVITY_TIMEOUT'] = 0
# Enable PSQL in Desktop Mode.
config['ENABLE_PSQL'] = True
if config.get('SERVER_MODE'):
config.setdefault('USE_OS_SECRET_STORAGE', False)
config.setdefault('KEYRING_NAME', '')
else:
k_name = keyring.get_keyring().name
# Setup USE_OS_SECRET_STORAGE false as no keyring backend available
if k_name == 'fail Keyring':
config['USE_OS_SECRET_STORAGE'] = False
config['KEYRING_NAME'] = ''
else:
config.setdefault('KEYRING_NAME', k_name)
config.setdefault('SESSION_COOKIE_PATH', config.get('COOKIE_DEFAULT_PATH'))
# if a script name is preset, session cookies should go to sub path
if 'SCRIPT_NAME' in os.environ and os.environ["SCRIPT_NAME"]:
config.update(dict({
'APPLICATION_ROOT': os.environ["SCRIPT_NAME"],
'SESSION_COOKIE_PATH': os.environ["SCRIPT_NAME"],
}))
return config