sovereign 0.19.3__py3-none-any.whl → 1.0.0b148__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.

Files changed (80) hide show
  1. sovereign/__init__.py +13 -81
  2. sovereign/app.py +59 -48
  3. sovereign/cache/__init__.py +172 -0
  4. sovereign/cache/backends/__init__.py +110 -0
  5. sovereign/cache/backends/s3.py +143 -0
  6. sovereign/cache/filesystem.py +73 -0
  7. sovereign/cache/types.py +15 -0
  8. sovereign/configuration.py +573 -0
  9. sovereign/constants.py +1 -0
  10. sovereign/context.py +271 -104
  11. sovereign/dynamic_config/__init__.py +113 -0
  12. sovereign/dynamic_config/deser.py +78 -0
  13. sovereign/dynamic_config/loaders.py +120 -0
  14. sovereign/events.py +49 -0
  15. sovereign/logging/access_logger.py +85 -0
  16. sovereign/logging/application_logger.py +54 -0
  17. sovereign/logging/base_logger.py +41 -0
  18. sovereign/logging/bootstrapper.py +36 -0
  19. sovereign/logging/types.py +10 -0
  20. sovereign/middlewares.py +8 -7
  21. sovereign/modifiers/lib.py +1 -0
  22. sovereign/rendering.py +192 -0
  23. sovereign/response_class.py +18 -0
  24. sovereign/server.py +93 -35
  25. sovereign/sources/file.py +1 -1
  26. sovereign/sources/inline.py +1 -0
  27. sovereign/sources/lib.py +1 -0
  28. sovereign/sources/poller.py +296 -53
  29. sovereign/statistics.py +17 -20
  30. sovereign/templates/base.html +59 -46
  31. sovereign/templates/resources.html +203 -102
  32. sovereign/testing/loaders.py +8 -0
  33. sovereign/{modifiers/test.py → testing/modifiers.py} +0 -2
  34. sovereign/tracing.py +102 -0
  35. sovereign/types.py +299 -0
  36. sovereign/utils/auth.py +26 -13
  37. sovereign/utils/crypto/__init__.py +0 -0
  38. sovereign/utils/crypto/crypto.py +135 -0
  39. sovereign/utils/crypto/suites/__init__.py +21 -0
  40. sovereign/utils/crypto/suites/aes_gcm_cipher.py +42 -0
  41. sovereign/utils/crypto/suites/base_cipher.py +21 -0
  42. sovereign/utils/crypto/suites/disabled_cipher.py +25 -0
  43. sovereign/utils/crypto/suites/fernet_cipher.py +29 -0
  44. sovereign/utils/dictupdate.py +2 -1
  45. sovereign/utils/eds.py +37 -21
  46. sovereign/utils/mock.py +54 -16
  47. sovereign/utils/resources.py +17 -0
  48. sovereign/utils/version_info.py +8 -0
  49. sovereign/views/__init__.py +4 -0
  50. sovereign/views/api.py +61 -0
  51. sovereign/views/crypto.py +46 -15
  52. sovereign/views/discovery.py +37 -116
  53. sovereign/views/healthchecks.py +87 -18
  54. sovereign/views/interface.py +112 -112
  55. sovereign/worker.py +204 -0
  56. {sovereign-0.19.3.dist-info → sovereign-1.0.0b148.dist-info}/METADATA +79 -76
  57. sovereign-1.0.0b148.dist-info/RECORD +77 -0
  58. {sovereign-0.19.3.dist-info → sovereign-1.0.0b148.dist-info}/WHEEL +1 -1
  59. sovereign-1.0.0b148.dist-info/entry_points.txt +38 -0
  60. sovereign_files/__init__.py +0 -0
  61. sovereign_files/static/darkmode.js +51 -0
  62. sovereign_files/static/node_expression.js +42 -0
  63. sovereign_files/static/panel.js +76 -0
  64. sovereign_files/static/resources.css +246 -0
  65. sovereign_files/static/resources.js +642 -0
  66. sovereign_files/static/sass/style.scss +33 -0
  67. sovereign_files/static/style.css +16143 -0
  68. sovereign_files/static/style.css.map +1 -0
  69. sovereign/config_loader.py +0 -225
  70. sovereign/discovery.py +0 -175
  71. sovereign/logs.py +0 -131
  72. sovereign/schemas.py +0 -780
  73. sovereign/static/sass/style.scss +0 -27
  74. sovereign/static/style.css +0 -13553
  75. sovereign/templates/ul_filter.html +0 -22
  76. sovereign/utils/crypto.py +0 -103
  77. sovereign/views/admin.py +0 -120
  78. sovereign-0.19.3.dist-info/LICENSE.txt +0 -13
  79. sovereign-0.19.3.dist-info/RECORD +0 -47
  80. sovereign-0.19.3.dist-info/entry_points.txt +0 -10
@@ -1,22 +0,0 @@
1
- <script>
2
- function filter_results(id, list) {
3
- // Declare variables
4
- let input, filter, container, iterable, resource, i, txtValue;
5
- input = document.getElementById(id);
6
- filter = input.value.toUpperCase();
7
-
8
- container = document.getElementById(list);
9
- iterable = container.getElementsByTagName("a");
10
-
11
- // Loop through all list items, and hide those who don't match the search query
12
- for (i = 0; i < iterable.length; i++) {
13
- resource = iterable[i];
14
- txtValue = resource.textContent;
15
- if (txtValue.toUpperCase().indexOf(filter) > -1) {
16
- iterable[i].style.display = "";
17
- } else {
18
- iterable[i].style.display = "none";
19
- }
20
- }
21
- }
22
- </script>
sovereign/utils/crypto.py DELETED
@@ -1,103 +0,0 @@
1
- from functools import partial
2
- from collections import namedtuple
3
- from typing import Optional, Any, List
4
- from cryptography.fernet import Fernet, InvalidToken
5
- from fastapi.exceptions import HTTPException
6
-
7
-
8
- CipherSuite = namedtuple("CipherSuite", "encrypt decrypt key_available")
9
-
10
-
11
- class CipherContainer:
12
- """
13
- Object which intercepts encrypt/decryptions
14
- Tries to decrypt data using the ciphers provided in order
15
- Encrypts with the first suite available.
16
- """
17
-
18
- def __init__(self, suites: List[CipherSuite]) -> None:
19
- self.suites = suites
20
-
21
- def encrypt(self, data: str, key: Optional[str] = None) -> str:
22
- if key is not None:
23
- return encrypt(Fernet(key.encode()), data)
24
- return self.suites[0].encrypt(data) # type: ignore
25
-
26
- def decrypt(self, data: str, key: Optional[str] = None) -> str:
27
- if key is not None:
28
- return decrypt(Fernet(key.encode()), data)
29
- success = False
30
- decrypted = None
31
- error = ValueError("Unable to decrypt value, unknown error")
32
- for suite in self.suites:
33
- try:
34
- decrypted = suite.decrypt(data)
35
- success = True
36
- break
37
- except (InvalidToken, AttributeError, HTTPException) as e:
38
- error = e # type: ignore
39
- continue
40
- if not success:
41
- raise error
42
- else:
43
- return decrypted # type: ignore
44
-
45
- @property
46
- def key_available(self) -> bool:
47
- return self.suites[0].key_available # type: ignore
48
-
49
-
50
- class DisabledSuite:
51
- @staticmethod
52
- def encrypt(_: bytes) -> bytes:
53
- return b"Unavailable (No Secret Key)"
54
-
55
- @staticmethod
56
- def decrypt(*_: bytes) -> str:
57
- return "Unavailable (No Secret Key)"
58
-
59
-
60
- def create_cipher_suite(key: bytes, logger: Any) -> CipherSuite:
61
- try:
62
- fernet = Fernet(key)
63
- return CipherSuite(partial(encrypt, fernet), partial(decrypt, fernet), True)
64
- except TypeError:
65
- pass
66
- except ValueError as e:
67
- if key not in (b"", ""):
68
- logger.application_log(
69
- event=f"Fernet key was provided, but appears to be invalid: {repr(e)}"
70
- )
71
- return CipherSuite(DisabledSuite.encrypt, DisabledSuite.decrypt, False)
72
-
73
-
74
- def generate_key() -> str:
75
- secret: bytes = Fernet.generate_key()
76
- return secret.decode()
77
-
78
-
79
- def encrypt(cipher_suite: Fernet, data: str, key: Optional[str] = None) -> str:
80
- _local_cipher_suite = cipher_suite
81
- if isinstance(key, str):
82
- _local_cipher_suite = Fernet(key.encode())
83
- try:
84
- encrypted: bytes = _local_cipher_suite.encrypt(data.encode())
85
- except (InvalidToken, AttributeError):
86
- # TODO: defer this http error to later, return a normal error here
87
- raise HTTPException(status_code=400, detail="Encryption failed")
88
- return encrypted.decode()
89
-
90
-
91
- def decrypt(cipher_suite: Fernet, data: str, key: Optional[str] = None) -> str:
92
- _local_cipher_suite = cipher_suite
93
- if key is not None:
94
- _local_cipher_suite = Fernet(key.encode())
95
- try:
96
- decrypted = _local_cipher_suite.decrypt(data.encode())
97
- except (InvalidToken, AttributeError):
98
- # TODO: defer this http error to later, return a normal error here
99
- raise HTTPException(status_code=400, detail="Decryption failed")
100
- if isinstance(decrypted, bytes):
101
- return decrypted.decode()
102
- else:
103
- return decrypted
sovereign/views/admin.py DELETED
@@ -1,120 +0,0 @@
1
- import yaml
2
- from typing import Any, Dict, List
3
- from collections import defaultdict
4
- from fastapi import APIRouter, Query
5
- from fastapi.responses import JSONResponse
6
- from fastapi.encoders import jsonable_encoder
7
- from sovereign import config, stats, poller, template_context
8
- from sovereign.discovery import select_template
9
- from sovereign.schemas import Resources
10
- from sovereign.utils.mock import mock_discovery_request
11
- from sovereign.views.discovery import perform_discovery
12
-
13
- router = APIRouter()
14
-
15
-
16
- @router.get("/xds_dump", summary="Displays all xDS resources as JSON")
17
- async def display_config(
18
- xds_type: str = Query(
19
- ..., title="xDS type", description="The type of request", example="clusters"
20
- ),
21
- service_cluster: str = Query(
22
- "*", title="The clients service cluster to emulate in this XDS request"
23
- ),
24
- resource_names: List[str] = Query([], title="Envoy Resource names to request"),
25
- region: str = Query(
26
- None, title="The clients region to emulate in this XDS request"
27
- ),
28
- version: str = Query(
29
- "1.11.1", title="The clients envoy version to emulate in this XDS request"
30
- ),
31
- ) -> JSONResponse:
32
- ret: Dict[str, List[Dict[str, Any]]] = defaultdict(list)
33
- mock_request = mock_discovery_request(
34
- service_cluster=service_cluster,
35
- resource_names=Resources(resource_names),
36
- version=version,
37
- region=region,
38
- )
39
- response = await perform_discovery(mock_request, "v3", xds_type, skip_auth=True)
40
- ret["resources"] += response.resources
41
- safe_response = jsonable_encoder(ret)
42
- return JSONResponse(content=safe_response)
43
-
44
-
45
- @router.get(
46
- "/debug_template",
47
- summary="Dumps raw representation of template output before serialization/extra processing",
48
- )
49
- async def debug_template(
50
- xds_type: str = Query(
51
- ..., title="xDS type", description="The type of request", example="clusters"
52
- ),
53
- service_cluster: str = Query(
54
- "*", title="The clients service cluster to emulate in this XDS request"
55
- ),
56
- resource_names: str = Query("", title="Envoy Resource names to request"),
57
- region: str = Query(
58
- None, title="The clients region to emulate in this XDS request"
59
- ),
60
- version: str = Query(
61
- "1.11.1", title="The clients envoy version to emulate in this XDS request"
62
- ),
63
- ) -> JSONResponse:
64
- mock_request = mock_discovery_request(
65
- service_cluster=service_cluster,
66
- resource_names=resource_names.split(","),
67
- version=version,
68
- region=region,
69
- )
70
- template = select_template(mock_request, xds_type)
71
- context = template_context.get_context(mock_request, template)
72
- context = dict(
73
- discovery_request=mock_request,
74
- host_header="debug",
75
- resource_names=mock_request.resources,
76
- **context,
77
- )
78
- raw_template_content = template(**context)
79
- safe_response = jsonable_encoder(raw_template_content)
80
- return JSONResponse(content=safe_response)
81
-
82
-
83
- @router.get(
84
- "/source_dump",
85
- summary="Displays all sources that this Sovereign has polled as JSON",
86
- )
87
- def instances(
88
- service_cluster: str = Query(
89
- "*", title="The clients service cluster to emulate in this XDS request"
90
- ),
91
- modified: str = Query(
92
- "yes",
93
- title="Whether the sources should run Modifiers/Global Modifiers prior to being returned",
94
- ),
95
- ) -> JSONResponse:
96
- node = mock_discovery_request(service_cluster=service_cluster).node
97
- args = {
98
- "modify": yaml.safe_load(modified),
99
- "node_value": poller.extract_node_key(node),
100
- }
101
- ret = poller.match_node(**args)
102
- safe_response = jsonable_encoder(ret)
103
- return JSONResponse(content=safe_response)
104
-
105
-
106
- @router.get("/config", summary="Display the current Sovereign configuration")
107
- def show_configuration() -> JSONResponse:
108
- safe_response = jsonable_encoder(config.show())
109
- return JSONResponse(content=safe_response)
110
-
111
-
112
- @router.get("/stats", summary="Displays all metrics emitted and their counters")
113
- def show_stats() -> JSONResponse:
114
- return JSONResponse(content=stats.emitted)
115
-
116
-
117
- @router.get("/templates", summary="Display the currently loaded XDS templates")
118
- def show_templates() -> JSONResponse:
119
- safe_response = jsonable_encoder(config.xds_templates())
120
- return JSONResponse(content=safe_response)
@@ -1,13 +0,0 @@
1
- Copyright @ 2018 Atlassian Pty Ltd
2
-
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
-
7
- http://www.apache.org/licenses/LICENSE-2.0
8
-
9
- Unless required by applicable law or agreed to in writing, software
10
- distributed under the License is distributed on an "AS IS" BASIS,
11
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- See the License for the specific language governing permissions and
13
- limitations under the License.
@@ -1,47 +0,0 @@
1
- sovereign/__init__.py,sha256=OqRozdp92NTV_6pbYNtyXsTAHxkpHTpxslhNgcrXuNY,3136
2
- sovereign/app.py,sha256=z5dT5wdVNeAQap5ORRmnLpJstb1euWoj4vXZPrMttNs,4017
3
- sovereign/config_loader.py,sha256=siuXN6T62Lx3JzMchnEBZ7ZDuSCFH73oWuUk-oTOVQQ,6382
4
- sovereign/context.py,sha256=VswYtHZNcRMMT-Dlx9CBTxLo398uRXUPl6N--VcqybE,4411
5
- sovereign/discovery.py,sha256=EIghvk_HMYp14WzEG1aQhnsoGcLXMWSrCncPobJST4c,5885
6
- sovereign/error_info.py,sha256=r2KXBYq9Fo7AI2pmIpATWFm0pykr2MqfrKH0WWW5Sfk,1488
7
- sovereign/logs.py,sha256=DZK6F3LMxhch96qFasdXA6NPlQHJcKbjD83_S8W6Rds,4340
8
- sovereign/middlewares.py,sha256=LMSNISF0nZEzSVVsRHbpC0BIH51iz0G1hkG1sQEEhtw,3026
9
- sovereign/modifiers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- sovereign/modifiers/lib.py,sha256=DbXsxrrjnFE4Y7rbwpeiM5tS5w5NBwSdYH58AtDTP0I,2884
11
- sovereign/modifiers/test.py,sha256=7_c2hWXn_sYJ6997N1_uSWtClOikcOzu1yRCY56-l-4,361
12
- sovereign/schemas.py,sha256=qznxevQs3il4H9w0H4q1H26Jr2Dt3hyCTlbXX5fkgvM,27383
13
- sovereign/server.py,sha256=z8Uz1UYIZix0S40Srk774WIMDN2jl2SozO8irib0wc4,1402
14
- sovereign/sources/__init__.py,sha256=g9hEpFk8j5i1ApHQpbc9giTyJW41Ppgsqv5P9zGxOJk,78
15
- sovereign/sources/file.py,sha256=A4UWoRU39v2Ex5Mtdl_uw53iMkslYylF4CiiwW7LOpk,689
16
- sovereign/sources/inline.py,sha256=bNqVZyelcUofYBWHFOUIhOUU9az32CdBEfaYRzNzFFE,1002
17
- sovereign/sources/lib.py,sha256=LIbnlKkL0bQT10y4GT2E8yypjYxqfJYbB9FkGB5C2oc,1030
18
- sovereign/sources/poller.py,sha256=EapfyFI7XSZDKIc3lu3QgWhJmm-iEMTREmOvlWKYa8k,10939
19
- sovereign/static/sass/style.scss,sha256=tPHPEm3sZeBFGDyyn3pHcA-nbaKT-h-UsSTsf6dHNDU,1158
20
- sovereign/static/style.css,sha256=vG8HPsbCbPIZfHgy7gSeof97Pnp0okkyaXyJzIEEW-8,447517
21
- sovereign/statistics.py,sha256=Xfj4oWMfCkbYc2ibF7rDUpbw6Zw6dI4N5BpCLDQc4j4,2336
22
- sovereign/templates/base.html,sha256=5vw3-NmN291pXRdArpCwhSce9bAYBWCJVRhvO5EmE9g,2296
23
- sovereign/templates/err.html,sha256=a3cEzOqyqWOIe3YxfTEjkxbTfxBxq1knD6GwzEFljfs,603
24
- sovereign/templates/resources.html,sha256=NnrnamWg_vJjY88efsMcjNsldg-K9TZnp6tFS5tkZOU,6366
25
- sovereign/templates/ul_filter.html,sha256=LrzZv5408Qq5UP4lcHVRwY2G6lXd3IiSNiJn1aH7Yqo,666
26
- sovereign/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- sovereign/utils/auth.py,sha256=9rruWP-Ok8ec9l_MzWY3oUZKI8s7jt0Dmx3kHWnTRgQ,1772
28
- sovereign/utils/crypto.py,sha256=jNM3YRgdkxmTEeEDftkXnn33rr2qmT1-_3n3DUUdzRE,3438
29
- sovereign/utils/dictupdate.py,sha256=JkDjg16u7sW6A_4Q2oX1PY_MtJU7m1VivZWn9VLZ9V8,2559
30
- sovereign/utils/eds.py,sha256=3NwvQpFMxeWJ8pT1XhzqikrgT26HjObms4Ieh3hivOM,3894
31
- sovereign/utils/entry_point_loader.py,sha256=BEVodk-um70RvT1nSOu_IB-hr1K4ppthXod0VZEiZJ8,526
32
- sovereign/utils/mock.py,sha256=s2LS8RzGjwIqsgDPQnpQs6W39hehq88II0dOefvoq0w,1342
33
- sovereign/utils/templates.py,sha256=FE_H_oE7VrS3X_VN1z_g10b9-rpmi1_gL-cMxi5XtXU,1057
34
- sovereign/utils/timer.py,sha256=_dUtEasj0BKbWYuQ_T3HFIyjurXXj-La-dNSMAwKMSo,795
35
- sovereign/utils/version_info.py,sha256=vbAiUyz6v3-zSOoS-7HwrvJie729RgIKy0Bt091Z6RE,349
36
- sovereign/utils/weighted_clusters.py,sha256=bPzuRE7Qgvv04HcR2AhMDvBrFlZ8AfteweLKhY9SvWg,1166
37
- sovereign/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- sovereign/views/admin.py,sha256=GtjSipSfLwrvU1axX3pJfJXiSO82e2pkw8izykZNtGA,4306
39
- sovereign/views/crypto.py,sha256=nxp6bkPU9GZw_zOk0fsJdz_XRQPXxPI6cXQDL9-cigU,2041
40
- sovereign/views/discovery.py,sha256=dPX0auMsQCCura7eIq-jEGQoS92Avs9QPAsPGDjWL5I,5902
41
- sovereign/views/healthchecks.py,sha256=_WkMunlrFpqGTLgtNtRr7gCsDCv5kiuYxCyTi-dMEKM,1357
42
- sovereign/views/interface.py,sha256=Y2fbR26cSF8eKQHfTbnv5WKEdgqaGNwys0lEGUTjXqw,7041
43
- sovereign-0.19.3.dist-info/LICENSE.txt,sha256=2X125zvAb9AYLjCgdMDQZuufhm0kwcg31A8pGKj_-VY,560
44
- sovereign-0.19.3.dist-info/METADATA,sha256=8Khff52oVMKs6VgKzr-EBmgprHZUu8d7awi4WS8i4kE,6282
45
- sovereign-0.19.3.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
46
- sovereign-0.19.3.dist-info/entry_points.txt,sha256=kOn848ucVbNvtsGABDuwzOHmNiOb0Ey8dV85Z3dLv3Y,222
47
- sovereign-0.19.3.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- [console_scripts]
2
- sovereign=sovereign.server:main
3
-
4
- [sovereign.modifiers]
5
- sovereign_3rd_party_test=sovereign.modifiers.test:Test
6
-
7
- [sovereign.sources]
8
- file=sovereign.sources.file:File
9
- inline=sovereign.sources.inline:Inline
10
-