qontract-reconcile 0.10.1rc788__py3-none-any.whl → 0.10.1rc790__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.
- {qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/RECORD +11 -11
- reconcile/gql_definitions/common/saas_files.py +2 -0
- reconcile/saas_auto_promotions_manager/publisher.py +8 -0
- reconcile/saas_auto_promotions_manager/subscriber.py +32 -6
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +4 -0
- reconcile/test/saas_auto_promotions_manager/conftest.py +3 -0
- reconcile/test/test_saasherder.py +10 -2
- {qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc790
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Home-page: https://github.com/app-sre/qontract-reconcile
|
6
6
|
Author: Red Hat App-SRE Team
|
{qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/RECORD
RENAMED
@@ -248,7 +248,7 @@ reconcile/gql_definitions/common/pagerduty_instances.py,sha256=qcbOSUNwmeRcBetJ2
|
|
248
248
|
reconcile/gql_definitions/common/pgp_reencryption_settings.py,sha256=NPLmO6J-zSu5B9QiYbDezLHY3TuOO9ihRBV-Zr84R9w,2259
|
249
249
|
reconcile/gql_definitions/common/pipeline_providers.py,sha256=JJgmmghqLIwjKOdcWYHPnf4PDgAq4GF7046i0ozrqgI,9127
|
250
250
|
reconcile/gql_definitions/common/reserved_networks.py,sha256=yP9qSQCaSQcva-ZgTnZp09qH27ur5_qK080ToIs04MY,2560
|
251
|
-
reconcile/gql_definitions/common/saas_files.py,sha256=
|
251
|
+
reconcile/gql_definitions/common/saas_files.py,sha256=0F1dXJo7B37S2i5RQSvISOQOBlu2U2ue1rRsK5SZ4VU,16005
|
252
252
|
reconcile/gql_definitions/common/saas_target_namespaces.py,sha256=gcTU9jrsNq9-HX-oOkj-nEZKYFTRytDHLs4SpEs93aw,2755
|
253
253
|
reconcile/gql_definitions/common/saasherder_settings.py,sha256=nqQLcMwYxLseqq0BEcVvmrpIj2eQq0h8XDSpLN6GGCw,1793
|
254
254
|
reconcile/gql_definitions/common/smtp_client_settings.py,sha256=JU6t6D-Qj-z1gLlgUiHKe0W7AxWQdty9jlv-ig_43tM,2248
|
@@ -409,9 +409,9 @@ reconcile/rhidp/sso_client/metrics.py,sha256=Tq7tSOsqL3XdcPUdozxqzSPIodUeOV87UCT
|
|
409
409
|
reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
410
410
|
reconcile/saas_auto_promotions_manager/integration.py,sha256=8IXLEvpblgZRr2UPfTsaLZIUDJOdJaoakhqLBkGU_Es,6750
|
411
411
|
reconcile/saas_auto_promotions_manager/meta.py,sha256=76Jp50r6Y_KyJoXFfSjrt5YrCtXyg_A4FXXxHYiS3TE,161
|
412
|
-
reconcile/saas_auto_promotions_manager/publisher.py,sha256=
|
412
|
+
reconcile/saas_auto_promotions_manager/publisher.py,sha256=am8b0uLZIhWjSAgUHPtSOu2fRpa5wXaMl_WnVe4gv2k,3009
|
413
413
|
reconcile/saas_auto_promotions_manager/s3_exporter.py,sha256=IKlVWZmiPnvl7sKeF6JgAlhXZe5CovKTxQc0SNkNSx4,2583
|
414
|
-
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=
|
414
|
+
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=SL-LsUhdhOLnlSremXStIlpVCZx-0zLcTkxSJPIScdQ,10338
|
415
415
|
reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
416
416
|
reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py,sha256=lHIULPE8nmPN9pJVfZFdD0l48EB20o4cAy4owahJenw,7848
|
417
417
|
reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py,sha256=isY8frVsL3PlcdZmdZ4O0qyp76oczl4DUMX9uMArs5Y,1222
|
@@ -422,7 +422,7 @@ reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py,sha256
|
|
422
422
|
reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py,sha256=-qGQOh6Jdp4lomNDij3zWVC0pl6uPHFWS5Woqcp5HQk,410
|
423
423
|
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=IZ7cuH6uOi7f0aIPVi1irBmP0CIK5vmEuhKBJz4YA1s,7235
|
424
424
|
reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
425
|
-
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=
|
425
|
+
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=ZZ7JL6VPfKasq-XXi6CL2UZ89jOcC9uwLW1e8LMvgws,8187
|
426
426
|
reconcile/skupper_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
427
427
|
reconcile/skupper_network/integration.py,sha256=178Q9RSYuZ9NmrCK4jRMLMekrewUaaRdclccI6zBsQ8,10786
|
428
428
|
reconcile/skupper_network/models.py,sha256=DNTI7HZv-rqY42GIIxyRuvroHLvdH6rJerjIq9lj3RU,6663
|
@@ -510,7 +510,7 @@ reconcile/test/test_quay_repos.py,sha256=TdkcRF_a8PLp01Kti9eZZN-vGup2yPBT4Iba3k0
|
|
510
510
|
reconcile/test/test_queries.py,sha256=SpH3RmNpBjEr_ne3VjAMCgKK8RE1z1zo7bypkT5uoO4,1946
|
511
511
|
reconcile/test/test_repo_owners.py,sha256=uRYMLbMmh-9usF0TerabZTZV-Z1CS4I6ybT-LQqCLe8,1423
|
512
512
|
reconcile/test/test_requests_sender.py,sha256=7fd9C2kEFS0-CYtlsif66N1kO9c44pzuBPAJKR9igqU,5385
|
513
|
-
reconcile/test/test_saasherder.py,sha256=
|
513
|
+
reconcile/test/test_saasherder.py,sha256=hSZk34aZFq-wspT-kJmFuHjh8ztSr7IzGc5QdRVrsJ8,47164
|
514
514
|
reconcile/test/test_saasherder_allowed_secret_paths.py,sha256=5NHQwNJO66at6HiyMZ5sVRTQDwxdvlOQo0KmkBWCw5Q,4853
|
515
515
|
reconcile/test/test_secret_reader.py,sha256=kz7nzcPjvA08cytnvcA_PMA98AEyqJWsESkYeRn5xCk,4994
|
516
516
|
reconcile/test/test_slack_base.py,sha256=gpbWOLNxMMX6fyAbs1JakhLTnwfedb3f7WpUae4tQZE,5060
|
@@ -536,7 +536,7 @@ reconcile/test/test_version_bump.py,sha256=q6-3Y1roriI6YWpFwaHOMN7emEP3yL33sh_0V
|
|
536
536
|
reconcile/test/test_vpc_peerings_validator.py,sha256=dFSmjc_dMN2GqMbntCFpa7PUZmyYuQ9DKffh-T5wmxM,6639
|
537
537
|
reconcile/test/test_wrong_region.py,sha256=7KzL7OaICQ9Z3DW27zt_ykMN7_87owAFC-2CYjvGoyA,2138
|
538
538
|
reconcile/test/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
539
|
-
reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=
|
539
|
+
reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=GdFWjuNMrwB9tp0ZG6O9OZnI2GTtBK5cO4DCz_liBtc,5980
|
540
540
|
reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=S30eXJSy2Vc3YLbCP7AfLkOiFGUVoKhEvEBL5vwnbfg,1848
|
541
541
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
542
542
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -785,8 +785,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
785
785
|
tools/test/test_qontract_cli.py,sha256=w2l4BHB09k1d-BGJ1jBUNCqDv7zkqYrMHojQXg-21kQ,4155
|
786
786
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
787
787
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
788
|
-
qontract_reconcile-0.10.
|
789
|
-
qontract_reconcile-0.10.
|
790
|
-
qontract_reconcile-0.10.
|
791
|
-
qontract_reconcile-0.10.
|
792
|
-
qontract_reconcile-0.10.
|
788
|
+
qontract_reconcile-0.10.1rc790.dist-info/METADATA,sha256=hGlhrIUEP7Ra-X9cEXOBXPCZA0mMazOKnqwWsMKfd6g,2364
|
789
|
+
qontract_reconcile-0.10.1rc790.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
790
|
+
qontract_reconcile-0.10.1rc790.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
|
791
|
+
qontract_reconcile-0.10.1rc790.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
792
|
+
qontract_reconcile-0.10.1rc790.dist-info/RECORD,,
|
@@ -254,6 +254,7 @@ query SaasFiles {
|
|
254
254
|
auto
|
255
255
|
publish
|
256
256
|
subscribe
|
257
|
+
soakDays
|
257
258
|
promotion_data {
|
258
259
|
channel
|
259
260
|
data {
|
@@ -452,6 +453,7 @@ class SaasResourceTemplateTargetPromotionV1(ConfiguredBaseModel):
|
|
452
453
|
auto: Optional[bool] = Field(..., alias="auto")
|
453
454
|
publish: Optional[list[str]] = Field(..., alias="publish")
|
454
455
|
subscribe: Optional[list[str]] = Field(..., alias="subscribe")
|
456
|
+
soak_days: Optional[int] = Field(..., alias="soakDays")
|
455
457
|
promotion_data: Optional[list[PromotionDataV1]] = Field(..., alias="promotion_data")
|
456
458
|
|
457
459
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
+
from datetime import datetime
|
2
3
|
from typing import Optional
|
3
4
|
|
4
5
|
from reconcile.utils.promotion_state import PromotionState
|
@@ -17,6 +18,7 @@ class DeploymentInfo:
|
|
17
18
|
success: bool
|
18
19
|
saas_file: str
|
19
20
|
target_config_hash: str
|
21
|
+
check_in: Optional[datetime]
|
20
22
|
|
21
23
|
|
22
24
|
class Publisher:
|
@@ -80,8 +82,14 @@ class Publisher:
|
|
80
82
|
):
|
81
83
|
continue
|
82
84
|
|
85
|
+
check_in = (
|
86
|
+
datetime.fromisoformat(promotion_data.check_in)
|
87
|
+
if promotion_data.check_in
|
88
|
+
else None
|
89
|
+
)
|
83
90
|
self.deployment_info_by_channel[channel] = DeploymentInfo(
|
84
91
|
success=promotion_data.success,
|
85
92
|
saas_file=promotion_data.saas_file,
|
86
93
|
target_config_hash=promotion_data.target_config_hash,
|
94
|
+
check_in=check_in,
|
87
95
|
)
|
@@ -43,6 +43,7 @@ class Subscriber:
|
|
43
43
|
target_namespace: SaasTargetNamespace,
|
44
44
|
use_target_config_hash: bool,
|
45
45
|
uid: str,
|
46
|
+
soak_days: int,
|
46
47
|
):
|
47
48
|
self.saas_name = saas_name
|
48
49
|
self.template_name = template_name
|
@@ -54,6 +55,7 @@ class Subscriber:
|
|
54
55
|
self.desired_hashes: list[ConfigHash] = []
|
55
56
|
self.target_namespace = target_namespace
|
56
57
|
self.uid = uid
|
58
|
+
self.soak_days = soak_days
|
57
59
|
self._content_hash = ""
|
58
60
|
self._use_target_config_hash = use_target_config_hash
|
59
61
|
|
@@ -85,9 +87,10 @@ class Subscriber:
|
|
85
87
|
use_target_config_hash=data["5"],
|
86
88
|
target_namespace=SaasTargetNamespace(**data["6"]),
|
87
89
|
uid=data["7"],
|
90
|
+
soak_days=data["8"],
|
88
91
|
)
|
89
|
-
subscriber.desired_hashes = data["
|
90
|
-
subscriber.desired_ref = data["
|
92
|
+
subscriber.desired_hashes = data["9"]
|
93
|
+
subscriber.desired_ref = data["10"]
|
91
94
|
return subscriber
|
92
95
|
|
93
96
|
def to_exportable_dict(self) -> dict[str, Any]:
|
@@ -103,8 +106,9 @@ class Subscriber:
|
|
103
106
|
data["5"] = self._use_target_config_hash
|
104
107
|
data["6"] = self.target_namespace.dict(by_alias=True)
|
105
108
|
data["7"] = self.uid
|
106
|
-
data["8"] = self.
|
107
|
-
data["9"] = self.
|
109
|
+
data["8"] = self.soak_days
|
110
|
+
data["9"] = self.desired_hashes
|
111
|
+
data["10"] = self.desired_ref
|
108
112
|
return data
|
109
113
|
|
110
114
|
def __eq__(self, other: object) -> bool:
|
@@ -143,6 +147,24 @@ class Subscriber:
|
|
143
147
|
return None
|
144
148
|
return deployment_info
|
145
149
|
|
150
|
+
def _passed_accumulated_soak_days(self) -> bool:
|
151
|
+
"""
|
152
|
+
We accumulate the time a ref is running on all publishers for this subscriber.
|
153
|
+
We compare that accumulated time with the soak_days setting of the subscriber.
|
154
|
+
"""
|
155
|
+
# now = datetime.now(timezone.utc)
|
156
|
+
# delta = timedelta(days=0)
|
157
|
+
# for channel in self.channels:
|
158
|
+
# for publisher in channel.publishers:
|
159
|
+
# deployed_at = publisher.deployment_info_by_channel.get(
|
160
|
+
# channel.name
|
161
|
+
# ).check_in
|
162
|
+
# if not deployed_at:
|
163
|
+
# continue
|
164
|
+
# delta += now - deployed_at
|
165
|
+
# return delta >= timedelta(days=self.soak_days)
|
166
|
+
return True
|
167
|
+
|
146
168
|
def _compute_desired_ref(self) -> None:
|
147
169
|
"""
|
148
170
|
Compute the desired reference for this subscriber.
|
@@ -174,8 +196,12 @@ class Subscriber:
|
|
174
196
|
self.target_file_path,
|
175
197
|
publisher_refs,
|
176
198
|
)
|
177
|
-
if
|
178
|
-
|
199
|
+
if (
|
200
|
+
len(publisher_refs) != 1
|
201
|
+
or any_bad_deployment
|
202
|
+
or not self._passed_accumulated_soak_days()
|
203
|
+
):
|
204
|
+
# We keep current state
|
179
205
|
self.desired_ref = self.ref
|
180
206
|
else:
|
181
207
|
# We have a common single publisher ref w/o any deployment issues
|
@@ -95,6 +95,9 @@ class SaasFilesInventory:
|
|
95
95
|
continue
|
96
96
|
if not target.promotion.auto:
|
97
97
|
continue
|
98
|
+
soak_days = (
|
99
|
+
target.promotion.soak_days if target.promotion.soak_days else 0
|
100
|
+
)
|
98
101
|
subscriber = Subscriber(
|
99
102
|
uid=target.uid(
|
100
103
|
parent_saas_file_name=saas_file.name,
|
@@ -105,6 +108,7 @@ class SaasFilesInventory:
|
|
105
108
|
target_file_path=file_path,
|
106
109
|
ref=target.ref,
|
107
110
|
target_namespace=target.namespace,
|
111
|
+
soak_days=soak_days,
|
108
112
|
# Note: this will be refactored at a later point.
|
109
113
|
# https://issues.redhat.com/browse/APPSRE-7516
|
110
114
|
use_target_config_hash=bool(saas_file.publish_job_logs),
|
@@ -5,6 +5,7 @@ from collections.abc import (
|
|
5
5
|
Mapping,
|
6
6
|
MutableMapping,
|
7
7
|
)
|
8
|
+
from datetime import datetime, timezone
|
8
9
|
from typing import Any
|
9
10
|
from unittest.mock import (
|
10
11
|
MagicMock,
|
@@ -139,6 +140,7 @@ def subscriber_builder(
|
|
139
140
|
success=publisher_data.get("SUCCESSFUL_DEPLOYMENT", True),
|
140
141
|
target_config_hash=publisher_data.get("CONFIG_HASH", ""),
|
141
142
|
saas_file=publisher_name,
|
143
|
+
check_in=publisher_data.get("CHECK_IN", datetime.now(timezone.utc)),
|
142
144
|
)
|
143
145
|
channel.publishers.append(publisher)
|
144
146
|
channels.append(channel)
|
@@ -155,6 +157,7 @@ def subscriber_builder(
|
|
155
157
|
target_file_path=data.get("TARGET_FILE_PATH", ""),
|
156
158
|
template_name="",
|
157
159
|
use_target_config_hash=data.get("USE_TARGET_CONFIG_HASH", True),
|
160
|
+
soak_days=data.get("SOAK_DAYS", 0),
|
158
161
|
)
|
159
162
|
subscriber.channels = channels
|
160
163
|
subscriber.config_hashes_by_channel_name = cur_config_hashes_by_channel
|
@@ -160,7 +160,11 @@ class TestSaasFileValid(TestCase):
|
|
160
160
|
self.saas_file.resource_templates[0].targets[
|
161
161
|
1
|
162
162
|
].promotion = SaasResourceTemplateTargetPromotionV1(
|
163
|
-
auto=True,
|
163
|
+
auto=True,
|
164
|
+
publish=None,
|
165
|
+
subscribe=None,
|
166
|
+
promotion_data=None,
|
167
|
+
soakDays=0,
|
164
168
|
)
|
165
169
|
saasherder = SaasHerder(
|
166
170
|
[self.saas_file],
|
@@ -180,7 +184,11 @@ class TestSaasFileValid(TestCase):
|
|
180
184
|
self.saas_file.resource_templates[0].targets[
|
181
185
|
1
|
182
186
|
].promotion = SaasResourceTemplateTargetPromotionV1(
|
183
|
-
auto=True,
|
187
|
+
auto=True,
|
188
|
+
publish=None,
|
189
|
+
subscribe=None,
|
190
|
+
promotion_data=None,
|
191
|
+
soakDays=0,
|
184
192
|
)
|
185
193
|
saasherder = SaasHerder(
|
186
194
|
[self.saas_file],
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc788.dist-info → qontract_reconcile-0.10.1rc790.dist-info}/top_level.txt
RENAMED
File without changes
|