Skip to content

Commit f39c755

Browse files
authored
Add support for overriding st2.conf settings via env vars (#6277)
2 parents e51fe93 + 4e8794c commit f39c755

21 files changed

Lines changed: 111 additions & 15 deletions

File tree

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ Added
8686
following to set system user to the current user: `export ST2TESTS_SYSTEM_USER=$(id -un)` #6242
8787
Contributed by @cognifloyd
8888

89+
* Added experimental support for setting conf vars via environment variables. All settings in `st2.conf` can be
90+
overriden via enviornment vars in the format: `ST2_<conf section>__<option name>` (env vars are upper cased)
91+
For example, the `[database].password` setting in `st2.conf` could be overriden using `ST2_DATABASE__PASSWORD`.
92+
This new feature is based on oslo_config's environment support, but patches it to use the `ST2_` prefix.
93+
If you experience any issues when using this experimental feature, please file an issue. #6277
94+
Contributed by @cognifloyd
95+
8996
3.8.1 - December 13, 2023
9097
-------------------------
9198
Fixed

st2actions/st2actions/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929

3030
def parse_args(args=None):
31+
common_config.use_st2_env_vars(CONF)
3132
CONF(
3233
args=args,
3334
version=VERSION_STRING,

st2actions/st2actions/notifier/config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@
2121
from st2common.constants.system import VERSION_STRING
2222
from st2common.constants.system import DEFAULT_CONFIG_FILE_PATH
2323

24-
CONF = cfg.CONF
25-
2624

2725
def parse_args(args=None):
26+
common_config.use_st2_env_vars(cfg.CONF)
2827
cfg.CONF(
2928
args=args,
3029
version=VERSION_STRING,

st2actions/st2actions/scheduler/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828

2929
def parse_args(args=None):
30+
common_config.use_st2_env_vars(cfg.CONF)
3031
cfg.CONF(
3132
args=args,
3233
version=sys_constants.VERSION_STRING,

st2actions/st2actions/workflows/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424

2525
def parse_args(args=None):
26+
common_config.use_st2_env_vars(cfg.CONF)
2627
cfg.CONF(
2728
args=args,
2829
version=sys_constants.VERSION_STRING,

st2api/st2api/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333

3434
def parse_args(args=None):
35+
common_config.use_st2_env_vars(cfg.CONF)
3536
cfg.CONF(
3637
args=args,
3738
version=VERSION_STRING,

st2api/tests/integration/test_gunicorn_configs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import eventlet
2323
from eventlet.green import subprocess
2424

25+
import st2tests.config
2526
from st2common.models.utils import profiling
2627
from st2common.util.shell import kill_process
2728
from st2tests.base import IntegrationTestCase
@@ -41,6 +42,9 @@ def test_st2api_wsgi_entry_point(self):
4142
)
4243
env = os.environ.copy()
4344
env["ST2_CONFIG_PATH"] = ST2_CONFIG_PATH
45+
env.update(st2tests.config.db_opts_as_env_vars())
46+
env.update(st2tests.config.mq_opts_as_env_vars())
47+
env.update(st2tests.config.coord_opts_as_env_vars())
4448
process = subprocess.Popen(cmd, env=env, shell=True, preexec_fn=os.setsid)
4549
try:
4650
self.add_process(process=process)
@@ -60,6 +64,9 @@ def test_st2auth(self):
6064
)
6165
env = os.environ.copy()
6266
env["ST2_CONFIG_PATH"] = ST2_CONFIG_PATH
67+
env.update(st2tests.config.db_opts_as_env_vars())
68+
env.update(st2tests.config.mq_opts_as_env_vars())
69+
env.update(st2tests.config.coord_opts_as_env_vars())
6370
process = subprocess.Popen(cmd, env=env, shell=True, preexec_fn=os.setsid)
6471
try:
6572
self.add_process(process=process)

st2auth/st2auth/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929

3030
def parse_args(args=None):
31+
st2cfg.use_st2_env_vars(cfg.CONF)
3132
cfg.CONF(
3233
args=args,
3334
version=VERSION_STRING,

st2common/st2common/config.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import sys
2020

2121
from oslo_config import cfg
22+
from oslo_config.sources._environment import EnvironmentConfigurationSource
2223

2324
from st2common.constants.system import VERSION_STRING
2425
from st2common.constants.system import DEFAULT_CONFIG_FILE_PATH
@@ -900,7 +901,20 @@ def register_opts(ignore_errors=False):
900901
)
901902

902903

904+
class St2EnvironmentConfigurationSource(EnvironmentConfigurationSource):
905+
@staticmethod
906+
def get_name(group_name, option_name):
907+
group_name = group_name or "DEFAULT"
908+
return "ST2_{}__{}".format(group_name.upper(), option_name.upper())
909+
910+
911+
def use_st2_env_vars(conf: cfg.ConfigOpts) -> None:
912+
# Override oslo_config's 'OS_' env var prefix with 'ST2_'.
913+
conf._env_driver = St2EnvironmentConfigurationSource()
914+
915+
903916
def parse_args(args=None, ignore_errors=False):
917+
use_st2_env_vars(cfg.CONF)
904918
register_opts(ignore_errors=ignore_errors)
905919
cfg.CONF(
906920
args=args,

st2common/tests/integration/test_register_content_script.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import sys
2020
import glob
2121

22+
import st2tests.config
2223
from st2tests.base import IntegrationTestCase
2324
from st2common.util.shell import run_command
2425
from st2tests import config as test_config
@@ -56,7 +57,7 @@ def test_register_from_pack_success(self):
5657
"--register-runner-dir=%s" % (runner_dirs),
5758
]
5859
cmd = BASE_REGISTER_ACTIONS_CMD_ARGS + opts
59-
exit_code, _, stderr = run_command(cmd=cmd)
60+
exit_code, _, stderr = self._run_command(cmd=cmd)
6061
self.assertIn("Registered 3 actions.", stderr)
6162
self.assertEqual(exit_code, 0)
6263

@@ -71,7 +72,7 @@ def test_register_from_pack_fail_on_failure_pack_dir_doesnt_exist(self):
7172
"--register-no-fail-on-failure",
7273
]
7374
cmd = BASE_REGISTER_ACTIONS_CMD_ARGS + opts
74-
exit_code, _, _ = run_command(cmd=cmd)
75+
exit_code, _, _ = self._run_command(cmd=cmd)
7576
self.assertEqual(exit_code, 0)
7677

7778
# Fail on failure, should fail
@@ -81,7 +82,7 @@ def test_register_from_pack_fail_on_failure_pack_dir_doesnt_exist(self):
8182
"--register-fail-on-failure",
8283
]
8384
cmd = BASE_REGISTER_ACTIONS_CMD_ARGS + opts
84-
exit_code, _, stderr = run_command(cmd=cmd)
85+
exit_code, _, stderr = self._run_command(cmd=cmd)
8586
self.assertIn('Directory "doesntexistblah" doesn\'t exist', stderr)
8687
self.assertEqual(exit_code, 1)
8788

@@ -97,7 +98,7 @@ def test_register_from_pack_action_metadata_fails_validation(self):
9798
]
9899

99100
cmd = BASE_REGISTER_ACTIONS_CMD_ARGS + opts
100-
exit_code, _, stderr = run_command(cmd=cmd)
101+
exit_code, _, stderr = self._run_command(cmd=cmd)
101102
self.assertIn("Registered 0 actions.", stderr)
102103
self.assertEqual(exit_code, 0)
103104

@@ -109,7 +110,7 @@ def test_register_from_pack_action_metadata_fails_validation(self):
109110
"--register-runner-dir=%s" % (runner_dirs),
110111
]
111112
cmd = BASE_REGISTER_ACTIONS_CMD_ARGS + opts
112-
exit_code, _, stderr = run_command(cmd=cmd)
113+
exit_code, _, stderr = self._run_command(cmd=cmd)
113114
self.assertIn("object has no attribute 'get'", stderr)
114115
self.assertEqual(exit_code, 1)
115116

@@ -127,7 +128,7 @@ def test_register_from_packs_doesnt_throw_on_missing_pack_resource_folder(self):
127128
"-v",
128129
"--register-sensors",
129130
]
130-
exit_code, _, stderr = run_command(cmd=cmd)
131+
exit_code, _, stderr = self._run_command(cmd=cmd)
131132
self.assertIn("Registered 0 sensors.", stderr, "Actual stderr: %s" % (stderr))
132133
self.assertEqual(exit_code, 0)
133134

@@ -139,7 +140,7 @@ def test_register_from_packs_doesnt_throw_on_missing_pack_resource_folder(self):
139140
"--register-all",
140141
"--register-no-fail-on-failure",
141142
]
142-
exit_code, _, stderr = run_command(cmd=cmd)
143+
exit_code, _, stderr = self._run_command(cmd=cmd)
143144
self.assertIn("Registered 0 actions.", stderr)
144145
self.assertIn("Registered 0 sensors.", stderr)
145146
self.assertIn("Registered 0 rules.", stderr)
@@ -155,7 +156,7 @@ def test_register_all_and_register_setup_virtualenvs(self):
155156
"--register-setup-virtualenvs",
156157
"--register-no-fail-on-failure",
157158
]
158-
exit_code, stdout, stderr = run_command(cmd=cmd)
159+
exit_code, stdout, stderr = self._run_command(cmd=cmd)
159160
self.assertIn("Registering actions", stderr, "Actual stderr: %s" % (stderr))
160161
self.assertIn("Registering rules", stderr)
161162
self.assertIn("Setup virtualenv for %s pack(s)" % ("1"), stderr)
@@ -170,7 +171,7 @@ def test_register_setup_virtualenvs(self):
170171
"--register-setup-virtualenvs",
171172
"--register-no-fail-on-failure",
172173
]
173-
exit_code, stdout, stderr = run_command(cmd=cmd)
174+
exit_code, stdout, stderr = self._run_command(cmd=cmd)
174175

175176
self.assertIn('Setting up virtualenv for pack "dummy_pack_1"', stderr)
176177
self.assertIn("Setup virtualenv for 1 pack(s)", stderr)
@@ -186,7 +187,7 @@ def test_register_recreate_virtualenvs(self):
186187
"--register-setup-virtualenvs",
187188
"--register-no-fail-on-failure",
188189
]
189-
exit_code, stdout, stderr = run_command(cmd=cmd)
190+
exit_code, stdout, stderr = self._run_command(cmd=cmd)
190191

191192
self.assertIn('Setting up virtualenv for pack "dummy_pack_1"', stderr)
192193
self.assertIn("Setup virtualenv for 1 pack(s)", stderr)
@@ -200,9 +201,17 @@ def test_register_recreate_virtualenvs(self):
200201
"--register-recreate-virtualenvs",
201202
"--register-no-fail-on-failure",
202203
]
203-
exit_code, stdout, stderr = run_command(cmd=cmd)
204+
exit_code, stdout, stderr = self._run_command(cmd=cmd)
204205

205206
self.assertIn('Setting up virtualenv for pack "dummy_pack_1"', stderr)
206207
self.assertIn("Virtualenv successfully removed.", stderr)
207208
self.assertIn("Setup virtualenv for 1 pack(s)", stderr)
208209
self.assertEqual(exit_code, 0)
210+
211+
@staticmethod
212+
def _run_command(cmd):
213+
env = os.environ.copy()
214+
env.update(st2tests.config.db_opts_as_env_vars())
215+
env.update(st2tests.config.mq_opts_as_env_vars())
216+
env.update(st2tests.config.coord_opts_as_env_vars())
217+
return run_command(cmd=cmd, env=env)

0 commit comments

Comments
 (0)