sovereign 0.19.3__py3-none-any.whl → 1.0.0a4__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.
Potentially problematic release.
This version of sovereign might be problematic. Click here for more details.
- sovereign/__init__.py +13 -81
- sovereign/app.py +62 -48
- sovereign/cache/__init__.py +245 -0
- sovereign/cache/backends/__init__.py +110 -0
- sovereign/cache/backends/s3.py +161 -0
- sovereign/cache/filesystem.py +74 -0
- sovereign/cache/types.py +17 -0
- sovereign/configuration.py +607 -0
- sovereign/constants.py +1 -0
- sovereign/context.py +270 -104
- sovereign/dynamic_config/__init__.py +112 -0
- sovereign/dynamic_config/deser.py +78 -0
- sovereign/dynamic_config/loaders.py +120 -0
- sovereign/error_info.py +2 -3
- sovereign/events.py +49 -0
- sovereign/logging/access_logger.py +85 -0
- sovereign/logging/application_logger.py +54 -0
- sovereign/logging/base_logger.py +41 -0
- sovereign/logging/bootstrapper.py +36 -0
- sovereign/logging/types.py +10 -0
- sovereign/middlewares.py +8 -7
- sovereign/modifiers/lib.py +2 -1
- sovereign/rendering.py +124 -0
- sovereign/rendering_common.py +91 -0
- sovereign/response_class.py +18 -0
- sovereign/server.py +112 -35
- sovereign/statistics.py +19 -21
- sovereign/templates/base.html +59 -46
- sovereign/templates/resources.html +203 -102
- sovereign/testing/loaders.py +9 -0
- sovereign/{modifiers/test.py → testing/modifiers.py} +0 -2
- sovereign/tracing.py +103 -0
- sovereign/types.py +304 -0
- sovereign/utils/auth.py +27 -13
- sovereign/utils/crypto/__init__.py +0 -0
- sovereign/utils/crypto/crypto.py +135 -0
- sovereign/utils/crypto/suites/__init__.py +21 -0
- sovereign/utils/crypto/suites/aes_gcm_cipher.py +42 -0
- sovereign/utils/crypto/suites/base_cipher.py +21 -0
- sovereign/utils/crypto/suites/disabled_cipher.py +25 -0
- sovereign/utils/crypto/suites/fernet_cipher.py +29 -0
- sovereign/utils/dictupdate.py +3 -2
- sovereign/utils/eds.py +40 -22
- sovereign/utils/entry_point_loader.py +2 -2
- sovereign/utils/mock.py +56 -17
- sovereign/utils/resources.py +17 -0
- sovereign/utils/templates.py +4 -2
- sovereign/utils/timer.py +5 -3
- sovereign/utils/version_info.py +8 -0
- sovereign/utils/weighted_clusters.py +2 -1
- sovereign/v2/__init__.py +0 -0
- sovereign/v2/data/data_store.py +621 -0
- sovereign/v2/data/render_discovery_response.py +24 -0
- sovereign/v2/data/repositories.py +90 -0
- sovereign/v2/data/utils.py +33 -0
- sovereign/v2/data/worker_queue.py +273 -0
- sovereign/v2/jobs/refresh_context.py +117 -0
- sovereign/v2/jobs/render_discovery_job.py +145 -0
- sovereign/v2/logging.py +81 -0
- sovereign/v2/types.py +41 -0
- sovereign/v2/web.py +101 -0
- sovereign/v2/worker.py +199 -0
- sovereign/views/__init__.py +7 -0
- sovereign/views/api.py +82 -0
- sovereign/views/crypto.py +46 -15
- sovereign/views/discovery.py +55 -119
- sovereign/views/healthchecks.py +107 -20
- sovereign/views/interface.py +171 -111
- sovereign/worker.py +193 -0
- {sovereign-0.19.3.dist-info → sovereign-1.0.0a4.dist-info}/METADATA +80 -76
- sovereign-1.0.0a4.dist-info/RECORD +85 -0
- {sovereign-0.19.3.dist-info → sovereign-1.0.0a4.dist-info}/WHEEL +1 -1
- sovereign-1.0.0a4.dist-info/entry_points.txt +46 -0
- sovereign_files/__init__.py +0 -0
- sovereign_files/static/darkmode.js +51 -0
- sovereign_files/static/node_expression.js +42 -0
- sovereign_files/static/panel.js +76 -0
- sovereign_files/static/resources.css +246 -0
- sovereign_files/static/resources.js +642 -0
- sovereign_files/static/sass/style.scss +33 -0
- sovereign_files/static/style.css +16143 -0
- sovereign_files/static/style.css.map +1 -0
- sovereign/config_loader.py +0 -225
- sovereign/discovery.py +0 -175
- sovereign/logs.py +0 -131
- sovereign/schemas.py +0 -780
- sovereign/sources/__init__.py +0 -3
- sovereign/sources/file.py +0 -21
- sovereign/sources/inline.py +0 -38
- sovereign/sources/lib.py +0 -40
- sovereign/sources/poller.py +0 -294
- sovereign/static/sass/style.scss +0 -27
- sovereign/static/style.css +0 -13553
- sovereign/templates/ul_filter.html +0 -22
- sovereign/utils/crypto.py +0 -103
- sovereign/views/admin.py +0 -120
- sovereign-0.19.3.dist-info/LICENSE.txt +0 -13
- sovereign-0.19.3.dist-info/RECORD +0 -47
- sovereign-0.19.3.dist-info/entry_points.txt +0 -10
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from importlib.util import find_spec
|
|
2
|
+
from typing import Type
|
|
3
|
+
|
|
4
|
+
from fastapi.responses import JSONResponse
|
|
5
|
+
|
|
6
|
+
json_response_class: Type[JSONResponse] = JSONResponse
|
|
7
|
+
if find_spec("orjson"):
|
|
8
|
+
from fastapi.responses import ORJSONResponse
|
|
9
|
+
|
|
10
|
+
json_response_class = ORJSONResponse
|
|
11
|
+
|
|
12
|
+
elif find_spec("ujson"):
|
|
13
|
+
from fastapi.responses import UJSONResponse
|
|
14
|
+
|
|
15
|
+
json_response_class = UJSONResponse
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__all__ = ["json_response_class"]
|
sovereign/server.py
CHANGED
|
@@ -1,49 +1,126 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
from sovereign.app import app
|
|
6
|
-
from sovereign.utils.entry_point_loader import EntryPointLoader
|
|
1
|
+
import configparser
|
|
2
|
+
import tempfile
|
|
3
|
+
import warnings
|
|
4
|
+
from pathlib import Path
|
|
7
5
|
|
|
6
|
+
import uvicorn
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
from sovereign import application_logger as log
|
|
9
|
+
from sovereign.configuration import SovereignAsgiConfig, SupervisordConfig, config
|
|
10
|
+
from sovereign.v2.worker import Worker
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
self.options = options or {}
|
|
17
|
-
self.application = application
|
|
18
|
-
super().__init__()
|
|
12
|
+
# noinspection PyArgumentList
|
|
13
|
+
asgi_config = SovereignAsgiConfig()
|
|
14
|
+
# noinspection PyArgumentList
|
|
15
|
+
supervisord_config = SupervisordConfig()
|
|
19
16
|
|
|
20
|
-
def load_config(self) -> None:
|
|
21
|
-
for key, value in self.options.items():
|
|
22
|
-
self.cfg.set(key.lower(), value)
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
def web(supervisor_enabled=True) -> None:
|
|
19
|
+
from sovereign.app import app
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
hooks: list[Callable[[Any, Any], None]] = [
|
|
29
|
-
ep.load() for ep in self.loader.groups[name]
|
|
30
|
-
]
|
|
21
|
+
log.debug("Starting web server")
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
if not supervisor_enabled:
|
|
24
|
+
uvicorn.run(
|
|
25
|
+
app,
|
|
26
|
+
log_level=asgi_config.log_level,
|
|
27
|
+
access_log=False,
|
|
28
|
+
timeout_keep_alive=asgi_config.keepalive,
|
|
29
|
+
host=asgi_config.host,
|
|
30
|
+
port=asgi_config.port,
|
|
31
|
+
workers=1, # per managed supervisor proc
|
|
32
|
+
)
|
|
33
|
+
else:
|
|
34
|
+
uvicorn.run(
|
|
35
|
+
app,
|
|
36
|
+
fd=0,
|
|
37
|
+
log_level=asgi_config.log_level,
|
|
38
|
+
access_log=False,
|
|
39
|
+
timeout_keep_alive=asgi_config.keepalive,
|
|
40
|
+
host=asgi_config.host,
|
|
41
|
+
port=asgi_config.port,
|
|
42
|
+
workers=1, # per managed supervisor proc
|
|
43
|
+
)
|
|
35
44
|
|
|
36
|
-
self.cfg.set(name, master_hook)
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
def worker():
|
|
47
|
+
if config.worker_v2_enabled:
|
|
48
|
+
log.debug("Starting worker v2")
|
|
49
|
+
Worker().start()
|
|
50
|
+
else:
|
|
51
|
+
from sovereign.worker import worker as worker_app
|
|
40
52
|
|
|
53
|
+
log.debug("Starting worker")
|
|
54
|
+
uvicorn.run(
|
|
55
|
+
worker_app,
|
|
56
|
+
log_level=asgi_config.log_level,
|
|
57
|
+
access_log=False,
|
|
58
|
+
timeout_keep_alive=asgi_config.keepalive,
|
|
59
|
+
host="127.0.0.1",
|
|
60
|
+
port=9080,
|
|
61
|
+
workers=1, # per managed supervisor proc
|
|
62
|
+
)
|
|
41
63
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
|
|
65
|
+
def write_supervisor_conf() -> Path:
|
|
66
|
+
proc_env = {
|
|
67
|
+
"LANG": "en_US.UTF-8",
|
|
68
|
+
"LC_ALL": "en_US.UTF-8",
|
|
69
|
+
}
|
|
70
|
+
base = {
|
|
71
|
+
"autostart": "true",
|
|
72
|
+
"autorestart": "true",
|
|
73
|
+
"stdout_logfile": "/dev/stdout",
|
|
74
|
+
"stdout_logfile_maxbytes": "0",
|
|
75
|
+
"stderr_logfile": "/dev/stderr",
|
|
76
|
+
"stderr_logfile_maxbytes": "0",
|
|
77
|
+
"stopsignal": "QUIT",
|
|
78
|
+
"environment": ",".join(["=".join((k, v)) for k, v in proc_env.items()]),
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
conf = configparser.RawConfigParser()
|
|
82
|
+
conf["supervisord"] = supervisord = {
|
|
83
|
+
"nodaemon": str(supervisord_config.nodaemon).lower(),
|
|
84
|
+
"loglevel": supervisord_config.loglevel,
|
|
85
|
+
"pidfile": supervisord_config.pidfile,
|
|
86
|
+
"logfile": supervisord_config.logfile,
|
|
87
|
+
"directory": supervisord_config.directory,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
conf["fcgi-program:web"] = web = {
|
|
91
|
+
**base,
|
|
92
|
+
"socket": f"tcp://{asgi_config.host}:{asgi_config.port}",
|
|
93
|
+
"numprocs": str(asgi_config.workers),
|
|
94
|
+
"process_name": "%(program_name)s-%(process_num)02d",
|
|
95
|
+
"command": "sovereign-web", # default niceness, higher CPU priority
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
conf["program:data"] = worker = {
|
|
99
|
+
**base,
|
|
100
|
+
"numprocs": "1",
|
|
101
|
+
"command": "nice -n 2 sovereign-worker", # run worker with reduced CPU priority (higher niceness value)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if user := asgi_config.user:
|
|
105
|
+
supervisord["user"] = user
|
|
106
|
+
web["user"] = user
|
|
107
|
+
worker["user"] = user
|
|
108
|
+
|
|
109
|
+
log.debug("Writing supervisor config")
|
|
110
|
+
with tempfile.NamedTemporaryFile("w", delete=False) as f:
|
|
111
|
+
conf.write(f)
|
|
112
|
+
log.debug("Supervisor config written out")
|
|
113
|
+
return Path(f.name)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def main():
|
|
117
|
+
path = write_supervisor_conf()
|
|
118
|
+
with warnings.catch_warnings():
|
|
119
|
+
warnings.simplefilter("ignore")
|
|
120
|
+
from supervisor import supervisord
|
|
121
|
+
|
|
122
|
+
log.debug("Starting processes")
|
|
123
|
+
supervisord.main(["-c", path])
|
|
47
124
|
|
|
48
125
|
|
|
49
126
|
if __name__ == "__main__":
|
sovereign/statistics.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Optional, Any, Callable, Dict
|
|
3
2
|
from functools import wraps
|
|
4
|
-
from
|
|
3
|
+
from typing import Any, Callable, Dict, Optional
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
from sovereign.configuration import config as sovereign_config
|
|
6
|
+
|
|
7
|
+
STATSD: Dict[str, Optional["StatsDProxy"]] = {"instance": None}
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class StatsDProxy:
|
|
10
11
|
def __init__(self, statsd_instance: Optional[Any] = None) -> None:
|
|
11
12
|
self.statsd = statsd_instance
|
|
12
|
-
self.emitted = emitted
|
|
13
13
|
|
|
14
14
|
def __getattr__(self, item: str) -> Any:
|
|
15
15
|
if self.statsd is not None:
|
|
@@ -20,14 +20,12 @@ class StatsDProxy:
|
|
|
20
20
|
return self.do_nothing
|
|
21
21
|
|
|
22
22
|
def do_nothing(self, *args: Any, **kwargs: Any) -> None:
|
|
23
|
-
|
|
24
|
-
emitted[k] = emitted.setdefault(k, 0) + 1
|
|
23
|
+
_ = args[0]
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
class StatsdNoop:
|
|
28
|
-
def __init__(self, *args
|
|
29
|
-
|
|
30
|
-
emitted[k] = emitted.setdefault(k, 0) + 1
|
|
27
|
+
def __init__(self, *args, **kwargs):
|
|
28
|
+
pass
|
|
31
29
|
|
|
32
30
|
def __enter__(self): # type: ignore
|
|
33
31
|
return self
|
|
@@ -43,21 +41,18 @@ class StatsdNoop:
|
|
|
43
41
|
return wrapped
|
|
44
42
|
|
|
45
43
|
|
|
46
|
-
def configure_statsd(
|
|
44
|
+
def configure_statsd() -> StatsDProxy:
|
|
45
|
+
if STATSD["instance"] is not None:
|
|
46
|
+
return STATSD["instance"]
|
|
47
|
+
config = sovereign_config.statsd
|
|
47
48
|
try:
|
|
48
49
|
from datadog import DogStatsd
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
self.emitted: Dict[str, Any] = dict()
|
|
54
|
-
self.emitted[metric] = self.emitted.setdefault(metric, 0) + 1
|
|
55
|
-
|
|
56
|
-
module: Optional[CustomStatsd]
|
|
57
|
-
module = CustomStatsd()
|
|
58
|
-
if config.enabled:
|
|
51
|
+
module: Optional[DogStatsd]
|
|
52
|
+
module = DogStatsd()
|
|
53
|
+
if config.enabled and module:
|
|
59
54
|
module.host = config.host
|
|
60
|
-
module.port = config.port
|
|
55
|
+
module.port = int(config.port)
|
|
61
56
|
module.namespace = config.namespace
|
|
62
57
|
module.use_ms = config.use_ms
|
|
63
58
|
for tag, value in config.tags.items():
|
|
@@ -71,4 +66,7 @@ def configure_statsd(config: StatsdConfig) -> StatsDProxy:
|
|
|
71
66
|
raise
|
|
72
67
|
module = None
|
|
73
68
|
|
|
74
|
-
|
|
69
|
+
ret = StatsDProxy(module)
|
|
70
|
+
if STATSD["instance"] is None:
|
|
71
|
+
STATSD["instance"] = ret
|
|
72
|
+
return ret
|
sovereign/templates/base.html
CHANGED
|
@@ -1,64 +1,77 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="en"
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|
7
7
|
<link rel="stylesheet" type="text/css" href="/static/style.css">
|
|
8
8
|
<title>{% block title %}{% endblock %} - Sovereign</title>
|
|
9
|
+
<script src="/static/darkmode.js"></script>
|
|
9
10
|
{%- block head %}{% endblock %}
|
|
10
11
|
</head>
|
|
11
12
|
<body>
|
|
12
|
-
<div class="columns">
|
|
13
|
-
<div class="column"></div>
|
|
14
13
|
{%- block nav %}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<a
|
|
34
|
-
|
|
35
|
-
|
|
14
|
+
<div class="hero">
|
|
15
|
+
<div class="hero-body p-4">
|
|
16
|
+
<a href="#">
|
|
17
|
+
<h3 class="title is-3" style="margin-bottom: 0px">sovereign</h3>
|
|
18
|
+
<h7 class="title is-7">version {{ sovereign_version }}</h7>
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div class="columns is-gapless" style="min-height: calc(100vh - 120px);">
|
|
24
|
+
<div class="column is-narrow" style="width: 250px;">
|
|
25
|
+
<aside class="menu p-4" style="height: 100%;">
|
|
26
|
+
<div class="mb-4">
|
|
27
|
+
<p class="menu-label">RESOURCES</p>
|
|
28
|
+
<ul class="menu-list">
|
|
29
|
+
{%- set active_page = resource_type|default('redirect_to_docs') -%}
|
|
30
|
+
{%- for type in all_types %}
|
|
31
|
+
<li style="padding: 2px">
|
|
32
|
+
<a href="/ui/resources/{{ type }}"
|
|
33
|
+
style="padding: 3px; border-radius: 4px"
|
|
34
|
+
{% if type == active_page %}class="is-active has-background-primary has-text-white"{% endif %}>
|
|
35
|
+
{{ type|capitalize }}
|
|
36
36
|
</a>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</
|
|
37
|
+
</li>
|
|
38
|
+
{%- endfor %}
|
|
39
|
+
</ul>
|
|
40
40
|
</div>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
|
|
42
|
+
<div class="mb-4">
|
|
43
|
+
<p class="menu-label">LINKS</p>
|
|
44
|
+
<ul class="menu-list">
|
|
45
|
+
<li>
|
|
46
|
+
<a href="/docs">OpenAPI Spec</a>
|
|
47
|
+
</li>
|
|
48
|
+
<li>
|
|
49
|
+
<a href="https://developer.atlassian.com/platform/sovereign/">Documentation</a>
|
|
50
|
+
</li>
|
|
51
|
+
<li>
|
|
52
|
+
<a href="https://bitbucket.org/atlassian/sovereign">Repository</a>
|
|
53
|
+
</li>
|
|
54
|
+
</ul>
|
|
47
55
|
</div>
|
|
56
|
+
|
|
57
|
+
<p class="menu-label">THEME</p>
|
|
58
|
+
<button id="dark-mode-toggle" class="button is-small">
|
|
59
|
+
<span>🌘</span>
|
|
60
|
+
</button>
|
|
61
|
+
</aside>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div class="column">
|
|
65
|
+
<div class="p-4" style="max-width: 1000px">
|
|
66
|
+
{%- endblock %}
|
|
67
|
+
{%- block body %}
|
|
68
|
+
{% endblock -%}
|
|
48
69
|
</div>
|
|
49
|
-
</
|
|
50
|
-
{%- endblock %}
|
|
51
|
-
|
|
52
|
-
{%- block subnav %}
|
|
53
|
-
{%- endblock %}
|
|
54
|
-
|
|
55
|
-
{%- block body %}
|
|
56
|
-
{% endblock -%}
|
|
70
|
+
</div>
|
|
57
71
|
</div>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</footer>
|
|
72
|
+
|
|
73
|
+
<footer class="footer">
|
|
74
|
+
{% block footer %}{% endblock %}
|
|
75
|
+
</footer>
|
|
63
76
|
</body>
|
|
64
77
|
</html>
|