1diff --git a/src/oncall/bin/notifier.py b/src/oncall/bin/notifier.py
2index 25142b8..cbc92aa 100644
3--- a/src/oncall/bin/notifier.py
4+++ b/src/oncall/bin/notifier.py
5@@ -32,11 +32,29 @@ send_queue = queue.Queue()
6
7 default_timezone = None
8
9+def merge_dict(extend_me, extend_by):
10+ if isinstance(extend_by, dict):
11+ for k, v in extend_by.items():
12+ if isinstance(v, dict) and isinstance(extend_me.get(k), dict):
13+ merge_dict(extend_me[k], v)
14+ else:
15+ extend_me[k] = v
16+ return extend_me
17
18 def load_config_file(config_path):
19 with open(config_path, 'r', encoding='utf-8') as h:
20 config = yaml.safe_load(h)
21
22+ # Check for extra config files from environment variable
23+ extra_config_paths = os.getenv('ONCALL_EXTRA_CONFIG')
24+ if extra_config_paths:
25+ for extra_path in extra_config_paths.split(','):
26+ extra_path = extra_path.strip()
27+ if os.path.isfile(extra_path):
28+ with open(extra_path, 'r') as f:
29+ extra_config = yaml.safe_load(f) or {}
30+ config = merge_dict(config, extra_config)
31+
32 if 'init_config_hook' in config:
33 try:
34 module = config['init_config_hook']
35diff --git a/src/oncall/user_sync/ldap_sync.py b/src/oncall/user_sync/ldap_sync.py
36index ef9a8ec..c5f027d 100644
37--- a/src/oncall/user_sync/ldap_sync.py
38+++ b/src/oncall/user_sync/ldap_sync.py
39@@ -6,6 +6,7 @@ import time
40 import yaml
41 import logging
42 import ldap
43+import os
44
45 from oncall import metrics
46 from ldap.controls import SimplePagedResultsControl
47@@ -447,9 +448,28 @@ def main(config):
48 logger.info('Sleeping for %s seconds' % sleep_time)
49 sleep(sleep_time)
50
51+def merge_dict(extend_me, extend_by):
52+ if isinstance(extend_by, dict):
53+ for k, v in extend_by.items():
54+ if isinstance(v, dict) and isinstance(extend_me.get(k), dict):
55+ merge_dict(extend_me[k], v)
56+ else:
57+ extend_me[k] = v
58+ return extend_me
59
60 if __name__ == '__main__':
61 config_path = sys.argv[1]
62 with open(config_path, 'r', encoding='utf-8') as config_file:
63 config = yaml.safe_load(config_file)
64+
65+ # Check for extra config files from environment variable
66+ extra_config_paths = os.getenv('ONCALL_EXTRA_CONFIG')
67+ if extra_config_paths:
68+ for extra_path in extra_config_paths.split(','):
69+ extra_path = extra_path.strip()
70+ if os.path.isfile(extra_path):
71+ with open(extra_path, 'r') as f:
72+ extra_config = yaml.safe_load(f) or {}
73+ config = merge_dict(config, extra_config)
74+
75 main(config)
76diff --git a/src/oncall/utils.py b/src/oncall/utils.py
77index a0b695c..278ca1d 100644
78--- a/src/oncall/utils.py
79+++ b/src/oncall/utils.py
80@@ -13,6 +13,7 @@ from pytz import timezone
81 from .constants import ONCALL_REMINDER
82 from . import constants
83 import re
84+import os
85
86 invalid_char_reg = re.compile(r'[!"#%-,\.\/;->@\[-\^`\{-~]+')
87 DAY = 86400
88@@ -27,10 +28,31 @@ def insert_notification(x, y):
89 def update_notification(x, y):
90 pass
91
92+def merge_dict(extend_me, extend_by):
93+ if isinstance(extend_by, dict):
94+ for k, v in extend_by.items():
95+ if isinstance(v, dict) and isinstance(extend_me.get(k), dict):
96+ merge_dict(extend_me[k], v)
97+ else:
98+ extend_me[k] = v
99+ return extend_me
100
101 def read_config(config_path):
102+
103 with open(config_path, 'r', encoding='utf8') as config_file:
104- return yaml.safe_load(config_file)
105+ config = yaml.safe_load(config_file)
106+
107+ # Check for extra config files from environment variable
108+ extra_config_paths = os.getenv('ONCALL_EXTRA_CONFIG')
109+ if extra_config_paths:
110+ for extra_path in extra_config_paths.split(','):
111+ extra_path = extra_path.strip()
112+ if os.path.isfile(extra_path):
113+ with open(extra_path, 'r') as f:
114+ extra_config = yaml.safe_load(f) or {}
115+ config = merge_dict(config, extra_config)
116+
117+ return config
118
119
120 def create_notification(context, team_id, role_ids, type_name, users_involved, cursor, **kwargs):