sovereign 0.29.4__tar.gz → 0.31.0__tar.gz
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-0.29.4 → sovereign-0.31.0}/PKG-INFO +44 -46
- {sovereign-0.29.4 → sovereign-0.31.0}/README.md +40 -43
- {sovereign-0.29.4 → sovereign-0.31.0}/pyproject.toml +20 -32
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/__init__.py +34 -40
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/app.py +11 -10
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/context.py +37 -24
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/discovery.py +8 -9
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/dynamic_config/__init__.py +1 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/dynamic_config/deser.py +1 -2
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/dynamic_config/loaders.py +1 -2
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/logging/access_logger.py +14 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/logging/application_logger.py +0 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/logging/base_logger.py +3 -27
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/logging/bootstrapper.py +1 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/middlewares.py +3 -2
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/modifiers/lib.py +1 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/schemas.py +86 -37
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/sources/inline.py +1 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/sources/lib.py +1 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/sources/poller.py +8 -8
- sovereign-0.31.0/src/sovereign/static/panel.js +56 -0
- sovereign-0.31.0/src/sovereign/static/search_filter.js +20 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/templates/resources.html +39 -36
- sovereign-0.31.0/src/sovereign/tracing.py +85 -0
- sovereign-0.31.0/src/sovereign/utils/crypto/suites/base_cipher.py +21 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/dictupdate.py +2 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/admin.py +23 -4
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/crypto.py +2 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/healthchecks.py +2 -1
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/interface.py +21 -5
- sovereign-0.29.4/src/sovereign/configuration.py +0 -66
- sovereign-0.29.4/src/sovereign/templates/ul_filter.html +0 -22
- sovereign-0.29.4/src/sovereign/tracing.py +0 -85
- sovereign-0.29.4/src/sovereign/utils/crypto/suites/base_cipher.py +0 -26
- {sovereign-0.29.4 → sovereign-0.31.0}/LICENSE.txt +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/constants.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/error_info.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/logging/types.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/modifiers/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/response_class.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/server.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/sources/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/sources/file.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/static/sass/style.scss +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/static/style.css +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/statistics.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/templates/base.html +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/templates/err.html +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/testing/loaders.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/testing/modifiers.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/auth.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/crypto.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/suites/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/suites/aes_gcm_cipher.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/suites/disabled_cipher.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/crypto/suites/fernet_cipher.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/eds.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/entry_point_loader.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/mock.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/resources.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/templates.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/timer.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/version_info.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/utils/weighted_clusters.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/__init__.py +0 -0
- {sovereign-0.29.4 → sovereign-0.31.0}/src/sovereign/views/discovery.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sovereign
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.0
|
|
4
4
|
Summary: Envoy Proxy control-plane written in Python
|
|
5
5
|
Home-page: https://pypi.org/project/sovereign/
|
|
6
6
|
License: Apache-2.0
|
|
@@ -43,7 +43,7 @@ Requires-Dist: cryptography (>=42.0.0,<43.0.0)
|
|
|
43
43
|
Requires-Dist: datadog (>=0.47.0,<0.48.0) ; extra == "statsd"
|
|
44
44
|
Requires-Dist: fastapi (>=0.115.2,<0.116.0)
|
|
45
45
|
Requires-Dist: glom (>=23.3.0,<24.0.0)
|
|
46
|
-
Requires-Dist: gunicorn (>=
|
|
46
|
+
Requires-Dist: gunicorn (>=23.0.0,<24.0.0)
|
|
47
47
|
Requires-Dist: httptools (>=0.6.0,<0.7.0) ; extra == "httptools"
|
|
48
48
|
Requires-Dist: orjson (>=3.9.15,<4.0.0) ; extra == "orjson"
|
|
49
49
|
Requires-Dist: pydantic (>=2.7.2,<3.0.0)
|
|
@@ -51,60 +51,70 @@ Requires-Dist: pydantic-settings (<2.6.0)
|
|
|
51
51
|
Requires-Dist: redis (<=5.0.0)
|
|
52
52
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
53
53
|
Requires-Dist: sentry-sdk (>=2.14.0,<3.0.0) ; extra == "sentry"
|
|
54
|
+
Requires-Dist: starlette-context (>=0.3.6,<0.4.0)
|
|
54
55
|
Requires-Dist: structlog (>=23.1.0,<24.0.0)
|
|
55
56
|
Requires-Dist: ujson (>=5.8.0,<6.0.0) ; extra == "ujson"
|
|
56
57
|
Requires-Dist: uvicorn (>=0.23.2,<0.24.0)
|
|
57
58
|
Requires-Dist: uvloop (>=0.19.0,<0.20.0)
|
|
58
|
-
Project-URL: Documentation, https://
|
|
59
|
+
Project-URL: Documentation, https://developer.atlassian.com/platform/sovereign/
|
|
59
60
|
Project-URL: Repository, https://bitbucket.org/atlassian/sovereign/src/master/
|
|
60
61
|
Description-Content-Type: text/markdown
|
|
61
62
|
|
|
62
63
|
sovereign
|
|
63
64
|
=========
|
|
64
65
|
|
|
66
|
+
|
|
65
67
|
Mission statement
|
|
66
68
|
-----------------
|
|
67
69
|
This project implements a JSON control-plane based on the [envoy](https://envoyproxy.io) [data-plane-api](https://github.com/envoyproxy/data-plane-api)
|
|
68
70
|
|
|
69
|
-
The purpose of `sovereign` is to supply downstream envoy proxies with
|
|
70
|
-
|
|
71
|
+
The purpose of `sovereign` is to supply downstream envoy proxies with dynamic configuration.
|
|
72
|
+
|
|
71
73
|
|
|
72
74
|
Mechanism of Operation
|
|
73
75
|
----------------------
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
Sovereign allows you to define templates that represent each resource type
|
|
77
|
+
provided by Envoy. For example, clusters, routes, listeners, secrets,
|
|
78
|
+
extension_configs, etc.
|
|
79
|
+
|
|
80
|
+
In order to enrich the templates with data, Sovereign has ways of polling data
|
|
81
|
+
out-of-band which it then includes as variables that can be accessed within the
|
|
82
|
+
templates.
|
|
83
|
+
|
|
84
|
+
This allows Sovereign to provide configuration to Envoy that changes over time
|
|
85
|
+
depending on the data sources, without needing to redeploy the control-plane.
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
uses the data to generate envoy configuration from either python code, or jinja2 templates.
|
|
87
|
+
Sovereign provides some built-in ways of polling data (such as over HTTP, or
|
|
88
|
+
on-disk) but also exposes extension points, allowing you to write your own
|
|
89
|
+
plugins in Python.
|
|
85
90
|
|
|
86
|
-
This is performed in a semi-stateless way, where the only state is data cached in memory.
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
Support
|
|
93
|
+
------------
|
|
94
|
+
[Submit new issues here](https://bitbucket.org/atlassian/sovereign/issues/new)
|
|
95
|
+
|
|
96
|
+
If you're unable to submit an issue on Bitbucket, send an email to [vsyrakis@atlassian.com](mailto:vsyrakis@atlassian.com)
|
|
97
|
+
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
Release
|
|
100
|
+
------------
|
|
101
|
+
See [RELEASE.md]
|
|
94
102
|
|
|
95
|
-
Both modifiers and sources are pluggable, i.e. it's easy to write your own and
|
|
96
|
-
plug them into Sovereign for your use-case.
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
Roadmap
|
|
105
|
+
------------
|
|
106
|
+
* Performance improvements
|
|
107
|
+
* Data persistence
|
|
108
|
+
* Push API (versus polling)
|
|
109
|
+
* Client for Sovereign
|
|
110
|
+
* gRPC
|
|
101
111
|
|
|
102
|
-
The JSON configuration can be viewed in real-time with Sovereign's read-only web interface.
|
|
103
112
|
|
|
104
113
|
Requirements
|
|
105
114
|
------------
|
|
106
115
|
* Python 3.8+
|
|
107
116
|
|
|
117
|
+
|
|
108
118
|
Installation
|
|
109
119
|
------------
|
|
110
120
|
```
|
|
@@ -113,62 +123,52 @@ pip install sovereign
|
|
|
113
123
|
|
|
114
124
|
Documentation
|
|
115
125
|
-------------
|
|
116
|
-
[Read the docs here!](https://
|
|
126
|
+
[Read the docs here!](https://developer.atlassian.com/platform/sovereign/)
|
|
117
127
|
|
|
118
|
-
:new: Read-only user interface
|
|
119
|
-
------------------------
|
|
120
|
-
Added in `v0.5.3`!
|
|
121
128
|
|
|
122
|
-
This interface allows you to browse the resources currently returned by Sovereign.
|
|
123
|
-
|
|
124
|
-

|
|
125
129
|
|
|
126
130
|
Local development
|
|
127
131
|
=================
|
|
128
132
|
|
|
133
|
+
|
|
129
134
|
Requirements
|
|
130
135
|
------------
|
|
136
|
+
* Poetry
|
|
131
137
|
* Docker
|
|
132
138
|
* Docker-compose
|
|
133
139
|
|
|
140
|
+
|
|
134
141
|
Installing dependencies for dev
|
|
135
142
|
-------------------------------
|
|
136
|
-
|
|
137
|
-
|
|
143
|
+
Dependencies and creation of virtualenv is handled by poetry
|
|
138
144
|
```
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
pip install -r requirements-dev.txt
|
|
145
|
+
poetry install
|
|
146
|
+
poetry shell
|
|
142
147
|
```
|
|
143
148
|
|
|
144
149
|
Running locally
|
|
145
150
|
---------------
|
|
146
151
|
Running the test env
|
|
147
|
-
|
|
148
152
|
```
|
|
149
153
|
make run
|
|
150
154
|
```
|
|
151
155
|
|
|
152
156
|
Running the test env daemonized
|
|
153
|
-
|
|
154
157
|
```
|
|
155
158
|
make run-daemon
|
|
156
159
|
```
|
|
157
160
|
|
|
158
161
|
Pylint
|
|
159
|
-
|
|
160
162
|
```
|
|
161
163
|
make lint
|
|
162
164
|
```
|
|
163
165
|
|
|
164
166
|
Unit tests
|
|
165
|
-
|
|
166
167
|
```
|
|
167
168
|
make unit
|
|
168
169
|
```
|
|
169
170
|
|
|
170
171
|
Acceptance tests
|
|
171
|
-
|
|
172
172
|
```
|
|
173
173
|
make run-daemon acceptance
|
|
174
174
|
```
|
|
@@ -176,7 +176,6 @@ make run-daemon acceptance
|
|
|
176
176
|
|
|
177
177
|
Contributors
|
|
178
178
|
============
|
|
179
|
-
|
|
180
179
|
Pull requests, issues and comments welcome. For pull requests:
|
|
181
180
|
|
|
182
181
|
* Add tests for new features and bug fixes
|
|
@@ -205,7 +204,6 @@ those contributing as an individual.
|
|
|
205
204
|
|
|
206
205
|
License
|
|
207
206
|
========
|
|
208
|
-
|
|
209
207
|
Copyright (c) 2018 Atlassian and others.
|
|
210
208
|
Apache 2.0 licensed, see [LICENSE.txt](LICENSE.txt) file.
|
|
211
209
|
|
|
@@ -1,49 +1,58 @@
|
|
|
1
1
|
sovereign
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
Mission statement
|
|
5
6
|
-----------------
|
|
6
7
|
This project implements a JSON control-plane based on the [envoy](https://envoyproxy.io) [data-plane-api](https://github.com/envoyproxy/data-plane-api)
|
|
7
8
|
|
|
8
|
-
The purpose of `sovereign` is to supply downstream envoy proxies with
|
|
9
|
-
|
|
9
|
+
The purpose of `sovereign` is to supply downstream envoy proxies with dynamic configuration.
|
|
10
|
+
|
|
10
11
|
|
|
11
12
|
Mechanism of Operation
|
|
12
13
|
----------------------
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
Sovereign allows you to define templates that represent each resource type
|
|
15
|
+
provided by Envoy. For example, clusters, routes, listeners, secrets,
|
|
16
|
+
extension_configs, etc.
|
|
17
|
+
|
|
18
|
+
In order to enrich the templates with data, Sovereign has ways of polling data
|
|
19
|
+
out-of-band which it then includes as variables that can be accessed within the
|
|
20
|
+
templates.
|
|
21
|
+
|
|
22
|
+
This allows Sovereign to provide configuration to Envoy that changes over time
|
|
23
|
+
depending on the data sources, without needing to redeploy the control-plane.
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
uses the data to generate envoy configuration from either python code, or jinja2 templates.
|
|
25
|
+
Sovereign provides some built-in ways of polling data (such as over HTTP, or
|
|
26
|
+
on-disk) but also exposes extension points, allowing you to write your own
|
|
27
|
+
plugins in Python.
|
|
24
28
|
|
|
25
|
-
This is performed in a semi-stateless way, where the only state is data cached in memory.
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
Support
|
|
31
|
+
------------
|
|
32
|
+
[Submit new issues here](https://bitbucket.org/atlassian/sovereign/issues/new)
|
|
33
|
+
|
|
34
|
+
If you're unable to submit an issue on Bitbucket, send an email to [vsyrakis@atlassian.com](mailto:vsyrakis@atlassian.com)
|
|
35
|
+
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
Release
|
|
38
|
+
------------
|
|
39
|
+
See [RELEASE.md]
|
|
33
40
|
|
|
34
|
-
Both modifiers and sources are pluggable, i.e. it's easy to write your own and
|
|
35
|
-
plug them into Sovereign for your use-case.
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
Roadmap
|
|
43
|
+
------------
|
|
44
|
+
* Performance improvements
|
|
45
|
+
* Data persistence
|
|
46
|
+
* Push API (versus polling)
|
|
47
|
+
* Client for Sovereign
|
|
48
|
+
* gRPC
|
|
40
49
|
|
|
41
|
-
The JSON configuration can be viewed in real-time with Sovereign's read-only web interface.
|
|
42
50
|
|
|
43
51
|
Requirements
|
|
44
52
|
------------
|
|
45
53
|
* Python 3.8+
|
|
46
54
|
|
|
55
|
+
|
|
47
56
|
Installation
|
|
48
57
|
------------
|
|
49
58
|
```
|
|
@@ -52,62 +61,52 @@ pip install sovereign
|
|
|
52
61
|
|
|
53
62
|
Documentation
|
|
54
63
|
-------------
|
|
55
|
-
[Read the docs here!](https://
|
|
64
|
+
[Read the docs here!](https://developer.atlassian.com/platform/sovereign/)
|
|
56
65
|
|
|
57
|
-
:new: Read-only user interface
|
|
58
|
-
------------------------
|
|
59
|
-
Added in `v0.5.3`!
|
|
60
66
|
|
|
61
|
-
This interface allows you to browse the resources currently returned by Sovereign.
|
|
62
|
-
|
|
63
|
-

|
|
64
67
|
|
|
65
68
|
Local development
|
|
66
69
|
=================
|
|
67
70
|
|
|
71
|
+
|
|
68
72
|
Requirements
|
|
69
73
|
------------
|
|
74
|
+
* Poetry
|
|
70
75
|
* Docker
|
|
71
76
|
* Docker-compose
|
|
72
77
|
|
|
78
|
+
|
|
73
79
|
Installing dependencies for dev
|
|
74
80
|
-------------------------------
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
Dependencies and creation of virtualenv is handled by poetry
|
|
77
82
|
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
pip install -r requirements-dev.txt
|
|
83
|
+
poetry install
|
|
84
|
+
poetry shell
|
|
81
85
|
```
|
|
82
86
|
|
|
83
87
|
Running locally
|
|
84
88
|
---------------
|
|
85
89
|
Running the test env
|
|
86
|
-
|
|
87
90
|
```
|
|
88
91
|
make run
|
|
89
92
|
```
|
|
90
93
|
|
|
91
94
|
Running the test env daemonized
|
|
92
|
-
|
|
93
95
|
```
|
|
94
96
|
make run-daemon
|
|
95
97
|
```
|
|
96
98
|
|
|
97
99
|
Pylint
|
|
98
|
-
|
|
99
100
|
```
|
|
100
101
|
make lint
|
|
101
102
|
```
|
|
102
103
|
|
|
103
104
|
Unit tests
|
|
104
|
-
|
|
105
105
|
```
|
|
106
106
|
make unit
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
Acceptance tests
|
|
110
|
-
|
|
111
110
|
```
|
|
112
111
|
make run-daemon acceptance
|
|
113
112
|
```
|
|
@@ -115,7 +114,6 @@ make run-daemon acceptance
|
|
|
115
114
|
|
|
116
115
|
Contributors
|
|
117
116
|
============
|
|
118
|
-
|
|
119
117
|
Pull requests, issues and comments welcome. For pull requests:
|
|
120
118
|
|
|
121
119
|
* Add tests for new features and bug fixes
|
|
@@ -144,7 +142,6 @@ those contributing as an individual.
|
|
|
144
142
|
|
|
145
143
|
License
|
|
146
144
|
========
|
|
147
|
-
|
|
148
145
|
Copyright (c) 2018 Atlassian and others.
|
|
149
146
|
Apache 2.0 licensed, see [LICENSE.txt](LICENSE.txt) file.
|
|
150
147
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "sovereign"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.31.0"
|
|
4
4
|
description = "Envoy Proxy control-plane written in Python"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
packages = [
|
|
@@ -8,7 +8,7 @@ packages = [
|
|
|
8
8
|
]
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
#include = ["CHANGELOG.md", "CODE_OF_CONDUCT.md"]
|
|
11
|
-
documentation = "https://
|
|
11
|
+
documentation = "https://developer.atlassian.com/platform/sovereign/"
|
|
12
12
|
repository = "https://bitbucket.org/atlassian/sovereign/src/master/"
|
|
13
13
|
homepage = "https://pypi.org/project/sovereign/"
|
|
14
14
|
authors = ["Vasili Syrakis <vsyrakis@atlassian.com>"]
|
|
@@ -58,6 +58,8 @@ sovereign = 'sovereign.server:main'
|
|
|
58
58
|
"jinja2" = "sovereign.dynamic_config.deser:JinjaDeserializer"
|
|
59
59
|
"string" = "sovereign.dynamic_config.deser:StringDeserializer"
|
|
60
60
|
"raw" = "sovereign.dynamic_config.deser:PassthroughDeserializer"
|
|
61
|
+
"none" = "sovereign.dynamic_config.deser:PassthroughDeserializer"
|
|
62
|
+
"passthrough" = "sovereign.dynamic_config.deser:PassthroughDeserializer"
|
|
61
63
|
"ujson" = "sovereign.dynamic_config.deser:UjsonDeserializer"
|
|
62
64
|
"orjson" = "sovereign.dynamic_config.deser:OrjsonDeserializer"
|
|
63
65
|
|
|
@@ -65,7 +67,7 @@ sovereign = 'sovereign.server:main'
|
|
|
65
67
|
[tool.poetry.dependencies]
|
|
66
68
|
python = "^3.11"
|
|
67
69
|
uvicorn = "^0.23.2"
|
|
68
|
-
gunicorn = "^
|
|
70
|
+
gunicorn = "^23.0.0"
|
|
69
71
|
aiofiles = "^23.2.1"
|
|
70
72
|
requests = "^2.31.0"
|
|
71
73
|
PyYAML = "^6.0.1"
|
|
@@ -88,6 +90,7 @@ httptools = {version = "^0.6.0", optional = true}
|
|
|
88
90
|
cachetools = "^5.3.2"
|
|
89
91
|
pydantic = "^2.7.2"
|
|
90
92
|
pydantic-settings = "<2.6.0"
|
|
93
|
+
starlette-context = "^0.3.6"
|
|
91
94
|
|
|
92
95
|
[tool.poetry.extras]
|
|
93
96
|
sentry = ["sentry-sdk"]
|
|
@@ -99,40 +102,28 @@ caching = ["cashews"]
|
|
|
99
102
|
httptools = ["httptools"]
|
|
100
103
|
|
|
101
104
|
[tool.poetry.group.dev.dependencies]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
pytest-mock = "^3.10.0"
|
|
106
|
-
pytest-spec = "^3.2.0"
|
|
107
|
-
pytest-timeout = "^2.1.0"
|
|
108
|
-
coverage = "^7.3.1"
|
|
109
|
-
invoke = "^2.2.0"
|
|
110
|
-
pylint = "^2.17.6"
|
|
111
|
-
tavern = "^2.9.2"
|
|
112
|
-
twine = "^4.0.2"
|
|
113
|
-
poethepoet = "^0.23.0"
|
|
114
|
-
mypy = "^1.8.0"
|
|
115
|
-
black = "^23.9.1"
|
|
116
|
-
freezegun = "^1.2.2"
|
|
105
|
+
# http integration test
|
|
106
|
+
tavern = "^2.11.0"
|
|
107
|
+
# mocking
|
|
117
108
|
moto = "^4.2.4"
|
|
118
|
-
|
|
109
|
+
freezegun = "^1.2.2"
|
|
110
|
+
pytest-mock = "^3.14.0"
|
|
111
|
+
pytest-asyncio = "^0.23"
|
|
112
|
+
# type and lint checks
|
|
113
|
+
mypy = "^1.8.0"
|
|
114
|
+
ruff = "^0.8.4"
|
|
115
|
+
# used in release checking script
|
|
116
|
+
toml = "^0.10.2"
|
|
117
|
+
# needed for starlette testclient
|
|
118
|
+
httpx = "^0.28.1"
|
|
119
|
+
# mypy types
|
|
119
120
|
types-croniter = "^1.4.0.1"
|
|
120
121
|
types-requests = "^2.31.0.8"
|
|
121
122
|
types-setuptools = "^68.2.0.0"
|
|
122
123
|
types-ujson = "^5.8.0.1"
|
|
123
124
|
types-PyYAML = "^6.0.12.12"
|
|
124
|
-
pylama = "^8.4.1"
|
|
125
|
-
prospector = "^1.10.2"
|
|
126
|
-
toml = "^0.10.2"
|
|
127
125
|
types-cachetools = "^5.3.0.7"
|
|
128
126
|
|
|
129
|
-
[tool.poe.tasks]
|
|
130
|
-
types = { cmd = "mypy src/sovereign --ignore-missing-imports", help = "Check types with mypy" }
|
|
131
|
-
format = { cmd = "black . --exclude test", help = "Apply black formatting to source code" }
|
|
132
|
-
clean = { cmd = "rm -rf site test-reports logs .coverage .mypy_cache .pytest_cache dist sovereign.egg-info **/__pycache__", help = "Clean out generated files from the workspace" }
|
|
133
|
-
check-style = { cmd = "black . --check --diff --exclude test", help = "Check if code style is correct" }
|
|
134
|
-
lint = { cmd = "pylint src/sovereign", help = "Run linter checks" }
|
|
135
|
-
|
|
136
127
|
[tool.black]
|
|
137
128
|
target-version = ['py311']
|
|
138
129
|
|
|
@@ -142,9 +133,6 @@ plugins = [
|
|
|
142
133
|
]
|
|
143
134
|
ignore_missing_imports = true
|
|
144
135
|
|
|
145
|
-
[tool.coverage.run]
|
|
146
|
-
omit = ["test/*"]
|
|
147
|
-
|
|
148
136
|
[build-system]
|
|
149
137
|
requires = ["poetry-core>=1.0.0"]
|
|
150
138
|
build-backend = "poetry.core.masonry.api"
|
|
@@ -1,46 +1,26 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import sys
|
|
2
3
|
from contextvars import ContextVar
|
|
3
4
|
from importlib.metadata import version
|
|
4
|
-
from typing import
|
|
5
|
+
from typing import Optional
|
|
5
6
|
|
|
6
|
-
from fastapi.responses import JSONResponse
|
|
7
7
|
from pydantic import ValidationError
|
|
8
8
|
from starlette.templating import Jinja2Templates
|
|
9
9
|
|
|
10
|
-
from sovereign import dynamic_config
|
|
11
10
|
from sovereign.context import TemplateContext
|
|
12
11
|
from sovereign.logging.bootstrapper import LoggerBootstrapper
|
|
13
|
-
from sovereign.schemas import
|
|
12
|
+
from sovereign.schemas import (
|
|
13
|
+
SovereignAsgiConfig,
|
|
14
|
+
SovereignConfig,
|
|
15
|
+
SovereignConfigv2,
|
|
16
|
+
migrate_configs,
|
|
17
|
+
parse_raw_configuration,
|
|
18
|
+
)
|
|
14
19
|
from sovereign.sources import SourcePoller
|
|
15
20
|
from sovereign.statistics import configure_statsd
|
|
16
21
|
from sovereign.utils.crypto.crypto import CipherContainer
|
|
17
|
-
from sovereign.utils.dictupdate import merge # type: ignore
|
|
18
22
|
from sovereign.utils.resources import get_package_file
|
|
19
23
|
|
|
20
|
-
json_response_class: Type[JSONResponse] = JSONResponse
|
|
21
|
-
try:
|
|
22
|
-
import orjson
|
|
23
|
-
from fastapi.responses import ORJSONResponse
|
|
24
|
-
|
|
25
|
-
json_response_class = ORJSONResponse
|
|
26
|
-
except ImportError:
|
|
27
|
-
try:
|
|
28
|
-
import ujson
|
|
29
|
-
from fastapi.responses import UJSONResponse
|
|
30
|
-
|
|
31
|
-
json_response_class = UJSONResponse
|
|
32
|
-
except ImportError:
|
|
33
|
-
pass
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def parse_raw_configuration(path: str) -> Mapping[Any, Any]:
|
|
37
|
-
ret: Mapping[Any, Any] = dict()
|
|
38
|
-
for p in path.split(","):
|
|
39
|
-
spec = dynamic_config.Loadable.from_legacy_fmt(p)
|
|
40
|
-
ret = merge(obj_a=ret, obj_b=spec.load(), merge_lists=True)
|
|
41
|
-
return ret
|
|
42
|
-
|
|
43
|
-
|
|
44
24
|
_request_id_ctx_var: ContextVar[str] = ContextVar("request_id", default="")
|
|
45
25
|
|
|
46
26
|
|
|
@@ -57,6 +37,9 @@ html_templates = Jinja2Templates(
|
|
|
57
37
|
directory=str(get_package_file(DIST_NAME, "templates"))
|
|
58
38
|
)
|
|
59
39
|
|
|
40
|
+
if sys.argv[0].endswith("sovereign"):
|
|
41
|
+
migrate_configs()
|
|
42
|
+
|
|
60
43
|
try:
|
|
61
44
|
config = SovereignConfigv2(**parse_raw_configuration(config_path))
|
|
62
45
|
except ValidationError:
|
|
@@ -69,15 +52,25 @@ logs = LoggerBootstrapper(config)
|
|
|
69
52
|
application_logger = logs.application_logger.logger
|
|
70
53
|
|
|
71
54
|
stats = configure_statsd(config=config.statsd)
|
|
72
|
-
poller =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
poller = None
|
|
56
|
+
if config.sources is not None:
|
|
57
|
+
if config.matching is not None:
|
|
58
|
+
matching_enabled = config.matching.enabled
|
|
59
|
+
node_key: Optional[str] = config.matching.node_key
|
|
60
|
+
source_key: Optional[str] = config.matching.source_key
|
|
61
|
+
else:
|
|
62
|
+
matching_enabled = False
|
|
63
|
+
node_key = None
|
|
64
|
+
source_key = None
|
|
65
|
+
poller = SourcePoller(
|
|
66
|
+
sources=config.sources,
|
|
67
|
+
matching_enabled=matching_enabled,
|
|
68
|
+
node_match_key=node_key,
|
|
69
|
+
source_match_key=source_key,
|
|
70
|
+
source_refresh_rate=config.source_config.refresh_rate,
|
|
71
|
+
logger=application_logger,
|
|
72
|
+
stats=stats,
|
|
73
|
+
)
|
|
81
74
|
|
|
82
75
|
encryption_configs = config.authentication.encryption_configs
|
|
83
76
|
server_cipher_container = CipherContainer.from_encryption_configs(
|
|
@@ -95,5 +88,6 @@ template_context = TemplateContext(
|
|
|
95
88
|
logger=application_logger,
|
|
96
89
|
stats=stats,
|
|
97
90
|
)
|
|
98
|
-
poller
|
|
99
|
-
poller.
|
|
91
|
+
if poller is not None:
|
|
92
|
+
poller.lazy_load_modifiers(config.modifiers)
|
|
93
|
+
poller.lazy_load_global_modifiers(config.global_modifiers)
|
|
@@ -4,24 +4,22 @@ from collections import namedtuple
|
|
|
4
4
|
|
|
5
5
|
import uvicorn
|
|
6
6
|
from fastapi import FastAPI, Request
|
|
7
|
-
from fastapi.responses import
|
|
7
|
+
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse, Response
|
|
8
|
+
from starlette_context.middleware import RawContextMiddleware
|
|
8
9
|
|
|
9
10
|
from sovereign import (
|
|
10
11
|
__version__,
|
|
11
|
-
config,
|
|
12
12
|
asgi_config,
|
|
13
|
-
|
|
13
|
+
config,
|
|
14
|
+
logs,
|
|
14
15
|
poller,
|
|
15
16
|
template_context,
|
|
16
|
-
logs,
|
|
17
17
|
)
|
|
18
|
+
from sovereign.response_class import json_response_class
|
|
18
19
|
from sovereign.error_info import ErrorInfo
|
|
20
|
+
from sovereign.middlewares import LoggingMiddleware, RequestContextLogMiddleware
|
|
19
21
|
from sovereign.utils.resources import get_package_file
|
|
20
|
-
from sovereign.views import crypto, discovery, healthchecks,
|
|
21
|
-
from sovereign.middlewares import (
|
|
22
|
-
RequestContextLogMiddleware,
|
|
23
|
-
LoggingMiddleware,
|
|
24
|
-
)
|
|
22
|
+
from sovereign.views import admin, crypto, discovery, healthchecks, interface
|
|
25
23
|
|
|
26
24
|
Router = namedtuple("Router", "module tags prefix")
|
|
27
25
|
|
|
@@ -89,6 +87,8 @@ def init_app() -> FastAPI:
|
|
|
89
87
|
application.add_middleware(SentryAsgiMiddleware)
|
|
90
88
|
logs.application_logger.logger.info("Sentry middleware enabled")
|
|
91
89
|
|
|
90
|
+
application.add_middleware(RawContextMiddleware)
|
|
91
|
+
|
|
92
92
|
@application.exception_handler(500)
|
|
93
93
|
async def exception_handler(_: Request, exc: Exception) -> JSONResponse:
|
|
94
94
|
"""
|
|
@@ -109,7 +109,8 @@ def init_app() -> FastAPI:
|
|
|
109
109
|
|
|
110
110
|
@application.on_event("startup")
|
|
111
111
|
async def keep_sources_uptodate() -> None:
|
|
112
|
-
|
|
112
|
+
if poller is not None:
|
|
113
|
+
asyncio.create_task(poller.poll_forever())
|
|
113
114
|
|
|
114
115
|
@application.on_event("startup")
|
|
115
116
|
async def refresh_template_context() -> None:
|