sovereign 0.23.0__tar.gz → 0.24.1__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.23.0 → sovereign-0.24.1}/PKG-INFO +14 -14
- {sovereign-0.23.0 → sovereign-0.24.1}/pyproject.toml +29 -29
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/__init__.py +2 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/configuration.py +2 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/context.py +80 -23
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/schemas.py +6 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/LICENSE.txt +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/README.md +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/app.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/config_loader.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/constants.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/discovery.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/error_info.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/logging/access_logger.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/logging/application_logger.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/logging/base_logger.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/logging/bootstrapper.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/logging/types.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/middlewares.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/modifiers/__init__.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/modifiers/lib.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/modifiers/test.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/response_class.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/server.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/sources/__init__.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/sources/file.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/sources/inline.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/sources/lib.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/sources/poller.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/static/sass/style.scss +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/static/style.css +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/statistics.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/templates/base.html +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/templates/err.html +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/templates/resources.html +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/templates/ul_filter.html +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/__init__.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/auth.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/crypto.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/dictupdate.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/eds.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/entry_point_loader.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/mock.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/resources.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/templates.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/timer.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/version_info.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/utils/weighted_clusters.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/__init__.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/admin.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/crypto.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/discovery.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/healthchecks.py +0 -0
- {sovereign-0.23.0 → sovereign-0.24.1}/src/sovereign/views/interface.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sovereign
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.1
|
|
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
|
|
@@ -29,23 +29,23 @@ Provides-Extra: statsd
|
|
|
29
29
|
Provides-Extra: ujson
|
|
30
30
|
Requires-Dist: Jinja2 (>=3.1.2,<4.0.0)
|
|
31
31
|
Requires-Dist: PyYAML (>=6.0.1,<7.0.0)
|
|
32
|
-
Requires-Dist: aiofiles (>=23.1
|
|
33
|
-
Requires-Dist: boto3 (>=1.
|
|
32
|
+
Requires-Dist: aiofiles (>=23.2.1,<24.0.0)
|
|
33
|
+
Requires-Dist: boto3 (>=1.28.62,<2.0.0) ; extra == "boto"
|
|
34
34
|
Requires-Dist: cachelib (>=0.10.2,<0.11.0)
|
|
35
|
-
Requires-Dist: cashews[redis] (>=6.
|
|
36
|
-
Requires-Dist: croniter (>=1.
|
|
37
|
-
Requires-Dist: cryptography (>=41.0.
|
|
38
|
-
Requires-Dist: datadog (>=0.
|
|
39
|
-
Requires-Dist: fastapi (>=0.
|
|
35
|
+
Requires-Dist: cashews[redis] (>=6.3.0,<7.0.0) ; extra == "caching"
|
|
36
|
+
Requires-Dist: croniter (>=1.4.1,<2.0.0)
|
|
37
|
+
Requires-Dist: cryptography (>=41.0.4,<42.0.0)
|
|
38
|
+
Requires-Dist: datadog (>=0.47.0,<0.48.0) ; extra == "statsd"
|
|
39
|
+
Requires-Dist: fastapi (>=0.99.1,<0.100.0)
|
|
40
40
|
Requires-Dist: glom (>=23.3.0,<24.0.0)
|
|
41
|
-
Requires-Dist: gunicorn (>=
|
|
42
|
-
Requires-Dist: httptools (>=0.
|
|
43
|
-
Requires-Dist: orjson (>=3.
|
|
44
|
-
Requires-Dist: requests (>=2.
|
|
41
|
+
Requires-Dist: gunicorn (>=21.2.0,<22.0.0)
|
|
42
|
+
Requires-Dist: httptools (>=0.6.0,<0.7.0) ; extra == "httptools"
|
|
43
|
+
Requires-Dist: orjson (>=3.9.7,<4.0.0) ; extra == "orjson"
|
|
44
|
+
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
45
45
|
Requires-Dist: sentry-sdk (>=1.23.1,<2.0.0) ; extra == "sentry"
|
|
46
46
|
Requires-Dist: structlog (>=23.1.0,<24.0.0)
|
|
47
|
-
Requires-Dist: ujson (>=5.
|
|
48
|
-
Requires-Dist: uvicorn (>=0.
|
|
47
|
+
Requires-Dist: ujson (>=5.8.0,<6.0.0) ; extra == "ujson"
|
|
48
|
+
Requires-Dist: uvicorn (>=0.23.2,<0.24.0)
|
|
49
49
|
Requires-Dist: uvloop (>=0.17.0,<0.18.0)
|
|
50
50
|
Project-URL: Documentation, https://vsyrakis.bitbucket.io/sovereign/docs/
|
|
51
51
|
Project-URL: Repository, https://bitbucket.org/atlassian/sovereign/src/master/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "sovereign"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.24.1"
|
|
4
4
|
description = "Envoy Proxy control-plane written in Python"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
packages = [
|
|
@@ -38,26 +38,26 @@ sovereign = 'sovereign.server:main'
|
|
|
38
38
|
|
|
39
39
|
[tool.poetry.dependencies]
|
|
40
40
|
python = "^3.11"
|
|
41
|
-
uvicorn = "^0.
|
|
42
|
-
gunicorn = "^
|
|
43
|
-
aiofiles = "^23.1
|
|
44
|
-
requests = "^2.
|
|
41
|
+
uvicorn = "^0.23.2"
|
|
42
|
+
gunicorn = "^21.2.0"
|
|
43
|
+
aiofiles = "^23.2.1"
|
|
44
|
+
requests = "^2.31.0"
|
|
45
45
|
PyYAML = "^6.0.1"
|
|
46
46
|
Jinja2 = "^3.1.2"
|
|
47
47
|
structlog = "^23.1.0"
|
|
48
48
|
cachelib = "^0.10.2"
|
|
49
49
|
glom = "^23.3.0"
|
|
50
|
-
cryptography = "^41.0.
|
|
51
|
-
fastapi = "^0.
|
|
50
|
+
cryptography = "^41.0.4"
|
|
51
|
+
fastapi = "^0.99.1"
|
|
52
52
|
uvloop = "^0.17.0"
|
|
53
53
|
sentry-sdk = "^1.23.1"
|
|
54
|
-
boto3 = {version = "^1.
|
|
55
|
-
datadog = {version = "^0.
|
|
56
|
-
ujson = {version = "^5.
|
|
57
|
-
orjson = {version = "^3.
|
|
58
|
-
croniter = "^1.
|
|
59
|
-
cashews = {extras = ["redis"], version = "^6.
|
|
60
|
-
httptools = {version = "^0.
|
|
54
|
+
boto3 = {version = "^1.28.62", optional = true}
|
|
55
|
+
datadog = {version = "^0.47.0", optional = true}
|
|
56
|
+
ujson = {version = "^5.8.0", optional = true}
|
|
57
|
+
orjson = {version = "^3.9.7", optional = true}
|
|
58
|
+
croniter = "^1.4.1"
|
|
59
|
+
cashews = {extras = ["redis"], version = "^6.3.0", optional = true}
|
|
60
|
+
httptools = {version = "^0.6.0", optional = true}
|
|
61
61
|
|
|
62
62
|
[tool.poetry.extras]
|
|
63
63
|
sentry = ["sentry-sdk"]
|
|
@@ -70,29 +70,29 @@ httptools = ["httptools"]
|
|
|
70
70
|
|
|
71
71
|
[tool.poetry.group.dev.dependencies]
|
|
72
72
|
pytest = "^6.2.5"
|
|
73
|
-
"ruamel.yaml" = "^0.17.
|
|
73
|
+
"ruamel.yaml" = "^0.17.32"
|
|
74
74
|
pytest-asyncio = "^0.20.0"
|
|
75
75
|
pytest-mock = "^3.10.0"
|
|
76
76
|
pytest-spec = "^3.2.0"
|
|
77
77
|
pytest-timeout = "^2.1.0"
|
|
78
|
-
coverage = "^7.
|
|
79
|
-
invoke = "^2.
|
|
80
|
-
pylint = "^2.17.
|
|
78
|
+
coverage = "^7.3.1"
|
|
79
|
+
invoke = "^2.2.0"
|
|
80
|
+
pylint = "^2.17.6"
|
|
81
81
|
tavern = "^1.24.1"
|
|
82
82
|
twine = "^4.0.2"
|
|
83
|
-
poethepoet = "^0.
|
|
84
|
-
mypy = "^1.
|
|
85
|
-
black = "^23.
|
|
83
|
+
poethepoet = "^0.23.0"
|
|
84
|
+
mypy = "^1.5.1"
|
|
85
|
+
black = "^23.9.1"
|
|
86
86
|
freezegun = "^1.2.2"
|
|
87
|
-
moto = "^4.
|
|
88
|
-
httpx = "^0.
|
|
89
|
-
types-croniter = "^1.
|
|
90
|
-
types-requests = "^2.
|
|
91
|
-
types-setuptools = "^
|
|
92
|
-
types-ujson = "^5.
|
|
93
|
-
types-PyYAML = "^6.0.12.
|
|
87
|
+
moto = "^4.2.4"
|
|
88
|
+
httpx = "^0.25.0"
|
|
89
|
+
types-croniter = "^1.4.0.1"
|
|
90
|
+
types-requests = "^2.31.0.8"
|
|
91
|
+
types-setuptools = "^68.2.0.0"
|
|
92
|
+
types-ujson = "^5.8.0.1"
|
|
93
|
+
types-PyYAML = "^6.0.12.12"
|
|
94
94
|
pylama = "^8.4.1"
|
|
95
|
-
prospector = "^1.10.
|
|
95
|
+
prospector = "^1.10.2"
|
|
96
96
|
|
|
97
97
|
[tool.poe.tasks]
|
|
98
98
|
types = { cmd = "mypy src/sovereign --ignore-missing-imports", help = "Check types with mypy" }
|
|
@@ -92,6 +92,8 @@ cipher_suite = CipherContainer(
|
|
|
92
92
|
template_context = TemplateContext(
|
|
93
93
|
refresh_rate=config.template_context.refresh_rate,
|
|
94
94
|
refresh_cron=config.template_context.refresh_cron,
|
|
95
|
+
refresh_num_retries=config.template_context.refresh_num_retries,
|
|
96
|
+
refresh_retry_interval_secs=config.template_context.refresh_retry_interval_secs,
|
|
95
97
|
configured_context=config.template_context.context,
|
|
96
98
|
poller=poller,
|
|
97
99
|
encryption_suite=cipher_suite,
|
|
@@ -61,6 +61,8 @@ POLLER = SourcePoller(
|
|
|
61
61
|
TEMPLATE_CONTEXT = TemplateContext(
|
|
62
62
|
refresh_rate=CONFIG.template_context.refresh_rate,
|
|
63
63
|
refresh_cron=CONFIG.template_context.refresh_cron,
|
|
64
|
+
refresh_num_retries=CONFIG.template_context.refresh_num_retries,
|
|
65
|
+
refresh_retry_interval_secs=CONFIG.template_context.refresh_retry_interval_secs,
|
|
64
66
|
configured_context=CONFIG.template_context.context,
|
|
65
67
|
poller=POLLER,
|
|
66
68
|
encryption_suite=CIPHER_SUITE,
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import traceback
|
|
2
|
-
from typing import Dict, Any, Generator, Iterable, NoReturn, Optional
|
|
3
3
|
from copy import deepcopy
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Awaitable,
|
|
7
|
+
Dict,
|
|
8
|
+
Generator,
|
|
9
|
+
Iterable,
|
|
10
|
+
NamedTuple,
|
|
11
|
+
NoReturn,
|
|
12
|
+
Optional,
|
|
13
|
+
)
|
|
14
|
+
|
|
4
15
|
from fastapi import HTTPException
|
|
16
|
+
from structlog.stdlib import BoundLogger
|
|
17
|
+
|
|
5
18
|
from sovereign.config_loader import Loadable
|
|
6
19
|
from sovereign.schemas import DiscoveryRequest, XdsTemplate
|
|
7
20
|
from sovereign.sources import SourcePoller
|
|
8
|
-
from sovereign.utils.crypto import
|
|
21
|
+
from sovereign.utils.crypto import CipherContainer, CipherSuite
|
|
9
22
|
from sovereign.utils.timer import poll_forever, poll_forever_cron
|
|
10
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class LoadContextResponse(NamedTuple):
|
|
26
|
+
context_name: str
|
|
27
|
+
context: Dict[str, Any]
|
|
11
28
|
|
|
12
29
|
|
|
13
30
|
class TemplateContext:
|
|
@@ -15,9 +32,11 @@ class TemplateContext:
|
|
|
15
32
|
self,
|
|
16
33
|
refresh_rate: Optional[int],
|
|
17
34
|
refresh_cron: Optional[str],
|
|
35
|
+
refresh_num_retries: int,
|
|
36
|
+
refresh_retry_interval_secs: int,
|
|
18
37
|
configured_context: Dict[str, Loadable],
|
|
19
38
|
poller: SourcePoller,
|
|
20
|
-
encryption_suite: CipherContainer,
|
|
39
|
+
encryption_suite: Optional[CipherContainer],
|
|
21
40
|
disabled_suite: CipherSuite,
|
|
22
41
|
logger: BoundLogger,
|
|
23
42
|
stats: Any,
|
|
@@ -25,13 +44,15 @@ class TemplateContext:
|
|
|
25
44
|
self.poller = poller
|
|
26
45
|
self.refresh_rate = refresh_rate
|
|
27
46
|
self.refresh_cron = refresh_cron
|
|
47
|
+
self.refresh_num_retries = refresh_num_retries
|
|
48
|
+
self.refresh_retry_interval_secs = refresh_retry_interval_secs
|
|
28
49
|
self.configured_context = configured_context
|
|
29
50
|
self.crypto = encryption_suite
|
|
30
51
|
self.disabled_suite = disabled_suite
|
|
31
52
|
self.logger = logger
|
|
32
53
|
self.stats = stats
|
|
33
54
|
# initial load
|
|
34
|
-
self.context = self.load_context_variables()
|
|
55
|
+
self.context = asyncio.run(self.load_context_variables())
|
|
35
56
|
|
|
36
57
|
async def start_refresh_context(self) -> NoReturn:
|
|
37
58
|
if self.refresh_cron is not None:
|
|
@@ -42,30 +63,66 @@ class TemplateContext:
|
|
|
42
63
|
raise RuntimeError("Failed to start refresh_context, this should never happen")
|
|
43
64
|
|
|
44
65
|
async def refresh_context(self) -> None:
|
|
45
|
-
self.context = self.load_context_variables()
|
|
66
|
+
self.context = await self.load_context_variables()
|
|
46
67
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
async def _load_context(
|
|
69
|
+
self,
|
|
70
|
+
context_name: str,
|
|
71
|
+
context_config: Loadable | str,
|
|
72
|
+
refresh_num_retries: int,
|
|
73
|
+
refresh_retry_interval_secs: int,
|
|
74
|
+
) -> LoadContextResponse:
|
|
75
|
+
retries_left = refresh_num_retries
|
|
76
|
+
context_response = {}
|
|
77
|
+
|
|
78
|
+
while True:
|
|
50
79
|
try:
|
|
51
|
-
if isinstance(
|
|
52
|
-
|
|
53
|
-
elif isinstance(
|
|
54
|
-
|
|
80
|
+
if isinstance(context_config, Loadable):
|
|
81
|
+
context_response = context_config.load()
|
|
82
|
+
elif isinstance(context_config, str):
|
|
83
|
+
context_response = Loadable.from_legacy_fmt(context_config).load()
|
|
55
84
|
self.stats.increment(
|
|
56
85
|
"context.refresh.success",
|
|
57
|
-
tags=[f"context:{
|
|
86
|
+
tags=[f"context:{context_name}"],
|
|
58
87
|
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
return LoadContextResponse(context_name, context_response)
|
|
89
|
+
# pylint: disable=broad-except
|
|
90
|
+
except Exception as e:
|
|
91
|
+
retries_left -= 1
|
|
92
|
+
if retries_left < 0:
|
|
93
|
+
tb = [line for line in traceback.format_exc().split("\n")]
|
|
94
|
+
self.logger.error(str(e), traceback=tb)
|
|
95
|
+
self.stats.increment(
|
|
96
|
+
"context.refresh.error",
|
|
97
|
+
tags=[f"context:{context_name}"],
|
|
98
|
+
)
|
|
99
|
+
return LoadContextResponse(context_name, context_response)
|
|
100
|
+
else:
|
|
101
|
+
await asyncio.sleep(refresh_retry_interval_secs)
|
|
102
|
+
|
|
103
|
+
async def load_context_variables(self) -> Dict[str, Any]:
|
|
104
|
+
context_response: Dict[str, Any] = dict()
|
|
105
|
+
|
|
106
|
+
context_coroutines: list[Awaitable[LoadContextResponse]] = []
|
|
107
|
+
for context_name, context_config in self.configured_context.items():
|
|
108
|
+
context_coroutines.append(
|
|
109
|
+
self._load_context(
|
|
110
|
+
context_name,
|
|
111
|
+
context_config,
|
|
112
|
+
self.refresh_num_retries,
|
|
113
|
+
self.refresh_retry_interval_secs,
|
|
65
114
|
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
context_results: list[LoadContextResponse] = await asyncio.gather(
|
|
118
|
+
*context_coroutines
|
|
119
|
+
)
|
|
120
|
+
for context_result in context_results:
|
|
121
|
+
context_response[context_result.context_name] = context_result.context
|
|
122
|
+
|
|
123
|
+
if "crypto" not in context_response and self.crypto:
|
|
124
|
+
context_response["crypto"] = self.crypto
|
|
125
|
+
return context_response
|
|
69
126
|
|
|
70
127
|
def build_new_context_from_instances(self, node_value: str) -> Dict[str, Any]:
|
|
71
128
|
matches = self.poller.match_node(node_value=node_value)
|
|
@@ -542,6 +542,8 @@ class ContextConfiguration(BaseSettings):
|
|
|
542
542
|
refresh: bool = False
|
|
543
543
|
refresh_rate: Optional[int] = None
|
|
544
544
|
refresh_cron: Optional[str] = None
|
|
545
|
+
refresh_num_retries: int = 3
|
|
546
|
+
refresh_retry_interval_secs: int = 10
|
|
545
547
|
|
|
546
548
|
@staticmethod
|
|
547
549
|
def context_from_legacy(context: Dict[str, str]) -> Dict[str, Loadable]:
|
|
@@ -585,6 +587,10 @@ class ContextConfiguration(BaseSettings):
|
|
|
585
587
|
"refresh": {"env": "SOVEREIGN_REFRESH_CONTEXT"},
|
|
586
588
|
"refresh_rate": {"env": "SOVEREIGN_CONTEXT_REFRESH_RATE"},
|
|
587
589
|
"refresh_cron": {"env": "SOVEREIGN_CONTEXT_REFRESH_CRON"},
|
|
590
|
+
"refresh_num_retries": {"env": "SOVEREIGN_CONTEXT_REFRESH_NUM_RETRIES"},
|
|
591
|
+
"refresh_retry_interval_secs": {
|
|
592
|
+
"env": "SOVEREIGN_CONTEXT_REFRESH_RETRY_INTERVAL_SECS"
|
|
593
|
+
},
|
|
588
594
|
}
|
|
589
595
|
|
|
590
596
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|