sovereign 0.17.1__tar.gz → 1.0.0a3__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.
Files changed (112) hide show
  1. {sovereign-0.17.1 → sovereign-1.0.0a3}/PKG-INFO +78 -75
  2. {sovereign-0.17.1 → sovereign-1.0.0a3}/README.md +41 -43
  3. sovereign-1.0.0a3/pyproject.toml +161 -0
  4. sovereign-1.0.0a3/src/sovereign/__init__.py +32 -0
  5. sovereign-1.0.0a3/src/sovereign/app.py +140 -0
  6. sovereign-1.0.0a3/src/sovereign/cache/__init__.py +245 -0
  7. sovereign-1.0.0a3/src/sovereign/cache/backends/__init__.py +110 -0
  8. sovereign-1.0.0a3/src/sovereign/cache/backends/s3.py +161 -0
  9. sovereign-1.0.0a3/src/sovereign/cache/filesystem.py +74 -0
  10. sovereign-1.0.0a3/src/sovereign/cache/types.py +17 -0
  11. sovereign-1.0.0a3/src/sovereign/configuration.py +607 -0
  12. sovereign-1.0.0a3/src/sovereign/constants.py +1 -0
  13. sovereign-1.0.0a3/src/sovereign/context.py +285 -0
  14. sovereign-1.0.0a3/src/sovereign/dynamic_config/__init__.py +112 -0
  15. sovereign-1.0.0a3/src/sovereign/dynamic_config/deser.py +78 -0
  16. sovereign-1.0.0a3/src/sovereign/dynamic_config/loaders.py +120 -0
  17. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/error_info.py +2 -3
  18. sovereign-1.0.0a3/src/sovereign/events.py +49 -0
  19. sovereign-1.0.0a3/src/sovereign/logging/access_logger.py +85 -0
  20. sovereign-1.0.0a3/src/sovereign/logging/application_logger.py +54 -0
  21. sovereign-1.0.0a3/src/sovereign/logging/base_logger.py +41 -0
  22. sovereign-1.0.0a3/src/sovereign/logging/bootstrapper.py +36 -0
  23. sovereign-1.0.0a3/src/sovereign/logging/types.py +10 -0
  24. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/middlewares.py +8 -7
  25. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/modifiers/lib.py +2 -1
  26. sovereign-1.0.0a3/src/sovereign/rendering.py +124 -0
  27. sovereign-1.0.0a3/src/sovereign/rendering_common.py +91 -0
  28. sovereign-1.0.0a3/src/sovereign/response_class.py +18 -0
  29. sovereign-1.0.0a3/src/sovereign/server.py +127 -0
  30. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/statistics.py +19 -21
  31. sovereign-1.0.0a3/src/sovereign/templates/base.html +77 -0
  32. sovereign-1.0.0a3/src/sovereign/templates/resources.html +260 -0
  33. sovereign-1.0.0a3/src/sovereign/testing/loaders.py +9 -0
  34. sovereign-0.17.1/src/sovereign/modifiers/test.py → sovereign-1.0.0a3/src/sovereign/testing/modifiers.py +0 -2
  35. sovereign-1.0.0a3/src/sovereign/tracing.py +103 -0
  36. sovereign-1.0.0a3/src/sovereign/types.py +304 -0
  37. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/auth.py +27 -13
  38. sovereign-1.0.0a3/src/sovereign/utils/crypto/crypto.py +135 -0
  39. sovereign-1.0.0a3/src/sovereign/utils/crypto/suites/__init__.py +21 -0
  40. sovereign-1.0.0a3/src/sovereign/utils/crypto/suites/aes_gcm_cipher.py +42 -0
  41. sovereign-1.0.0a3/src/sovereign/utils/crypto/suites/base_cipher.py +21 -0
  42. sovereign-1.0.0a3/src/sovereign/utils/crypto/suites/disabled_cipher.py +25 -0
  43. sovereign-1.0.0a3/src/sovereign/utils/crypto/suites/fernet_cipher.py +29 -0
  44. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/dictupdate.py +3 -2
  45. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/eds.py +40 -22
  46. sovereign-1.0.0a3/src/sovereign/utils/entry_point_loader.py +18 -0
  47. sovereign-1.0.0a3/src/sovereign/utils/mock.py +75 -0
  48. sovereign-1.0.0a3/src/sovereign/utils/resources.py +17 -0
  49. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/templates.py +4 -2
  50. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/timer.py +5 -3
  51. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/version_info.py +8 -0
  52. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/weighted_clusters.py +2 -1
  53. sovereign-1.0.0a3/src/sovereign/v2/__init__.py +0 -0
  54. sovereign-1.0.0a3/src/sovereign/v2/data/data_store.py +621 -0
  55. sovereign-1.0.0a3/src/sovereign/v2/data/render_discovery_response.py +24 -0
  56. sovereign-1.0.0a3/src/sovereign/v2/data/repositories.py +90 -0
  57. sovereign-1.0.0a3/src/sovereign/v2/data/utils.py +33 -0
  58. sovereign-1.0.0a3/src/sovereign/v2/data/worker_queue.py +273 -0
  59. sovereign-1.0.0a3/src/sovereign/v2/jobs/refresh_context.py +117 -0
  60. sovereign-1.0.0a3/src/sovereign/v2/jobs/render_discovery_job.py +145 -0
  61. sovereign-1.0.0a3/src/sovereign/v2/logging.py +81 -0
  62. sovereign-1.0.0a3/src/sovereign/v2/types.py +41 -0
  63. sovereign-1.0.0a3/src/sovereign/v2/web.py +101 -0
  64. sovereign-1.0.0a3/src/sovereign/v2/worker.py +199 -0
  65. sovereign-1.0.0a3/src/sovereign/views/__init__.py +7 -0
  66. sovereign-1.0.0a3/src/sovereign/views/api.py +82 -0
  67. sovereign-1.0.0a3/src/sovereign/views/crypto.py +100 -0
  68. sovereign-1.0.0a3/src/sovereign/views/discovery.py +92 -0
  69. sovereign-1.0.0a3/src/sovereign/views/healthchecks.py +127 -0
  70. sovereign-1.0.0a3/src/sovereign/views/interface.py +261 -0
  71. sovereign-1.0.0a3/src/sovereign/worker.py +193 -0
  72. sovereign-1.0.0a3/src/sovereign_files/__init__.py +0 -0
  73. sovereign-1.0.0a3/src/sovereign_files/static/darkmode.js +51 -0
  74. sovereign-1.0.0a3/src/sovereign_files/static/node_expression.js +42 -0
  75. sovereign-1.0.0a3/src/sovereign_files/static/panel.js +76 -0
  76. sovereign-1.0.0a3/src/sovereign_files/static/resources.css +246 -0
  77. sovereign-1.0.0a3/src/sovereign_files/static/resources.js +642 -0
  78. sovereign-1.0.0a3/src/sovereign_files/static/sass/style.scss +33 -0
  79. sovereign-1.0.0a3/src/sovereign_files/static/style.css +16143 -0
  80. sovereign-1.0.0a3/src/sovereign_files/static/style.css.map +1 -0
  81. sovereign-0.17.1/LICENSE.txt +0 -13
  82. sovereign-0.17.1/pyproject.toml +0 -111
  83. sovereign-0.17.1/setup.py +0 -67
  84. sovereign-0.17.1/src/sovereign/__init__.py +0 -96
  85. sovereign-0.17.1/src/sovereign/app.py +0 -121
  86. sovereign-0.17.1/src/sovereign/config_loader.py +0 -225
  87. sovereign-0.17.1/src/sovereign/context.py +0 -114
  88. sovereign-0.17.1/src/sovereign/discovery.py +0 -175
  89. sovereign-0.17.1/src/sovereign/logs.py +0 -131
  90. sovereign-0.17.1/src/sovereign/schemas.py +0 -776
  91. sovereign-0.17.1/src/sovereign/server.py +0 -32
  92. sovereign-0.17.1/src/sovereign/sources/__init__.py +0 -3
  93. sovereign-0.17.1/src/sovereign/sources/file.py +0 -21
  94. sovereign-0.17.1/src/sovereign/sources/inline.py +0 -38
  95. sovereign-0.17.1/src/sovereign/sources/lib.py +0 -40
  96. sovereign-0.17.1/src/sovereign/sources/poller.py +0 -298
  97. sovereign-0.17.1/src/sovereign/static/sass/style.scss +0 -27
  98. sovereign-0.17.1/src/sovereign/static/style.css +0 -13553
  99. sovereign-0.17.1/src/sovereign/templates/base.html +0 -64
  100. sovereign-0.17.1/src/sovereign/templates/resources.html +0 -159
  101. sovereign-0.17.1/src/sovereign/templates/ul_filter.html +0 -22
  102. sovereign-0.17.1/src/sovereign/utils/crypto.py +0 -103
  103. sovereign-0.17.1/src/sovereign/utils/mock.py +0 -35
  104. sovereign-0.17.1/src/sovereign/views/admin.py +0 -120
  105. sovereign-0.17.1/src/sovereign/views/crypto.py +0 -69
  106. sovereign-0.17.1/src/sovereign/views/discovery.py +0 -156
  107. sovereign-0.17.1/src/sovereign/views/healthchecks.py +0 -40
  108. sovereign-0.17.1/src/sovereign/views/interface.py +0 -205
  109. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/modifiers/__init__.py +0 -0
  110. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/templates/err.html +0 -0
  111. {sovereign-0.17.1 → sovereign-1.0.0a3}/src/sovereign/utils/__init__.py +0 -0
  112. {sovereign-0.17.1/src/sovereign/views → sovereign-1.0.0a3/src/sovereign/utils/crypto}/__init__.py +0 -0
@@ -1,13 +1,13 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: sovereign
3
- Version: 0.17.1
3
+ Version: 1.0.0a3
4
4
  Summary: Envoy Proxy control-plane written in Python
5
- Home-page: https://pypi.org/project/sovereign/
6
- License: Apache-2.0
7
- Keywords: envoy,envoyproxy,control-plane,management,server
8
- Author: Vasili Syrakis
9
- Author-email: vsyrakis@atlassian.com
10
- Requires-Python: >=3.8,<4.0
5
+ Project-URL: Homepage, https://pypi.org/project/sovereign/
6
+ Project-URL: Repository, https://bitbucket.org/atlassian/sovereign/src/master/
7
+ Project-URL: Documentation, https://developer.atlassian.com/platform/sovereign/
8
+ Author-email: Vasili Syrakis <vsyrakis@atlassian.com>
9
+ License-Expression: Apache-2.0
10
+ Keywords: control-plane,envoy,envoyproxy,management,server
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Environment :: No Input/Output (Daemon)
13
13
  Classifier: Intended Audience :: Developers
@@ -16,88 +16,103 @@ Classifier: Intended Audience :: System Administrators
16
16
  Classifier: License :: OSI Approved :: Apache Software License
17
17
  Classifier: Natural Language :: English
18
18
  Classifier: Operating System :: POSIX :: Linux
19
- Classifier: Programming Language :: Python :: 3
20
19
  Classifier: Programming Language :: Python :: 3.8
21
20
  Classifier: Programming Language :: Python :: 3.9
22
21
  Classifier: Programming Language :: Python :: 3.10
23
22
  Classifier: Programming Language :: Python :: 3.11
24
- Classifier: Programming Language :: Python :: 3.8
25
23
  Classifier: Topic :: Internet :: Proxy Servers
24
+ Requires-Python: <4.0,>=3.11.0
25
+ Requires-Dist: aiofiles<24,>=23.2.1
26
+ Requires-Dist: cachelib<0.11,>=0.10.2
27
+ Requires-Dist: cachetools<6,>=5.3.2
28
+ Requires-Dist: croniter<2,>=1.4.1
29
+ Requires-Dist: cryptography>=45.0.2
30
+ Requires-Dist: fastapi<0.129,>=0.128.0
31
+ Requires-Dist: glom<24,>=23.3.0
32
+ Requires-Dist: h11<0.17,>=0.16.0
33
+ Requires-Dist: jinja2<4,>=3.1.2
34
+ Requires-Dist: jmespath<2,>=1.0.1
35
+ Requires-Dist: pydantic-settings<2.6.0
36
+ Requires-Dist: pydantic<3,>=2.7.2
37
+ Requires-Dist: pyyaml<7,>=6.0.1
38
+ Requires-Dist: requests<3,>=2.32.4
39
+ Requires-Dist: rich>=14.2.0
40
+ Requires-Dist: starlette-context<0.4,>=0.3.6
41
+ Requires-Dist: starlette<0.50,>=0.49.1
42
+ Requires-Dist: structlog<24,>=23.1.0
43
+ Requires-Dist: supervisor<5,>=4.2.5
44
+ Requires-Dist: uvicorn<0.24,>=0.23.2
45
+ Requires-Dist: uvloop<1.0,>0.19.0
26
46
  Provides-Extra: boto
47
+ Requires-Dist: boto3<2,>=1.28.62; extra == 'boto'
27
48
  Provides-Extra: caching
49
+ Provides-Extra: httptools
50
+ Requires-Dist: httptools<0.7,>=0.6.0; extra == 'httptools'
28
51
  Provides-Extra: orjson
52
+ Requires-Dist: orjson<4,>=3.9.15; extra == 'orjson'
29
53
  Provides-Extra: sentry
54
+ Requires-Dist: sentry-sdk<3,>=2.14.0; extra == 'sentry'
30
55
  Provides-Extra: statsd
56
+ Requires-Dist: datadog>=0.50.1; extra == 'statsd'
31
57
  Provides-Extra: ujson
32
- Requires-Dist: Jinja2 (>=3.1.2,<4.0.0)
33
- Requires-Dist: PyYAML (>=5.4,<6.0)
34
- Requires-Dist: aiofiles (>=22.1.0,<23.0.0)
35
- Requires-Dist: boto3 (>=1.17.0,<2.0.0); extra == "boto"
36
- Requires-Dist: cachelib (>=0.1.1,<0.2.0)
37
- Requires-Dist: cashews[redis] (>=5.0.0,<6.0.0); extra == "caching"
38
- Requires-Dist: croniter (>=1.3.5,<2.0.0)
39
- Requires-Dist: cryptography (>=38.0.3,<39.0.0)
40
- Requires-Dist: datadog (>=0.39.0,<0.40.0); extra == "statsd"
41
- Requires-Dist: fastapi (>=0.88.0,<0.89.0)
42
- Requires-Dist: glom (>=20.11.0,<21.0.0)
43
- Requires-Dist: gunicorn (>=20.1.0,<21.0.0)
44
- Requires-Dist: orjson (>=3.4.7,<4.0.0); extra == "orjson"
45
- Requires-Dist: requests (>=2.28.1,<3.0.0)
46
- Requires-Dist: sentry-sdk (>=0.19.5,<0.20.0); extra == "sentry"
47
- Requires-Dist: structlog (==21.5.0)
48
- Requires-Dist: ujson (>=5.4.0,<6.0.0); extra == "ujson"
49
- Requires-Dist: uvicorn (>=0.20.0,<0.21.0)
50
- Requires-Dist: uvloop (>=0.17.0,<0.18.0)
51
- Project-URL: Documentation, https://vsyrakis.bitbucket.io/sovereign/docs/
52
- Project-URL: Repository, https://bitbucket.org/atlassian/sovereign/src/master/
58
+ Requires-Dist: ujson<6,>=5.8.0; extra == 'ujson'
53
59
  Description-Content-Type: text/markdown
54
60
 
55
61
  sovereign
56
62
  =========
57
63
 
64
+
58
65
  Mission statement
59
66
  -----------------
60
67
  This project implements a JSON control-plane based on the [envoy](https://envoyproxy.io) [data-plane-api](https://github.com/envoyproxy/data-plane-api)
61
68
 
62
- The purpose of `sovereign` is to supply downstream envoy proxies with
63
- configuration in near-realtime by responding to discovery requests.
69
+ The purpose of `sovereign` is to supply downstream envoy proxies with dynamic configuration.
70
+
64
71
 
65
72
  Mechanism of Operation
66
73
  ----------------------
67
- tl;dr version:
68
- ```
69
- * Polls HTTP/File/Other for data
70
- * (optional) Applies transforms to the data
71
- * Uses the data to generate Envoy configuration from templates
72
- ```
74
+ Sovereign allows you to define templates that represent each resource type
75
+ provided by Envoy. For example, clusters, routes, listeners, secrets,
76
+ extension_configs, etc.
73
77
 
74
- In a nutshell, Sovereign
75
- gathers contextual data (*"sources"* and *"template context"*),
76
- optionally applies transforms to that data (using *"modifiers"*) and finally
77
- uses the data to generate envoy configuration from either python code, or jinja2 templates.
78
+ In order to enrich the templates with data, Sovereign has ways of polling data
79
+ out-of-band which it then includes as variables that can be accessed within the
80
+ templates.
78
81
 
79
- This is performed in a semi-stateless way, where the only state is data cached in memory.
82
+ This allows Sovereign to provide configuration to Envoy that changes over time
83
+ depending on the data sources, without needing to redeploy the control-plane.
80
84
 
81
- Template context is intended to be statically configured, whereas *Sources*
82
- are meant to be dynamic - for example, fetching from an API, an S3 bucket,
83
- or a file that receives updates.
85
+ Sovereign provides some built-in ways of polling data (such as over HTTP, or
86
+ on-disk) but also exposes extension points, allowing you to write your own
87
+ plugins in Python.
84
88
 
85
- *Modifiers* can mutate the data retrieved from sources, just in case the data
86
- is in a less than favorable structure.
87
89
 
88
- Both modifiers and sources are pluggable, i.e. it's easy to write your own and
89
- plug them into Sovereign for your use-case.
90
+ Support
91
+ ------------
92
+ [Submit new issues here](https://bitbucket.org/atlassian/sovereign/issues/new)
93
+
94
+ If you're unable to submit an issue on Bitbucket, send an email to [vsyrakis@atlassian.com](mailto:vsyrakis@atlassian.com)
90
95
 
91
- Currently, Sovereign supports only providing configuration to Envoy as JSON.
92
- That is to say, gRPC is not supported yet. Contributions in this area are highly
93
- appreciated!
94
96
 
95
- The JSON configuration can be viewed in real-time with Sovereign's read-only web interface.
97
+ Release
98
+ ------------
99
+ See [RELEASE.md]
100
+
101
+
102
+ Roadmap
103
+ ------------
104
+ * Performance improvements
105
+ * Data persistence
106
+ * Push API (versus polling)
107
+ * Client for Sovereign
108
+ * gRPC
109
+
96
110
 
97
111
  Requirements
98
112
  ------------
99
113
  * Python 3.8+
100
114
 
115
+
101
116
  Installation
102
117
  ------------
103
118
  ```
@@ -106,62 +121,53 @@ pip install sovereign
106
121
 
107
122
  Documentation
108
123
  -------------
109
- [Read the docs here!](https://vsyrakis.bitbucket.io/sovereign/docs/)
110
-
111
- :new: Read-only user interface
112
- ------------------------
113
- Added in `v0.5.3`!
124
+ [Read the docs here!](https://developer.atlassian.com/platform/sovereign/)
114
125
 
115
- This interface allows you to browse the resources currently returned by Sovereign.
116
126
 
117
- ![Sovereign User Interface Screenshot](https://bitbucket.org/atlassian/sovereign/src/master/assets/sovereign_ui.png)
118
127
 
119
128
  Local development
120
129
  =================
121
130
 
131
+
122
132
  Requirements
123
133
  ------------
134
+ * uv
124
135
  * Docker
125
136
  * Docker-compose
126
137
 
138
+
127
139
  Installing dependencies for dev
128
140
  -------------------------------
129
- I recommend creating a virtualenv before doing any dev work
130
-
141
+ Dependencies and creation of virtualenv is handled by uv
131
142
  ```
132
- python3 -m venv venv
133
- source venv/bin/activate
134
- pip install -r requirements-dev.txt
143
+ uv sync
144
+ uv venv activate
145
+ uv run <command>
135
146
  ```
136
147
 
137
148
  Running locally
138
149
  ---------------
139
150
  Running the test env
140
-
141
151
  ```
142
152
  make run
143
153
  ```
144
154
 
145
155
  Running the test env daemonized
146
-
147
156
  ```
148
157
  make run-daemon
149
158
  ```
150
159
 
151
160
  Pylint
152
-
153
161
  ```
154
162
  make lint
155
163
  ```
156
164
 
157
165
  Unit tests
158
-
159
166
  ```
160
167
  make unit
161
168
  ```
162
169
 
163
170
  Acceptance tests
164
-
165
171
  ```
166
172
  make run-daemon acceptance
167
173
  ```
@@ -169,7 +175,6 @@ make run-daemon acceptance
169
175
 
170
176
  Contributors
171
177
  ============
172
-
173
178
  Pull requests, issues and comments welcome. For pull requests:
174
179
 
175
180
  * Add tests for new features and bug fixes
@@ -198,9 +203,7 @@ those contributing as an individual.
198
203
 
199
204
  License
200
205
  ========
201
-
202
206
  Copyright (c) 2018 Atlassian and others.
203
207
  Apache 2.0 licensed, see [LICENSE.txt](LICENSE.txt) file.
204
208
 
205
209
 
206
-
@@ -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
- configuration in near-realtime by responding to discovery requests.
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
- tl;dr version:
14
- ```
15
- * Polls HTTP/File/Other for data
16
- * (optional) Applies transforms to the data
17
- * Uses the data to generate Envoy configuration from templates
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
- In a nutshell, Sovereign
21
- gathers contextual data (*"sources"* and *"template context"*),
22
- optionally applies transforms to that data (using *"modifiers"*) and finally
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
- Template context is intended to be statically configured, whereas *Sources*
28
- are meant to be dynamic - for example, fetching from an API, an S3 bucket,
29
- or a file that receives updates.
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
- *Modifiers* can mutate the data retrieved from sources, just in case the data
32
- is in a less than favorable structure.
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
- Currently, Sovereign supports only providing configuration to Envoy as JSON.
38
- That is to say, gRPC is not supported yet. Contributions in this area are highly
39
- appreciated!
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,53 @@ pip install sovereign
52
61
 
53
62
  Documentation
54
63
  -------------
55
- [Read the docs here!](https://vsyrakis.bitbucket.io/sovereign/docs/)
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
- ![Sovereign User Interface Screenshot](https://bitbucket.org/atlassian/sovereign/src/master/assets/sovereign_ui.png)
64
67
 
65
68
  Local development
66
69
  =================
67
70
 
71
+
68
72
  Requirements
69
73
  ------------
74
+ * uv
70
75
  * Docker
71
76
  * Docker-compose
72
77
 
78
+
73
79
  Installing dependencies for dev
74
80
  -------------------------------
75
- I recommend creating a virtualenv before doing any dev work
76
-
81
+ Dependencies and creation of virtualenv is handled by uv
77
82
  ```
78
- python3 -m venv venv
79
- source venv/bin/activate
80
- pip install -r requirements-dev.txt
83
+ uv sync
84
+ uv venv activate
85
+ uv run <command>
81
86
  ```
82
87
 
83
88
  Running locally
84
89
  ---------------
85
90
  Running the test env
86
-
87
91
  ```
88
92
  make run
89
93
  ```
90
94
 
91
95
  Running the test env daemonized
92
-
93
96
  ```
94
97
  make run-daemon
95
98
  ```
96
99
 
97
100
  Pylint
98
-
99
101
  ```
100
102
  make lint
101
103
  ```
102
104
 
103
105
  Unit tests
104
-
105
106
  ```
106
107
  make unit
107
108
  ```
108
109
 
109
110
  Acceptance tests
110
-
111
111
  ```
112
112
  make run-daemon acceptance
113
113
  ```
@@ -115,7 +115,6 @@ make run-daemon acceptance
115
115
 
116
116
  Contributors
117
117
  ============
118
-
119
118
  Pull requests, issues and comments welcome. For pull requests:
120
119
 
121
120
  * Add tests for new features and bug fixes
@@ -144,7 +143,6 @@ those contributing as an individual.
144
143
 
145
144
  License
146
145
  ========
147
-
148
146
  Copyright (c) 2018 Atlassian and others.
149
147
  Apache 2.0 licensed, see [LICENSE.txt](LICENSE.txt) file.
150
148
 
@@ -0,0 +1,161 @@
1
+ [project]
2
+ name = "sovereign"
3
+ version = "1.0.0a3"
4
+ description = "Envoy Proxy control-plane written in Python"
5
+ authors = [{ name = "Vasili Syrakis", email = "vsyrakis@atlassian.com" }]
6
+ requires-python = ">=3.11.0, <4.0"
7
+ readme = "README.md"
8
+ license = "Apache-2.0"
9
+ keywords = [
10
+ "envoy",
11
+ "envoyproxy",
12
+ "control-plane",
13
+ "management",
14
+ "server",
15
+ ]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Environment :: No Input/Output (Daemon)",
19
+ "Intended Audience :: Developers",
20
+ "Intended Audience :: Information Technology",
21
+ "Intended Audience :: System Administrators",
22
+ "License :: OSI Approved :: Apache Software License",
23
+ "Natural Language :: English",
24
+ "Operating System :: POSIX :: Linux",
25
+ "Programming Language :: Python :: 3.8",
26
+ "Programming Language :: Python :: 3.9",
27
+ "Programming Language :: Python :: 3.10",
28
+ "Programming Language :: Python :: 3.11",
29
+ "Topic :: Internet :: Proxy Servers",
30
+ ]
31
+ dependencies = [
32
+ "uvicorn>=0.23.2,<0.24",
33
+ "aiofiles>=23.2.1,<24",
34
+ "requests>=2.32.4,<3",
35
+ "PyYAML>=6.0.1,<7",
36
+ "Jinja2>=3.1.2,<4",
37
+ "structlog>=23.1.0,<24",
38
+ "cachelib>=0.10.2,<0.11",
39
+ "glom>=23.3.0,<24",
40
+ "cryptography>=45.0.2",
41
+ "fastapi>=0.128.0,<0.129",
42
+ "uvloop>0.19.0,<1.0",
43
+ "croniter>=1.4.1,<2",
44
+ "cachetools>=5.3.2,<6",
45
+ "pydantic>=2.7.2,<3",
46
+ "pydantic-settings<2.6.0",
47
+ "starlette-context>=0.3.6,<0.4",
48
+ "starlette>=0.49.1,<0.50",
49
+ "h11>=0.16.0,<0.17",
50
+ "supervisor>=4.2.5,<5",
51
+ "jmespath>=1.0.1,<2",
52
+ "rich>=14.2.0",
53
+ ]
54
+
55
+ [project.optional-dependencies]
56
+ sentry = ["sentry-sdk>=2.14.0,<3"]
57
+ boto = ["boto3>=1.28.62,<2"]
58
+ statsd = ["datadog>=0.50.1"]
59
+ ujson = ["ujson>=5.8.0,<6"]
60
+ orjson = ["orjson>=3.9.15,<4"]
61
+ caching = []
62
+ httptools = ["httptools>=0.6.0,<0.7"]
63
+
64
+ [project.urls]
65
+ Homepage = "https://pypi.org/project/sovereign/"
66
+ Repository = "https://bitbucket.org/atlassian/sovereign/src/master/"
67
+ Documentation = "https://developer.atlassian.com/platform/sovereign/"
68
+
69
+ [project.scripts]
70
+ sovereign = "sovereign.server:main"
71
+ sovereign-web = "sovereign.server:web"
72
+ sovereign-worker = "sovereign.server:worker"
73
+
74
+ [project.entry-points."sovereign.sources"]
75
+ file = "sovereign.sources.file:File"
76
+ inline = "sovereign.sources.inline:Inline"
77
+
78
+ [project.entry-points."sovereign.modifiers"]
79
+ sovereign_3rd_party_test = "sovereign.testing.modifiers:Test"
80
+
81
+ [project.entry-points."sovereign.loaders"]
82
+ example = "sovereign.testing.loaders:Multiply"
83
+ file = "sovereign.dynamic_config.loaders:File"
84
+ pkgdata = "sovereign.dynamic_config.loaders:PackageData"
85
+ http = "sovereign.dynamic_config.loaders:Web"
86
+ https = "sovereign.dynamic_config.loaders:Web"
87
+ env = "sovereign.dynamic_config.loaders:EnvironmentVariable"
88
+ module = "sovereign.dynamic_config.loaders:PythonModule"
89
+ s3 = "sovereign.dynamic_config.loaders:S3Bucket"
90
+ python = "sovereign.dynamic_config.loaders:PythonInlineCode"
91
+ inline = "sovereign.dynamic_config.loaders:Inline"
92
+
93
+ [project.entry-points."sovereign.deserializers"]
94
+ yaml = "sovereign.dynamic_config.deser:YamlDeserializer"
95
+ json = "sovereign.dynamic_config.deser:JsonDeserializer"
96
+ jinja = "sovereign.dynamic_config.deser:JinjaDeserializer"
97
+ jinja2 = "sovereign.dynamic_config.deser:JinjaDeserializer"
98
+ string = "sovereign.dynamic_config.deser:StringDeserializer"
99
+ raw = "sovereign.dynamic_config.deser:PassthroughDeserializer"
100
+ none = "sovereign.dynamic_config.deser:PassthroughDeserializer"
101
+ passthrough = "sovereign.dynamic_config.deser:PassthroughDeserializer"
102
+ ujson = "sovereign.dynamic_config.deser:UjsonDeserializer"
103
+ orjson = "sovereign.dynamic_config.deser:OrjsonDeserializer"
104
+
105
+ [project.entry-points."sovereign.cache.backends"]
106
+ s3 = "sovereign.cache.backends.s3:S3Backend"
107
+
108
+ [project.entry-points."sovereign.data_stores"]
109
+ memory = "sovereign.v2.data.data_store:InMemoryDataStore"
110
+ sqlite = "sovereign.v2.data.data_store:SqliteDataStore"
111
+
112
+ [project.entry-points."sovereign.queues"]
113
+ memory = "sovereign.v2.data.worker_queue:InMemoryQueue"
114
+ sqlite = "sovereign.v2.data.worker_queue:SqliteQueue"
115
+
116
+ [dependency-groups]
117
+ dev = [
118
+ "freezegun",
119
+ "httpx",
120
+ "moto>=5.0.0",
121
+ "pytest-asyncio",
122
+ "pytest-mock",
123
+ "ruff",
124
+ "tavern",
125
+ "toml",
126
+ "ty",
127
+ "ty==0.0.1a26",
128
+ "types-PyYAML",
129
+ "types-cachetools",
130
+ "types-croniter",
131
+ "types-mock>=5.2.0.20250306,<6",
132
+ "types-requests",
133
+ "types-setuptools",
134
+ "types-ujson",
135
+ ]
136
+
137
+ [tool.hatch.build.targets.sdist]
138
+ include = [
139
+ "src/sovereign",
140
+ "src/sovereign_files",
141
+ "src/sovereign_files/**/*",
142
+ ]
143
+
144
+ [tool.hatch.build.targets.wheel]
145
+ include = [
146
+ "src/sovereign",
147
+ "src/sovereign_files",
148
+ "src/sovereign_files/**/*",
149
+ ]
150
+
151
+ [tool.hatch.build.targets.wheel.sources]
152
+ "src/sovereign" = "sovereign"
153
+ "src/sovereign_files" = "sovereign_files"
154
+
155
+ [[tool.uv.index]]
156
+ url = "https://pypi.org/simple"
157
+ default = true
158
+
159
+ [build-system]
160
+ requires = ["hatchling"]
161
+ build-backend = "hatchling.build"
@@ -0,0 +1,32 @@
1
+ from contextvars import ContextVar
2
+ from importlib.metadata import version
3
+
4
+ from sovereign.configuration import EncryptionConfig, config
5
+ from sovereign.logging.bootstrapper import LoggerBootstrapper
6
+ from sovereign.statistics import configure_statsd
7
+ from sovereign.utils.crypto.crypto import CipherContainer
8
+ from sovereign.utils.crypto.suites import EncryptionType
9
+
10
+ _request_id_ctx_var: ContextVar[str] = ContextVar("request_id", default="")
11
+
12
+
13
+ def get_request_id() -> str:
14
+ return _request_id_ctx_var.get()
15
+
16
+
17
+ WORKER_URL = "http://localhost:9080"
18
+ DIST_NAME = "sovereign"
19
+ __version__ = version(DIST_NAME)
20
+
21
+ stats = configure_statsd()
22
+ logs = LoggerBootstrapper(config)
23
+ application_logger = logs.application_logger.logger
24
+
25
+ encryption_configs = config.authentication.encryption_configs
26
+ server_cipher_container = CipherContainer.from_encryption_configs(
27
+ encryption_configs, logger=application_logger
28
+ )
29
+ disabled_ciphersuite = CipherContainer.from_encryption_configs(
30
+ encryption_configs=[EncryptionConfig("", EncryptionType.DISABLED)],
31
+ logger=application_logger,
32
+ )