qontract-reconcile 0.10.1rc711__py3-none-any.whl → 0.10.1rc712__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.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/RECORD +7 -7
- reconcile/deadmanssnitch.py +40 -41
- reconcile/test/test_deadmanssnitch.py +18 -2
- {qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.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.1rc712
|
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.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/RECORD
RENAMED
@@ -18,7 +18,7 @@ reconcile/dashdotdb_dora.py,sha256=n9EJXhxCoMYuldj4Fa5s0TqfiiolSrqDEOCaLBV3uag,1
|
|
18
18
|
reconcile/dashdotdb_dvo.py,sha256=YXqpI6fBQAql-ybGI0grj9gWMzmKiAvPE__pNju6obk,8996
|
19
19
|
reconcile/dashdotdb_slo.py,sha256=bf1WSh5JP9obHVQsMy0OO71_VTYZgwAopElFZM6DmRo,6714
|
20
20
|
reconcile/database_access_manager.py,sha256=42dBJyihdwx4WjEBjwi3lUiDzQ1t_2ZFViJri2c4_aE,25716
|
21
|
-
reconcile/deadmanssnitch.py,sha256=
|
21
|
+
reconcile/deadmanssnitch.py,sha256=n-5W-djUgwzpmdDM4eQIZpkkDmHY0vndt-42LJXI4Y8,7491
|
22
22
|
reconcile/dynatrace_token_provider.py,sha256=P5jvMavremWp64LVknz1kCZI4aagwLrDDfXkmJ9diwY,17212
|
23
23
|
reconcile/email_sender.py,sha256=-5L-Ag_jaEYSzYRoMr52KQBRXz1E8yx9GqLbg2X4XFU,3533
|
24
24
|
reconcile/gabi_authorized_users.py,sha256=9kpSJGyMe_qYVHIgTFHhYf8E3lKSLO0Ia1WwK9ADNIE,4502
|
@@ -440,7 +440,7 @@ reconcile/test/test_cli.py,sha256=qx_iBwh4Z-YkK3sbjK1wEziPTgn060EN-baf9DNvR3k,10
|
|
440
440
|
reconcile/test/test_closedbox_endpoint_monitoring.py,sha256=isMHYwRWMFARU2nbJgbl69kD6H0eA86noCM4MPVI1fo,7151
|
441
441
|
reconcile/test/test_dashdotdb_dora.py,sha256=MfHGAsX2eSQSvBVt9_1Sah3aQKNJBXA9Iu86X0NWD6c,7705
|
442
442
|
reconcile/test/test_database_access_manager.py,sha256=-9fYo8wMNhbJUTK_bd7g_fS5zYsAlqQ0rBDDYBMZvZQ,19595
|
443
|
-
reconcile/test/test_deadmanssnitch.py,sha256=
|
443
|
+
reconcile/test/test_deadmanssnitch.py,sha256=qtn1zwWgIQYw5JULLPvDLaj0GWiecYnvky0HcuETjdo,9843
|
444
444
|
reconcile/test/test_gabi_authorized_users.py,sha256=6XnV5Q9inxP81ktGMVKyWucjBTUj8Imy2L0HG3YHyUE,2496
|
445
445
|
reconcile/test/test_gcr_mirror.py,sha256=A0y8auKZzr62-mGoxSQ__JnN0-ijZUltzjwR5miBgso,490
|
446
446
|
reconcile/test/test_github_org.py,sha256=j3KeB4OnSln1gm2hidce49xdMru-j75NS3cM-AEgzZc,4511
|
@@ -764,8 +764,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
764
764
|
tools/test/test_qontract_cli.py,sha256=UEwAW7PA_GIrbqzaLxpkCxbuVjEFLNvnVG-6VyoCGIc,4147
|
765
765
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
766
766
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
767
|
-
qontract_reconcile-0.10.
|
768
|
-
qontract_reconcile-0.10.
|
769
|
-
qontract_reconcile-0.10.
|
770
|
-
qontract_reconcile-0.10.
|
771
|
-
qontract_reconcile-0.10.
|
767
|
+
qontract_reconcile-0.10.1rc712.dist-info/METADATA,sha256=MeTu0tcuNA_jlvS3yM5lz9s0oR5AQtaXj5SbIG8_qjk,2382
|
768
|
+
qontract_reconcile-0.10.1rc712.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
769
|
+
qontract_reconcile-0.10.1rc712.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
|
770
|
+
qontract_reconcile-0.10.1rc712.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
771
|
+
qontract_reconcile-0.10.1rc712.dist-info/RECORD,,
|
reconcile/deadmanssnitch.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import (
|
3
|
-
Optional,
|
4
3
|
cast,
|
5
4
|
)
|
6
5
|
|
@@ -20,12 +19,8 @@ from reconcile.utils.runtime.integration import (
|
|
20
19
|
NoParams,
|
21
20
|
QontractReconcileIntegration,
|
22
21
|
)
|
23
|
-
from reconcile.utils.secret_reader import (
|
24
|
-
SecretNotFound,
|
25
|
-
)
|
26
22
|
from reconcile.utils.semver_helper import make_semver
|
27
23
|
from reconcile.utils.vault import (
|
28
|
-
SecretFieldNotFound,
|
29
24
|
VaultClient,
|
30
25
|
_VaultClient,
|
31
26
|
)
|
@@ -62,37 +57,24 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
62
57
|
def get_snitch_name(cluster: ClusterV1) -> str:
|
63
58
|
return cluster.prometheus_url.replace("https://", "")
|
64
59
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if snitch_url:
|
69
|
-
self.vault_client.write(
|
70
|
-
{
|
71
|
-
"path": self.settings.snitches_path,
|
72
|
-
"data": {f"deadmanssnitch-{cluster_name}-url": snitch_url},
|
73
|
-
},
|
74
|
-
decode_base64=False,
|
75
|
-
)
|
60
|
+
@staticmethod
|
61
|
+
def get_vault_key(cluster_name: str) -> str:
|
62
|
+
return f"deadmanssnitch-{cluster_name}-url"
|
76
63
|
|
77
64
|
def add_vault_data(
|
78
|
-
self, cluster_name: str, snitch: Snitch,
|
65
|
+
self, cluster_name: str, snitch: Snitch, vault_snitch_map: dict[str, str]
|
79
66
|
) -> Snitch:
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
"field": f"deadmanssnitch-{cluster_name}-url",
|
84
|
-
}
|
85
|
-
snitch.vault_data = self.secret_reader.read(full_secret_path).strip()
|
86
|
-
except (SecretNotFound, SecretFieldNotFound):
|
67
|
+
if snitch_url := vault_snitch_map.get(self.get_vault_key(cluster_name)):
|
68
|
+
snitch.vault_data = snitch_url
|
69
|
+
else:
|
87
70
|
snitch.vault_data = SECRET_NOT_FOUND
|
88
71
|
return snitch
|
89
72
|
|
90
73
|
def create_snitch(
|
91
74
|
self,
|
92
|
-
cluster_name: str,
|
93
75
|
snitch_spec: SnitchSpec,
|
94
76
|
deadmanssnitch_api: DeadMansSnitchApi,
|
95
|
-
) ->
|
77
|
+
) -> Snitch:
|
96
78
|
payload = {
|
97
79
|
"name": snitch_spec.name,
|
98
80
|
"alert_type": snitch_spec.alert_type,
|
@@ -102,9 +84,7 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
102
84
|
"notes": snitch_spec.notes,
|
103
85
|
}
|
104
86
|
snitch_data = deadmanssnitch_api.create_snitch(payload=payload)
|
105
|
-
|
106
|
-
cluster_name=cluster_name, snitch_url=snitch_data.check_in_url
|
107
|
-
)
|
87
|
+
return snitch_data
|
108
88
|
|
109
89
|
def reconcile(
|
110
90
|
self,
|
@@ -112,6 +92,7 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
112
92
|
current_state: dict[str, Snitch],
|
113
93
|
desired_state: dict[str, SnitchSpec],
|
114
94
|
deadmanssnitch_api: DeadMansSnitchApi,
|
95
|
+
vault_snitch_map: dict[str, str],
|
115
96
|
) -> None:
|
116
97
|
diffs = diff_mappings(
|
117
98
|
current=current_state,
|
@@ -119,11 +100,15 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
119
100
|
equal=lambda current, desired: current.name == desired.name,
|
120
101
|
)
|
121
102
|
errors = []
|
103
|
+
vault_snitch_map_copy = vault_snitch_map.copy()
|
122
104
|
for cluster_name, snitch in diffs.add.items():
|
123
105
|
logging.info("[cluster_name:%s] [Action:create_snitch]", cluster_name)
|
124
106
|
if not dry_run:
|
125
107
|
try:
|
126
|
-
self.create_snitch(
|
108
|
+
snitch_data = self.create_snitch(snitch, deadmanssnitch_api)
|
109
|
+
vault_snitch_map_copy[self.get_vault_key(cluster_name)] = (
|
110
|
+
snitch_data.check_in_url
|
111
|
+
)
|
127
112
|
except Exception as e:
|
128
113
|
errors.append(e)
|
129
114
|
for cluster_name, snitch_value in diffs.delete.items():
|
@@ -136,14 +121,23 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
136
121
|
for cluster_name, diff_pair in diffs.identical.items():
|
137
122
|
if diff_pair.current.needs_vault_update():
|
138
123
|
logging.info("[cluster_name:%s] [Action:update_vault]", cluster_name)
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
124
|
+
vault_snitch_map_copy[self.get_vault_key(cluster_name)] = (
|
125
|
+
diff_pair.current.check_in_url
|
126
|
+
)
|
127
|
+
|
128
|
+
# write to vault in case there is change in secret i.e in case of creation/update
|
129
|
+
if vault_snitch_map != vault_snitch_map_copy and not dry_run:
|
130
|
+
try:
|
131
|
+
self.vault_client.write(
|
132
|
+
{
|
133
|
+
"path": self.settings.snitches_path,
|
134
|
+
"data": vault_snitch_map_copy,
|
135
|
+
},
|
136
|
+
decode_base64=False,
|
137
|
+
)
|
138
|
+
except Exception as e:
|
139
|
+
errors.append(e)
|
140
|
+
|
147
141
|
if errors:
|
148
142
|
raise ExceptionGroup("Errors occurred while reconcile", errors)
|
149
143
|
|
@@ -151,6 +145,7 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
151
145
|
self,
|
152
146
|
deadmanssnitch_api: DeadMansSnitchApi,
|
153
147
|
clusters: list[ClusterV1],
|
148
|
+
vault_snitch_map: dict[str, str],
|
154
149
|
) -> dict[str, Snitch]:
|
155
150
|
snitch_name_to_cluster_name_mapping = {
|
156
151
|
self.get_snitch_name(cluster): cluster.name for cluster in clusters
|
@@ -159,9 +154,7 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
159
154
|
snitches = deadmanssnitch_api.get_snitches(tags=self.settings.tags)
|
160
155
|
# create snitch_map only for the desired clusters
|
161
156
|
current_state = {
|
162
|
-
cluster_name: self.add_vault_data(
|
163
|
-
cluster_name, snitch, self.settings.snitches_path
|
164
|
-
)
|
157
|
+
cluster_name: self.add_vault_data(cluster_name, snitch, vault_snitch_map)
|
165
158
|
for snitch in snitches
|
166
159
|
if (cluster_name := snitch_name_to_cluster_name_mapping.get(snitch.name))
|
167
160
|
}
|
@@ -191,6 +184,10 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
191
184
|
"path": self.settings.token_creds.path,
|
192
185
|
"field": self.settings.token_creds.field,
|
193
186
|
})
|
187
|
+
# get all snitch secrets from vault
|
188
|
+
vault_snitch_map = self.secret_reader.read_all({
|
189
|
+
"path": self.settings.snitches_path
|
190
|
+
})
|
194
191
|
with DeadMansSnitchApi(token=token) as deadmanssnitch_api:
|
195
192
|
# desired state - get the clusters having enableDeadMansSnitch field
|
196
193
|
clusters = get_clusters_with_dms()
|
@@ -199,10 +196,12 @@ class DeadMansSnitchIntegration(QontractReconcileIntegration[NoParams]):
|
|
199
196
|
current_state = self.get_current_state(
|
200
197
|
deadmanssnitch_api,
|
201
198
|
clusters,
|
199
|
+
vault_snitch_map,
|
202
200
|
)
|
203
201
|
self.reconcile(
|
204
202
|
dry_run,
|
205
203
|
current_state=current_state,
|
206
204
|
desired_state=desired_state,
|
207
205
|
deadmanssnitch_api=deadmanssnitch_api,
|
206
|
+
vault_snitch_map=vault_snitch_map,
|
208
207
|
)
|
@@ -102,6 +102,7 @@ def test_get_current_state(
|
|
102
102
|
current_state = dms_integration.get_current_state(
|
103
103
|
deadmanssnitch_api=deadmanssnitch_api,
|
104
104
|
clusters=clusters,
|
105
|
+
vault_snitch_map={"deadmanssnitch-test_cluster_1-url": "secret"},
|
105
106
|
)
|
106
107
|
assert current_state["test_cluster_1"].vault_data == "secret"
|
107
108
|
|
@@ -116,6 +117,7 @@ def test_integration_for_create(
|
|
116
117
|
"reconcile.deadmanssnitch.DeadMansSnitchIntegration.__init__"
|
117
118
|
).return_value = None
|
118
119
|
dms_integration = DeadMansSnitchIntegration()
|
120
|
+
secret_reader.read_all.return_value = {}
|
119
121
|
dms_integration._secret_reader = secret_reader
|
120
122
|
dms_integration.settings = deadmanssnitch_settings
|
121
123
|
dms_integration.vault_client = vault_mock
|
@@ -136,7 +138,18 @@ def test_integration_for_create(
|
|
136
138
|
mock_create_snitch = mocker.patch(
|
137
139
|
"reconcile.deadmanssnitch.DeadMansSnitchIntegration.create_snitch"
|
138
140
|
)
|
139
|
-
mock_create_snitch.return_value =
|
141
|
+
mock_create_snitch.return_value = Snitch(
|
142
|
+
name="prometheus.create_cluster.devshift.net",
|
143
|
+
token="test",
|
144
|
+
href="testc",
|
145
|
+
status="healthy",
|
146
|
+
alert_type="basic",
|
147
|
+
alert_email=["test_mail"],
|
148
|
+
interval="15_minute",
|
149
|
+
check_in_url="test_url",
|
150
|
+
tags=["app-sre"],
|
151
|
+
notes="test_notes",
|
152
|
+
)
|
140
153
|
dms_integration.run(dry_run=False)
|
141
154
|
mock_create_snitch.assert_called_once()
|
142
155
|
|
@@ -151,6 +164,7 @@ def test_integration_for_delete(
|
|
151
164
|
"reconcile.deadmanssnitch.DeadMansSnitchIntegration.__init__"
|
152
165
|
).return_value = None
|
153
166
|
dms_integration = DeadMansSnitchIntegration()
|
167
|
+
secret_reader.read_all.return_value = {"deadmanssnitch-create_cluster-url": "test"}
|
154
168
|
dms_integration._secret_reader = secret_reader
|
155
169
|
dms_integration.settings = deadmanssnitch_settings
|
156
170
|
dms_integration.vault_client = vault_mock
|
@@ -199,6 +213,7 @@ def test_integration_for_update_vault(
|
|
199
213
|
"reconcile.deadmanssnitch.DeadMansSnitchIntegration.__init__"
|
200
214
|
).return_value = None
|
201
215
|
dms_integration = DeadMansSnitchIntegration()
|
216
|
+
secret_reader.read_all.return_value = {"deadmanssnitch-test_cluster-url": "test"}
|
202
217
|
dms_integration._secret_reader = secret_reader
|
203
218
|
dms_integration.settings = deadmanssnitch_settings
|
204
219
|
dms_integration.vault_client = vault_mock
|
@@ -230,10 +245,11 @@ def test_integration_for_update_vault(
|
|
230
245
|
)
|
231
246
|
]
|
232
247
|
dms_integration.run(dry_run=False)
|
248
|
+
data = {"deadmanssnitch-test_cluster-url": "test_url"}
|
233
249
|
vault_mock.write.assert_called_once_with(
|
234
250
|
{
|
235
251
|
"path": deadmanssnitch_settings.snitches_path,
|
236
|
-
"data":
|
252
|
+
"data": data,
|
237
253
|
},
|
238
254
|
decode_base64=False,
|
239
255
|
)
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc711.dist-info → qontract_reconcile-0.10.1rc712.dist-info}/top_level.txt
RENAMED
File without changes
|