qontract-reconcile 0.10.2.dev248__py3-none-any.whl → 0.10.2.dev249__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.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/RECORD +5 -5
- reconcile/status_board.py +31 -39
- {qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev249
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
|
6
6
|
Project-URL: repository, https://github.com/app-sre/qontract-reconcile
|
{qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/RECORD
RENAMED
@@ -103,7 +103,7 @@ reconcile/slack_base.py,sha256=I-msunWxfgu5bSwXYulGbtLjxUB_tRmTCAUCU-3nabI,3484
|
|
103
103
|
reconcile/slack_usergroups.py,sha256=xFkVe67RXSUj8JvpfSFEiRdQzB0TnJJEHW_b5PEwLng,30213
|
104
104
|
reconcile/sql_query.py,sha256=auZCWe6dytsDp83Imfo4zqkpMCLRXU007IUlPeUE3j4,26376
|
105
105
|
reconcile/status.py,sha256=cY4IJFXemhxptRJqR4qaaOWqei9e4jgLXuVSGajMsjg,544
|
106
|
-
reconcile/status_board.py,sha256=
|
106
|
+
reconcile/status_board.py,sha256=wDto8vVFXHLIGwh4MfvsXTogVQ08JhqyDmhOyjjTJyk,15288
|
107
107
|
reconcile/terraform_aws_route53.py,sha256=dQzzT46YhwRA902_H6pi-f7WlX4EaH187wXSdmJAUkQ,9958
|
108
108
|
reconcile/terraform_cloudflare_dns.py,sha256=-aLEe2QnH5cJPu7HWqs-R9NmQ1NlFbcVUm0v7alVL3I,13431
|
109
109
|
reconcile/terraform_cloudflare_resources.py,sha256=pq8Ieo5NmB-dYQ9X2F0s6iEoINMzhiqGw2yQK4ovok4,14980
|
@@ -797,7 +797,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
797
797
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
798
798
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
799
799
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
800
|
-
qontract_reconcile-0.10.2.
|
801
|
-
qontract_reconcile-0.10.2.
|
802
|
-
qontract_reconcile-0.10.2.
|
803
|
-
qontract_reconcile-0.10.2.
|
800
|
+
qontract_reconcile-0.10.2.dev249.dist-info/METADATA,sha256=gwjkeR4GBIHNQvWj-GxTlvIelNg9lny81cU3jDwHC8c,23974
|
801
|
+
qontract_reconcile-0.10.2.dev249.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
802
|
+
qontract_reconcile-0.10.2.dev249.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
803
|
+
qontract_reconcile-0.10.2.dev249.dist-info/RECORD,,
|
reconcile/status_board.py
CHANGED
@@ -5,9 +5,7 @@ from abc import (
|
|
5
5
|
)
|
6
6
|
from collections.abc import Iterable, Mapping
|
7
7
|
from enum import Enum
|
8
|
-
from
|
9
|
-
Optional,
|
10
|
-
)
|
8
|
+
from itertools import chain
|
11
9
|
|
12
10
|
from pydantic import BaseModel
|
13
11
|
|
@@ -122,11 +120,11 @@ class Product(AbstractStatusBoard):
|
|
122
120
|
|
123
121
|
|
124
122
|
class Application(AbstractStatusBoard):
|
125
|
-
product:
|
123
|
+
product: Product
|
126
124
|
services: list["Service"] | None
|
127
125
|
|
128
126
|
def create(self, ocm: OCMBaseClient) -> None:
|
129
|
-
if self.product
|
127
|
+
if self.product.id:
|
130
128
|
spec = self.to_ocm_spec()
|
131
129
|
self.id = create_application(ocm, spec)
|
132
130
|
else:
|
@@ -147,7 +145,7 @@ class Application(AbstractStatusBoard):
|
|
147
145
|
return f'Application: "{self.name}" "{self.fullname}"'
|
148
146
|
|
149
147
|
def to_ocm_spec(self) -> ApplicationOCMSpec:
|
150
|
-
product_id = self.product.id
|
148
|
+
product_id = self.product.id or ""
|
151
149
|
return {
|
152
150
|
"name": self.name,
|
153
151
|
"fullname": self.fullname,
|
@@ -160,18 +158,12 @@ class Application(AbstractStatusBoard):
|
|
160
158
|
|
161
159
|
|
162
160
|
class Service(AbstractStatusBoard):
|
163
|
-
|
164
|
-
# This field is optional so we can create the Service object without the
|
165
|
-
# need to create an Application object first.
|
166
|
-
# This filed is needed when we are creating a Service on teh OCM API.
|
167
|
-
# This field is not used when we are mapping the services that belongs to an
|
168
|
-
# application in that case we use the `services` field in Application class.
|
169
|
-
application: Optional["Application"]
|
161
|
+
application: Application
|
170
162
|
metadata: ServiceMetadataSpec
|
171
163
|
|
172
164
|
def create(self, ocm: OCMBaseClient) -> None:
|
173
165
|
spec = self.to_ocm_spec()
|
174
|
-
if self.application
|
166
|
+
if self.application.id:
|
175
167
|
self.id = create_service(ocm, spec)
|
176
168
|
else:
|
177
169
|
logging.warning("Missing application id for service")
|
@@ -187,7 +179,7 @@ class Service(AbstractStatusBoard):
|
|
187
179
|
logging.error(f'Trying to update Service "{self.name}" without id')
|
188
180
|
return
|
189
181
|
spec = self.to_ocm_spec()
|
190
|
-
if self.application
|
182
|
+
if self.application.id:
|
191
183
|
update_service(ocm, self.id, spec)
|
192
184
|
else:
|
193
185
|
logging.warning("Missing application id for service")
|
@@ -196,9 +188,7 @@ class Service(AbstractStatusBoard):
|
|
196
188
|
return f'Service: "{self.name}" "{self.fullname}"'
|
197
189
|
|
198
190
|
def to_ocm_spec(self) -> ServiceOCMSpec:
|
199
|
-
application_id =
|
200
|
-
self.application.id if self.application and self.application.id else ""
|
201
|
-
)
|
191
|
+
application_id = self.application.id or ""
|
202
192
|
|
203
193
|
return {
|
204
194
|
"name": self.name,
|
@@ -281,21 +271,24 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
281
271
|
logging.error(f'Product "{p.name}" has no id')
|
282
272
|
continue
|
283
273
|
p.applications = [
|
284
|
-
Application(**a
|
274
|
+
Application(**a, product=p)
|
275
|
+
for a in get_product_applications(ocm_api, p.id)
|
285
276
|
]
|
286
277
|
for a in p.applications:
|
287
278
|
if not a.id:
|
288
279
|
logging.error(f'Application "{a.name}" has no id')
|
289
280
|
continue
|
290
281
|
a.services = [
|
291
|
-
Service(**s
|
282
|
+
Service(**s, application=a)
|
283
|
+
for s in get_application_services(ocm_api, a.id)
|
292
284
|
]
|
293
285
|
|
294
286
|
return products
|
295
287
|
|
296
288
|
@staticmethod
|
297
289
|
def desired_abstract_status_board_map(
|
298
|
-
desired_product_apps: Mapping[str, set[str]],
|
290
|
+
desired_product_apps: Mapping[str, set[str]],
|
291
|
+
slodocs: list[SLODocumentV1],
|
299
292
|
) -> dict[str, AbstractStatusBoard]:
|
300
293
|
"""
|
301
294
|
Returns a Mapping of all the AbstractStatusBoard data objects as dictionaries.
|
@@ -304,25 +297,26 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
304
297
|
on Status Board OCM API.
|
305
298
|
"""
|
306
299
|
desired_abstract_status_board_map: dict[str, AbstractStatusBoard] = {}
|
307
|
-
for
|
308
|
-
|
309
|
-
name=
|
300
|
+
for product_name, apps in desired_product_apps.items():
|
301
|
+
product = Product(
|
302
|
+
id=None, name=product_name, fullname=product_name, applications=[]
|
310
303
|
)
|
304
|
+
desired_abstract_status_board_map[product_name] = product
|
311
305
|
for a in apps:
|
312
|
-
key = f"{
|
306
|
+
key = f"{product_name}/{a}"
|
313
307
|
desired_abstract_status_board_map[key] = Application(
|
308
|
+
id=None,
|
314
309
|
name=a,
|
315
310
|
fullname=key,
|
316
311
|
services=[],
|
317
|
-
product=
|
318
|
-
metadata={},
|
312
|
+
product=product,
|
319
313
|
)
|
320
314
|
for slodoc in slodocs:
|
321
315
|
products = [
|
322
316
|
ns.namespace.environment.product.name for ns in slodoc.namespaces
|
323
317
|
]
|
324
318
|
for slo in slodoc.slos or []:
|
325
|
-
for
|
319
|
+
for product_name in products:
|
326
320
|
if slodoc.app.parent_app:
|
327
321
|
app = f"{slodoc.app.parent_app.name}-{slodoc.app.name}"
|
328
322
|
else:
|
@@ -330,8 +324,8 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
330
324
|
|
331
325
|
# Check if the product or app is excluded from the desired list
|
332
326
|
product_or_app_excluded = (
|
333
|
-
|
334
|
-
or app not in desired_product_apps.get(
|
327
|
+
product_name not in desired_product_apps
|
328
|
+
or app not in desired_product_apps.get(product_name, set())
|
335
329
|
)
|
336
330
|
|
337
331
|
# Check if statusBoard label exists and is explicitly disabled
|
@@ -344,8 +338,8 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
344
338
|
if product_or_app_excluded or not status_board_enabled:
|
345
339
|
continue
|
346
340
|
|
347
|
-
key = f"{
|
348
|
-
metadata = {
|
341
|
+
key = f"{product_name}/{app}/{slo.name}"
|
342
|
+
metadata: ServiceMetadataSpec = {
|
349
343
|
"sli_type": slo.sli_type,
|
350
344
|
"sli_specification": slo.sli_specification,
|
351
345
|
"slo_details": slo.slo_details,
|
@@ -354,11 +348,12 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
354
348
|
"window": slo.slo_parameters.window,
|
355
349
|
}
|
356
350
|
desired_abstract_status_board_map[key] = Service(
|
351
|
+
id=None,
|
357
352
|
name=slo.name,
|
358
353
|
fullname=key,
|
359
354
|
metadata=metadata,
|
360
355
|
application=desired_abstract_status_board_map[
|
361
|
-
f"{
|
356
|
+
f"{product_name}/{app}"
|
362
357
|
],
|
363
358
|
)
|
364
359
|
|
@@ -382,7 +377,6 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
382
377
|
def get_diff(
|
383
378
|
desired_abstract_status_board_map: Mapping[str, AbstractStatusBoard],
|
384
379
|
current_abstract_status_board_map: Mapping[str, AbstractStatusBoard],
|
385
|
-
current_products: Mapping[str, Product],
|
386
380
|
) -> list[StatusBoardHandler]:
|
387
381
|
return_list: list[StatusBoardHandler] = []
|
388
382
|
|
@@ -391,6 +385,9 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
391
385
|
desired_abstract_status_board_map,
|
392
386
|
)
|
393
387
|
|
388
|
+
for pair in chain(diff_result.identical.values(), diff_result.change.values()):
|
389
|
+
pair.desired.id = pair.current.id
|
390
|
+
|
394
391
|
return_list.extend(
|
395
392
|
StatusBoardHandler(action=Action.create, status_board_object=o)
|
396
393
|
for o in diff_result.add.values()
|
@@ -460,14 +457,9 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
460
457
|
current_abstract_status_board_map = self.current_abstract_status_board_map(
|
461
458
|
current_products_applications_services
|
462
459
|
)
|
463
|
-
|
464
|
-
current_products = {
|
465
|
-
p.name: p for p in current_products_applications_services
|
466
|
-
}
|
467
460
|
diff = self.get_diff(
|
468
461
|
desired_abstract_status_board_map,
|
469
462
|
current_abstract_status_board_map,
|
470
|
-
current_products,
|
471
463
|
)
|
472
464
|
|
473
465
|
self.apply_diff(dry_run, ocm_api, diff)
|
{qontract_reconcile-0.10.2.dev248.dist-info → qontract_reconcile-0.10.2.dev249.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|