meerschaum 1.7.1__py3-none-any.whl → 1.7.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerschaum/_internal/arguments/_parser.py +1 -1
- meerschaum/actions/api.py +3 -2
- meerschaum/actions/stack.py +5 -9
- meerschaum/api/dash/components.py +2 -2
- meerschaum/api/routes/_misc.py +27 -1
- meerschaum/config/__init__.py +4 -4
- meerschaum/config/_edit.py +10 -20
- meerschaum/config/_read_config.py +11 -12
- meerschaum/config/_sync.py +44 -75
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +31 -21
- meerschaum/config/static/__init__.py +7 -2
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_login.py +2 -2
- meerschaum/connectors/api/_misc.py +6 -26
- meerschaum/connectors/api/_plugins.py +4 -5
- meerschaum/connectors/api/_users.py +14 -14
- meerschaum/connectors/parse.py +2 -2
- meerschaum/connectors/sql/_users.py +1 -1
- meerschaum/core/User/_User.py +7 -3
- meerschaum/utils/venv/_Venv.py +2 -0
- meerschaum/utils/venv/__init__.py +14 -9
- meerschaum-1.7.3.dist-info/METADATA +500 -0
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/RECORD +30 -30
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/WHEEL +1 -1
- meerschaum-1.7.1.dist-info/METADATA +0 -499
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/LICENSE +0 -0
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/NOTICE +0 -0
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/entry_points.txt +0 -0
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/top_level.txt +0 -0
- {meerschaum-1.7.1.dist-info → meerschaum-1.7.3.dist-info}/zip-safe +0 -0
@@ -270,7 +270,7 @@ groups['api'].add_argument(
|
|
270
270
|
help = "Start the API in secure mode, only allowing `admin` users to execute actions.",
|
271
271
|
)
|
272
272
|
groups['api'].add_argument(
|
273
|
-
'--no-auth', '--noauth', action='store_true',
|
273
|
+
'--no-auth', '--noauth', '--insecure', action='store_true',
|
274
274
|
help = 'When starting the API, do not require authentication. WARNING: This is dangerous!',
|
275
275
|
)
|
276
276
|
groups['api'].add_argument(
|
meerschaum/actions/api.py
CHANGED
@@ -157,7 +157,6 @@ def _api_start(
|
|
157
157
|
from meerschaum.connectors.parse import parse_instance_keys
|
158
158
|
from meerschaum.utils.pool import get_pool
|
159
159
|
import shutil
|
160
|
-
import os
|
161
160
|
from copy import deepcopy
|
162
161
|
|
163
162
|
if action is None:
|
@@ -276,6 +275,7 @@ def _api_start(
|
|
276
275
|
env_dict = {
|
277
276
|
MRSM_SERVER_ID: SERVER_ID,
|
278
277
|
MRSM_RUNTIME: 'api',
|
278
|
+
MRSM_CONFIG: json.loads(os.environ.get(MRSM_CONFIG, '{}')),
|
279
279
|
}
|
280
280
|
for env_var in get_env_vars():
|
281
281
|
if env_var in env_dict:
|
@@ -319,7 +319,8 @@ def _api_start(
|
|
319
319
|
]
|
320
320
|
for key, val in env_dict.items():
|
321
321
|
gunicorn_args += [
|
322
|
-
'--env', key +
|
322
|
+
'--env', key + "="
|
323
|
+
+ (json.dumps(val) if isinstance(val, (dict, list)) else val)
|
323
324
|
]
|
324
325
|
if workers is not None:
|
325
326
|
gunicorn_args += ['--workers', str(workers)]
|
meerschaum/actions/stack.py
CHANGED
@@ -43,6 +43,7 @@ def stack(
|
|
43
43
|
attempt_import, run_python_package, venv_contains_package,
|
44
44
|
pip_install,
|
45
45
|
)
|
46
|
+
from meerschaum.config._sync import sync_files
|
46
47
|
from meerschaum.config import get_config
|
47
48
|
from meerschaum.utils.debug import dprint
|
48
49
|
from meerschaum.utils.warnings import warn
|
@@ -73,9 +74,10 @@ def stack(
|
|
73
74
|
if not path.exists():
|
74
75
|
bootstrap = True
|
75
76
|
break
|
76
|
-
### if bootstrap flag was set, create files
|
77
77
|
if bootstrap:
|
78
78
|
write_stack(debug=debug)
|
79
|
+
else:
|
80
|
+
sync_files(['stack'])
|
79
81
|
|
80
82
|
compose_command = ['up']
|
81
83
|
### default: alias stack as docker-compose
|
@@ -125,14 +127,8 @@ def stack(
|
|
125
127
|
warn(f"Unable to install `pyyaml` into venv '{_compose_venv}'.")
|
126
128
|
|
127
129
|
cmd_list = [
|
128
|
-
_arg
|
129
|
-
|
130
|
-
+ compose_command
|
131
|
-
+ (
|
132
|
-
sysargs[2:] if len(sysargs) > 2 and not sub_args
|
133
|
-
else sub_args
|
134
|
-
)
|
135
|
-
)
|
130
|
+
_arg
|
131
|
+
for _arg in (settings_list + sysargs[1:])
|
136
132
|
if _arg != '--debug'
|
137
133
|
]
|
138
134
|
if debug:
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
10
10
|
from meerschaum.utils.venv import Venv
|
11
11
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html
|
12
12
|
from meerschaum.utils.typing import SuccessTuple, List
|
13
|
-
from meerschaum.config.static import
|
13
|
+
from meerschaum.config.static import STATIC_CONFIG
|
14
14
|
from meerschaum.utils.misc import remove_ansi
|
15
15
|
from meerschaum.actions import get_shell
|
16
16
|
from meerschaum.api import endpoints, CHECK_UPDATE
|
@@ -154,7 +154,7 @@ def alert_from_success_tuple(success: SuccessTuple) -> dbc.Alert:
|
|
154
154
|
id = 'success-alert',
|
155
155
|
dismissable = True,
|
156
156
|
fade = True,
|
157
|
-
is_open = not (success[1] in
|
157
|
+
is_open = not (success[1] in STATIC_CONFIG['system']['success']['ignore']),
|
158
158
|
color = 'success' if success[0] else 'danger',
|
159
159
|
)
|
160
160
|
)
|
meerschaum/api/routes/_misc.py
CHANGED
@@ -16,10 +16,14 @@ from meerschaum.api import (
|
|
16
16
|
private, no_auth, manager
|
17
17
|
)
|
18
18
|
import fastapi
|
19
|
-
from starlette.responses import FileResponse
|
19
|
+
from starlette.responses import FileResponse, JSONResponse
|
20
|
+
from meerschaum.connectors.poll import _wrap_retry_connect
|
20
21
|
|
21
22
|
@app.get(endpoints['favicon'], tags=['Misc'])
|
22
23
|
def get_favicon() -> Any:
|
24
|
+
"""
|
25
|
+
Return the favicon file.
|
26
|
+
"""
|
23
27
|
from meerschaum.config._paths import API_STATIC_PATH
|
24
28
|
return FileResponse(os.path.join(API_STATIC_PATH, 'ico', 'logo.ico'))
|
25
29
|
|
@@ -30,6 +34,9 @@ def get_chaining_status(
|
|
30
34
|
fastapi.Depends(manager) if private else None
|
31
35
|
),
|
32
36
|
) -> bool:
|
37
|
+
"""
|
38
|
+
Return whether this API instance may be chained.
|
39
|
+
"""
|
33
40
|
return check_allow_chaining()
|
34
41
|
|
35
42
|
|
@@ -39,6 +46,9 @@ def get_instance_info(
|
|
39
46
|
fastapi.Depends(manager) if private else None
|
40
47
|
),
|
41
48
|
) -> Dict[str, Union[str, int]]:
|
49
|
+
"""
|
50
|
+
Return information about this API instance.
|
51
|
+
"""
|
42
52
|
from meerschaum import __version__ as version
|
43
53
|
num_plugins = len(get_api_connector().get_plugins(debug=debug))
|
44
54
|
num_users = len(get_api_connector().get_users(debug=debug))
|
@@ -50,6 +60,22 @@ def get_instance_info(
|
|
50
60
|
'num_pipes': num_pipes,
|
51
61
|
}
|
52
62
|
|
63
|
+
|
64
|
+
@app.get(endpoints['healthcheck'], tags=['Misc'])
|
65
|
+
def get_healtheck() -> Dict[str, Any]:
|
66
|
+
"""
|
67
|
+
Return a success message to confirm this API is reachable.
|
68
|
+
"""
|
69
|
+
conn = get_api_connector()
|
70
|
+
success = _wrap_retry_connect(
|
71
|
+
conn.meta,
|
72
|
+
max_retries = 1,
|
73
|
+
)
|
74
|
+
message = "Success" if success else "Failed to connect to instance connector."
|
75
|
+
status_code = 200 if success else 503
|
76
|
+
return JSONResponse({"success": success, "message": message}, status_code=status_code)
|
77
|
+
|
78
|
+
|
53
79
|
if debug:
|
54
80
|
@app.get('/id', tags=['Misc'])
|
55
81
|
def get_ids(
|
meerschaum/config/__init__.py
CHANGED
@@ -45,12 +45,13 @@ def _config(
|
|
45
45
|
if config is None or reload:
|
46
46
|
with _locks['config']:
|
47
47
|
config = {}
|
48
|
+
|
48
49
|
if keys and keys[0] not in config:
|
49
50
|
from meerschaum.config._sync import sync_files as _sync_files
|
50
51
|
key_config = read_config(
|
51
|
-
keys=[keys[0]],
|
52
|
-
substitute=substitute,
|
53
|
-
write_missing=write_missing,
|
52
|
+
keys = [keys[0]],
|
53
|
+
substitute = substitute,
|
54
|
+
write_missing = write_missing,
|
54
55
|
)
|
55
56
|
if keys[0] in key_config:
|
56
57
|
config[keys[0]] = key_config[keys[0]]
|
@@ -232,7 +233,6 @@ def get_config(
|
|
232
233
|
)
|
233
234
|
)
|
234
235
|
if patch and keys[0] != symlinks_key:
|
235
|
-
# print("Updating configuration, please wait...")
|
236
236
|
if write_missing:
|
237
237
|
write_config(config, debug=debug)
|
238
238
|
|
meerschaum/config/_edit.py
CHANGED
@@ -71,7 +71,7 @@ def write_config(
|
|
71
71
|
if directory is None:
|
72
72
|
from meerschaum.config._paths import CONFIG_DIR_PATH
|
73
73
|
directory = CONFIG_DIR_PATH
|
74
|
-
from meerschaum.config.static import
|
74
|
+
from meerschaum.config.static import STATIC_CONFIG
|
75
75
|
from meerschaum.config._default import default_header_comment
|
76
76
|
from meerschaum.config._patch import apply_patch_to_config
|
77
77
|
from meerschaum.config._read_config import get_keyfile_path
|
@@ -84,14 +84,14 @@ def write_config(
|
|
84
84
|
cf = _config()
|
85
85
|
config_dict = cf
|
86
86
|
|
87
|
-
default_filetype =
|
87
|
+
default_filetype = STATIC_CONFIG['config']['default_filetype']
|
88
88
|
filetype_dumpers = {
|
89
89
|
'yml' : yaml.dump,
|
90
90
|
'yaml' : yaml.dump,
|
91
91
|
'json' : json.dump,
|
92
92
|
}
|
93
93
|
|
94
|
-
symlinks_key =
|
94
|
+
symlinks_key = STATIC_CONFIG['config']['symlinks_key']
|
95
95
|
symlinks = config_dict.pop(symlinks_key) if symlinks_key in config_dict else {}
|
96
96
|
config_dict = apply_patch_to_config(config_dict, symlinks)
|
97
97
|
|
@@ -148,27 +148,17 @@ def write_config(
|
|
148
148
|
return True
|
149
149
|
|
150
150
|
def general_write_yaml_config(
|
151
|
-
files
|
152
|
-
debug
|
151
|
+
files: Optional[Dict[pathlib.Path, Dict[str, Any]]] = None,
|
152
|
+
debug: bool = False
|
153
153
|
):
|
154
|
-
"""
|
155
|
-
|
156
|
-
files : dict
|
157
|
-
Dictionary of paths -> dict or tuple of format (dict, header).
|
158
|
-
If item is a tuple, the header will be written at the top of the file.
|
154
|
+
"""
|
155
|
+
Write configuration dictionaries to file paths with optional headers.
|
159
156
|
|
160
157
|
Parameters
|
161
158
|
----------
|
162
|
-
files
|
163
|
-
|
164
|
-
|
165
|
-
(Default value = None)
|
166
|
-
debug : bool :
|
167
|
-
(Default value = False)
|
168
|
-
|
169
|
-
Returns
|
170
|
-
-------
|
171
|
-
|
159
|
+
files: Optional[Dict[str, pathlib.Path]], default None
|
160
|
+
Dictionary of paths -> dict or tuple of format (dict, header).
|
161
|
+
If item is a tuple, the header will be written at the top of the file.
|
172
162
|
"""
|
173
163
|
|
174
164
|
from meerschaum.utils.debug import dprint
|
@@ -46,7 +46,7 @@ def read_config(
|
|
46
46
|
from meerschaum.utils.packages import attempt_import
|
47
47
|
from meerschaum.utils.yaml import yaml, _yaml
|
48
48
|
from meerschaum.config._paths import CONFIG_DIR_PATH
|
49
|
-
from meerschaum.config.static import
|
49
|
+
from meerschaum.config.static import STATIC_CONFIG
|
50
50
|
from meerschaum.config._patch import apply_patch_to_config
|
51
51
|
if directory is None:
|
52
52
|
directory = CONFIG_DIR_PATH
|
@@ -57,11 +57,11 @@ def read_config(
|
|
57
57
|
return default_config
|
58
58
|
|
59
59
|
### Each key corresponds to a YAML or JSON file.
|
60
|
-
symlinks_key =
|
60
|
+
symlinks_key = STATIC_CONFIG['config']['symlinks_key']
|
61
61
|
config = {}
|
62
62
|
config_to_write = {}
|
63
63
|
|
64
|
-
default_filetype =
|
64
|
+
default_filetype = STATIC_CONFIG['config']['default_filetype']
|
65
65
|
filetype_loaders = {
|
66
66
|
'yml' : yaml.load,
|
67
67
|
'yaml' : yaml.load,
|
@@ -187,7 +187,6 @@ def read_config(
|
|
187
187
|
print(f"Unable to parse {filename}!")
|
188
188
|
import traceback
|
189
189
|
traceback.print_exc()
|
190
|
-
# print(e)
|
191
190
|
input(f"Press [Enter] to open '{filename}' and fix formatting errors.")
|
192
191
|
from meerschaum.utils.misc import edit_file
|
193
192
|
edit_file(filepath)
|
@@ -363,8 +362,8 @@ def search_and_substitute_config(
|
|
363
362
|
s[_keys[-1]] = _pattern
|
364
363
|
|
365
364
|
from meerschaum.config._patch import apply_patch_to_config
|
366
|
-
from meerschaum.config.static import
|
367
|
-
symlinks_key =
|
365
|
+
from meerschaum.config.static import STATIC_CONFIG
|
366
|
+
symlinks_key = STATIC_CONFIG['config']['symlinks_key']
|
368
367
|
if symlinks_key not in parsed_config:
|
369
368
|
parsed_config[symlinks_key] = {}
|
370
369
|
parsed_config[symlinks_key] = apply_patch_to_config(parsed_config[symlinks_key], symlinks)
|
@@ -403,16 +402,16 @@ def get_keyfile_path(
|
|
403
402
|
os.path.join(
|
404
403
|
directory,
|
405
404
|
read_config(
|
406
|
-
keys=[key],
|
407
|
-
with_filenames=True,
|
408
|
-
write_missing=False,
|
409
|
-
substitute=False,
|
405
|
+
keys = [key],
|
406
|
+
with_filenames = True,
|
407
|
+
write_missing = False,
|
408
|
+
substitute = False,
|
410
409
|
)[1][0]
|
411
410
|
)
|
412
411
|
)
|
413
412
|
except IndexError as e:
|
414
413
|
if create_new:
|
415
|
-
from meerschaum.config.static import
|
416
|
-
default_filetype =
|
414
|
+
from meerschaum.config.static import STATIC_CONFIG
|
415
|
+
default_filetype = STATIC_CONFIG['config']['default_filetype']
|
417
416
|
return pathlib.Path(os.path.join(directory, key + '.' + default_filetype))
|
418
417
|
return None
|
meerschaum/config/_sync.py
CHANGED
@@ -10,7 +10,6 @@ from __future__ import annotations
|
|
10
10
|
from meerschaum.utils.typing import Optional, List, Tuple
|
11
11
|
|
12
12
|
def sync_yaml_configs(
|
13
|
-
config_path: pathlib.Path,
|
14
13
|
keys: List[str],
|
15
14
|
sub_path: pathlib.Path,
|
16
15
|
substitute: bool = True,
|
@@ -19,46 +18,24 @@ def sync_yaml_configs(
|
|
19
18
|
) -> None:
|
20
19
|
"""Synchronize sub-configuration with main configuration file.
|
21
20
|
|
22
|
-
NOTE: This function might need refactoring to work better with the new
|
23
|
-
`read_config` system.
|
24
|
-
|
25
21
|
Parameters
|
26
22
|
----------
|
27
|
-
|
28
|
-
Not sure if this is necessary.
|
29
|
-
keys :
|
23
|
+
keys: List[str]
|
30
24
|
The config keys to read via `get_config()`.
|
31
|
-
|
25
|
+
|
26
|
+
sub_path: pathlib.Path
|
32
27
|
The derivative file to write.
|
33
|
-
|
28
|
+
|
29
|
+
substitute: bool, default True
|
34
30
|
If `True`, parse `MRSM{}` syntax and substitute values.
|
35
31
|
See `get_config()` for more information.
|
36
|
-
|
37
|
-
permissions
|
32
|
+
|
33
|
+
permissions: Optional[int], default None
|
38
34
|
If not `None`, set permissions of the derivative file.
|
39
|
-
|
40
|
-
replace_tuples
|
35
|
+
|
36
|
+
replace_tuples: Optional[List[Tuple[str]]], default None
|
41
37
|
If provided, iterate through a list of tuples,
|
42
38
|
replacing the old string (index 0) with the new string (index 1).
|
43
|
-
Defaults to `None`.
|
44
|
-
config_path: pathlib.Path :
|
45
|
-
|
46
|
-
keys: List[str] :
|
47
|
-
|
48
|
-
sub_path: pathlib.Path :
|
49
|
-
|
50
|
-
substitute: bool :
|
51
|
-
(Default value = True)
|
52
|
-
permissions: Optional[int] :
|
53
|
-
(Default value = None)
|
54
|
-
replace_tuples: Optional[List[Tuple[str :
|
55
|
-
|
56
|
-
str]]] :
|
57
|
-
(Default value = None)
|
58
|
-
|
59
|
-
Returns
|
60
|
-
-------
|
61
|
-
|
62
39
|
"""
|
63
40
|
import os, sys
|
64
41
|
try:
|
@@ -68,22 +45,12 @@ def sync_yaml_configs(
|
|
68
45
|
from meerschaum.config._patch import apply_patch_to_config
|
69
46
|
import meerschaum.config
|
70
47
|
from meerschaum.utils.packages import reload_package
|
71
|
-
from meerschaum.config._read_config import search_and_substitute_config
|
72
|
-
if not os.path.isfile(config_path) or not os.path.isfile(sub_path):
|
73
|
-
return
|
74
|
-
|
75
|
-
def _read_config(path):
|
76
|
-
"""Read YAML file with header comment
|
77
|
-
|
78
|
-
Parameters
|
79
|
-
----------
|
80
|
-
path :
|
81
|
-
|
48
|
+
from meerschaum.config._read_config import search_and_substitute_config, get_keyfile_path
|
82
49
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
50
|
+
def _read_yaml_config(path):
|
51
|
+
"""Read YAML file with header comment."""
|
52
|
+
if not path.exists():
|
53
|
+
return "", {}
|
87
54
|
header_comment = ""
|
88
55
|
with open(path, 'r') as f:
|
89
56
|
if _yaml is not None:
|
@@ -98,58 +65,60 @@ def sync_yaml_configs(
|
|
98
65
|
header_comment += line
|
99
66
|
return header_comment, config
|
100
67
|
|
101
|
-
config_header, config = _read_config(config_path)
|
102
|
-
sub_header, sub_config = _read_config(sub_path)
|
103
|
-
|
104
68
|
from meerschaum.config import get_config
|
69
|
+
config_path = get_keyfile_path(keys[0], create_new=True)
|
105
70
|
c = get_config(*keys, substitute=substitute, sync_files=False)
|
71
|
+
|
72
|
+
config_header, config = _read_yaml_config(config_path)
|
73
|
+
sub_header, sub_config = _read_yaml_config(sub_path)
|
74
|
+
|
106
75
|
if substitute:
|
107
76
|
sub_config = search_and_substitute_config(sub_config)
|
108
77
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
### write changes
|
122
|
-
with open(new_path, 'w+') as f:
|
123
|
-
f.write(new_header)
|
124
|
-
f.write(new_config_text)
|
78
|
+
sub_config = c
|
79
|
+
new_config_text = yaml.dump(c, sort_keys=False)
|
80
|
+
if replace_tuples:
|
81
|
+
for replace_tuple in replace_tuples:
|
82
|
+
new_config_text = new_config_text.replace(replace_tuple[0], replace_tuple[1])
|
83
|
+
new_header = sub_header
|
84
|
+
new_path = sub_path
|
85
|
+
|
86
|
+
### write changes
|
87
|
+
with open(new_path, 'w+') as f:
|
88
|
+
f.write(new_header)
|
89
|
+
f.write(new_config_text)
|
125
90
|
if permissions is not None:
|
126
91
|
os.chmod(new_path, permissions)
|
127
92
|
|
128
93
|
def sync_files(keys: Optional[List[str]] = None):
|
129
94
|
if keys is None:
|
130
95
|
keys = []
|
96
|
+
|
131
97
|
def _stack():
|
132
98
|
import os
|
133
|
-
from meerschaum.config._paths import
|
134
|
-
|
135
|
-
|
136
|
-
|
99
|
+
from meerschaum.config._paths import (
|
100
|
+
CONFIG_DIR_PATH,
|
101
|
+
STACK_ENV_PATH,
|
102
|
+
STACK_COMPOSE_PATH,
|
103
|
+
STACK_COMPOSE_FILENAME,
|
104
|
+
STACK_ENV_FILENAME,
|
105
|
+
GRAFANA_DATASOURCE_PATH,
|
106
|
+
GRAFANA_DASHBOARD_PATH,
|
107
|
+
)
|
108
|
+
from meerschaum.config.static import STATIC_CONFIG
|
137
109
|
|
138
110
|
sync_yaml_configs(
|
139
|
-
CONFIG_DIR_PATH / 'stack.yaml',
|
140
111
|
['stack', STACK_COMPOSE_FILENAME],
|
141
112
|
STACK_COMPOSE_PATH,
|
142
113
|
substitute = True,
|
143
|
-
replace_tuples = [('$', '$$')],
|
114
|
+
replace_tuples = [('$', '$$'), ('<DOLLAR>', '$')],
|
144
115
|
)
|
145
116
|
sync_yaml_configs(
|
146
|
-
CONFIG_DIR_PATH / 'stack.yaml',
|
147
117
|
['stack', 'grafana', 'datasource'],
|
148
118
|
GRAFANA_DATASOURCE_PATH,
|
149
119
|
substitute = True,
|
150
120
|
)
|
151
121
|
sync_yaml_configs(
|
152
|
-
CONFIG_DIR_PATH / 'stack.yaml',
|
153
122
|
['stack', 'grafana', 'dashboard'],
|
154
123
|
GRAFANA_DASHBOARD_PATH,
|
155
124
|
substitute = True,
|
@@ -157,7 +126,7 @@ def sync_files(keys: Optional[List[str]] = None):
|
|
157
126
|
|
158
127
|
|
159
128
|
key_functions = {
|
160
|
-
'stack'
|
129
|
+
'stack': _stack,
|
161
130
|
}
|
162
131
|
if keys is None:
|
163
132
|
keys = list(key_functions.keys())
|
meerschaum/config/_version.py
CHANGED
@@ -29,11 +29,11 @@ db_base = "MRSM{meerschaum:connectors:sql:main:database}"
|
|
29
29
|
db_hostname = "db"
|
30
30
|
db_host = 'MRSM{stack:' + str(STACK_COMPOSE_FILENAME) + ':services:db:hostname}'
|
31
31
|
api_port = "MRSM{meerschaum:connectors:api:main:port}"
|
32
|
-
api_host = "
|
32
|
+
api_host = "api"
|
33
33
|
|
34
34
|
env_dict = {
|
35
35
|
'COMPOSE_PROJECT_NAME' : 'mrsm',
|
36
|
-
'TIMESCALEDB_VERSION' : 'latest-
|
36
|
+
'TIMESCALEDB_VERSION' : 'latest-pg15-oss',
|
37
37
|
'POSTGRES_USER' : f'{db_user}',
|
38
38
|
'POSTGRES_PASSWORD' : f'{db_pass}',
|
39
39
|
'POSTGRES_DB' : f'{db_base}',
|
@@ -54,13 +54,25 @@ env_dict['MEERSCHAUM_API_CONFIG'] = json.dumps(
|
|
54
54
|
'"MRSM{!meerschaum}"', 'MRSM{!meerschaum}',
|
55
55
|
)
|
56
56
|
|
57
|
+
volumes = {
|
58
|
+
'api_root': '/meerschaum',
|
59
|
+
'meerschaum_db_data': '/var/lib/postgresql/data',
|
60
|
+
'grafana_storage': '/var/lib/grafana',
|
61
|
+
}
|
62
|
+
networks = {
|
63
|
+
'frontend': None,
|
64
|
+
'backend': None,
|
65
|
+
}
|
57
66
|
env_dict['MEERSCHAUM_API_PATCH'] = json.dumps(
|
58
67
|
{
|
59
|
-
'meerschaum'
|
60
|
-
'connectors'
|
61
|
-
'sql'
|
62
|
-
'main'
|
63
|
-
'host'
|
68
|
+
'meerschaum': {
|
69
|
+
'connectors': {
|
70
|
+
'sql': {
|
71
|
+
'main': {
|
72
|
+
'host': db_host,
|
73
|
+
},
|
74
|
+
'local': {
|
75
|
+
'database': volumes['api_root'] + '/sqlite/mrsm_local.db'
|
64
76
|
},
|
65
77
|
},
|
66
78
|
},
|
@@ -82,15 +94,6 @@ compose_header = """
|
|
82
94
|
##############################################################
|
83
95
|
"""
|
84
96
|
|
85
|
-
volumes = {
|
86
|
-
'api_root' : '/meerschaum',
|
87
|
-
'meerschaum_db_data' : '/var/lib/postgresql/data',
|
88
|
-
'grafana_storage' : '/var/lib/grafana',
|
89
|
-
}
|
90
|
-
networks = {
|
91
|
-
'frontend' : None,
|
92
|
-
'backend' : None,
|
93
|
-
}
|
94
97
|
|
95
98
|
default_docker_compose_config = {
|
96
99
|
'version': '3.9',
|
@@ -98,16 +101,15 @@ default_docker_compose_config = {
|
|
98
101
|
'db': {
|
99
102
|
'environment': {
|
100
103
|
'TIMESCALEDB_TELEMETRY': 'off',
|
101
|
-
'POSTGRES_USER': '
|
102
|
-
'POSTGRES_DB': '
|
103
|
-
'POSTGRES_PASSWORD': '
|
104
|
+
'POSTGRES_USER': '<DOLLAR>POSTGRES_USER',
|
105
|
+
'POSTGRES_DB': '<DOLLAR>POSTGRES_DB',
|
106
|
+
'POSTGRES_PASSWORD': '<DOLLAR>POSTGRES_PASSWORD',
|
104
107
|
'ALLOW_IP_RANGE': env_dict['ALLOW_IP_RANGE'],
|
105
108
|
},
|
106
109
|
'command': 'postgres -c max_connections=1000 -c shared_buffers=1024MB',
|
107
110
|
'healthcheck': {
|
108
111
|
'test': [
|
109
|
-
'CMD-SHELL', 'pg_isready',
|
110
|
-
'-U', '$POSTGRES_USER', '-d', '$POSTGRES_DB',
|
112
|
+
'CMD-SHELL', 'pg_isready -d <DOLLAR>POSTGRES_DB -U <DOLLAR>POSTGRES_USER',
|
111
113
|
],
|
112
114
|
'interval': '5s',
|
113
115
|
'timeout': '3s',
|
@@ -136,6 +138,14 @@ default_docker_compose_config = {
|
|
136
138
|
'backend',
|
137
139
|
],
|
138
140
|
'command': f'start api --production --port {api_port}',
|
141
|
+
'healthcheck': {
|
142
|
+
'test': [
|
143
|
+
'CMD', 'curl', '--fail', f'http://localhost:{api_port}/healthcheck',
|
144
|
+
],
|
145
|
+
'interval': '5s',
|
146
|
+
'timeout': '3s',
|
147
|
+
'retries': 3
|
148
|
+
},
|
139
149
|
'environment': {
|
140
150
|
'MRSM_CONFIG': env_dict['MEERSCHAUM_API_CONFIG'],
|
141
151
|
'MRSM_PATCH': env_dict['MEERSCHAUM_API_PATCH'],
|
@@ -8,12 +8,13 @@ Insert non-user-editable configuration files here.
|
|
8
8
|
|
9
9
|
import os
|
10
10
|
import uuid
|
11
|
+
from typing import Dict, Any
|
11
12
|
from meerschaum.utils.misc import generate_password
|
12
13
|
|
13
14
|
__all__ = ['STATIC_CONFIG']
|
14
15
|
|
15
|
-
SERVER_ID = os.environ.get('MRSM_SERVER_ID', generate_password(6))
|
16
|
-
STATIC_CONFIG = {
|
16
|
+
SERVER_ID: str = os.environ.get('MRSM_SERVER_ID', generate_password(6))
|
17
|
+
STATIC_CONFIG: Dict[str, Any] = {
|
17
18
|
'api': {
|
18
19
|
'endpoints': {
|
19
20
|
'index': '/',
|
@@ -32,6 +33,7 @@ STATIC_CONFIG = {
|
|
32
33
|
'webterm': '/webterm',
|
33
34
|
'webterm_websocket': '/websocket',
|
34
35
|
'info': '/info',
|
36
|
+
'healthcheck': '/healthcheck',
|
35
37
|
},
|
36
38
|
'oauth': {
|
37
39
|
'token_expires_minutes': 720,
|
@@ -83,6 +85,9 @@ STATIC_CONFIG = {
|
|
83
85
|
'connectors': {
|
84
86
|
'default_label': 'main',
|
85
87
|
},
|
88
|
+
'stack': {
|
89
|
+
'dollar_standin': '<DOLLAR>', ### Temporary replacement for docker-compose.yaml.
|
90
|
+
},
|
86
91
|
'users': {
|
87
92
|
'password_hash': {
|
88
93
|
'schemes': [
|
@@ -50,7 +50,7 @@ def do_action(
|
|
50
50
|
"""
|
51
51
|
import sys, json
|
52
52
|
from meerschaum.utils.debug import dprint
|
53
|
-
from meerschaum.config.static import
|
53
|
+
from meerschaum.config.static import STATIC_CONFIG
|
54
54
|
from meerschaum.utils.misc import json_serialize_datetime
|
55
55
|
if action is None:
|
56
56
|
action = []
|
@@ -67,7 +67,7 @@ def do_action(
|
|
67
67
|
|
68
68
|
root_action = json_dict['action'][0]
|
69
69
|
del json_dict['action'][0]
|
70
|
-
r_url = f"{
|
70
|
+
r_url = f"{STATIC_CONFIG['api']['endpoints']['actions']}/{root_action}"
|
71
71
|
|
72
72
|
if debug:
|
73
73
|
from meerschaum.utils.formatting import pprint
|
@@ -18,7 +18,7 @@ def login(
|
|
18
18
|
"""Log in and set the session token."""
|
19
19
|
from meerschaum.utils.warnings import warn as _warn, info, error
|
20
20
|
from meerschaum.core import User
|
21
|
-
from meerschaum.config.static import
|
21
|
+
from meerschaum.config.static import STATIC_CONFIG
|
22
22
|
import json, datetime
|
23
23
|
try:
|
24
24
|
login_data = {
|
@@ -28,7 +28,7 @@ def login(
|
|
28
28
|
except AttributeError:
|
29
29
|
return False, f"Please login with the command `login {self}`."
|
30
30
|
response = self.post(
|
31
|
-
|
31
|
+
STATIC_CONFIG['api']['endpoints']['login'],
|
32
32
|
data = login_data,
|
33
33
|
use_token = False,
|
34
34
|
debug = debug
|