qontract-reconcile 0.10.2.dev303__py3-none-any.whl → 0.10.2.dev304__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.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/RECORD +9 -9
- reconcile/gql_definitions/status_board/status_board.py +0 -20
- reconcile/status_board.py +9 -133
- reconcile/typed_queries/status_board.py +8 -43
- reconcile/utils/ocm/status_board.py +0 -13
- tools/qontract_cli.py +1 -1
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev304.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.dev304
|
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.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/RECORD
RENAMED
@@ -102,7 +102,7 @@ reconcile/slack_base.py,sha256=I-msunWxfgu5bSwXYulGbtLjxUB_tRmTCAUCU-3nabI,3484
|
|
102
102
|
reconcile/slack_usergroups.py,sha256=3uQVZK0WeZfvE1g7xQwciKCcC3LifDa3NuE1ygQ0cRk,30174
|
103
103
|
reconcile/sql_query.py,sha256=FVwANLPWjkUHqN2OXJ-vnX5hqqcO6rTdyLEO4HkmAgM,26397
|
104
104
|
reconcile/status.py,sha256=cY4IJFXemhxptRJqR4qaaOWqei9e4jgLXuVSGajMsjg,544
|
105
|
-
reconcile/status_board.py,sha256=
|
105
|
+
reconcile/status_board.py,sha256=0vTQzxrFPTmJtzNOC-iaJG_BmXbDe2vgBUe0LMUyfDE,15313
|
106
106
|
reconcile/terraform_aws_route53.py,sha256=CWp5bE3ddUrJGNNvG8YmkSPyNHCWtOc1GEDVLnbOY9Q,10043
|
107
107
|
reconcile/terraform_cloudflare_dns.py,sha256=0Eu46o_BBEEq-B-CCvKop9VTbwrvliCKGSS9gLBSJE4,13456
|
108
108
|
reconcile/terraform_cloudflare_resources.py,sha256=tK-BxQeNdZjf59deKd51Roz868e7UXe52XvcHsffJK0,14982
|
@@ -405,7 +405,7 @@ reconcile/gql_definitions/slack_usergroups/users.py,sha256=0KFLYHYXL_bGIKf5LAJSY
|
|
405
405
|
reconcile/gql_definitions/slo_documents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
406
406
|
reconcile/gql_definitions/slo_documents/slo_documents.py,sha256=pOrm9NXAonlo6Lxq6NkD3mHkZ53ZeBnZOZMkDvOEwds,3746
|
407
407
|
reconcile/gql_definitions/status_board/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
408
|
-
reconcile/gql_definitions/status_board/status_board.py,sha256=
|
408
|
+
reconcile/gql_definitions/status_board/status_board.py,sha256=BYq-1g_-AjNKHIKmY2rQT8l3ql4Mcwa_CIxN_FS4F6M,4690
|
409
409
|
reconcile/gql_definitions/statuspage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
410
410
|
reconcile/gql_definitions/statuspage/statuspages.py,sha256=CTRzjiR9k41LqlkgyoNHwC2JERsoD_Run_aK7jw_Ono,5299
|
411
411
|
reconcile/gql_definitions/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -563,7 +563,7 @@ reconcile/typed_queries/saas_files.py,sha256=SOE36sWPBcuaRmEaNxXCQZMQdJiUZX8_A92
|
|
563
563
|
reconcile/typed_queries/slack.py,sha256=r30lspctHloyygPn8_DVybxPwUWwiBpvBRRXiTVcQYk,251
|
564
564
|
reconcile/typed_queries/slo_documents.py,sha256=YMdox_-lBRqrdxamPhdnUlRTY_Ro35ptsupq7OaynUQ,362
|
565
565
|
reconcile/typed_queries/smtp.py,sha256=aSLglYa5bHKmlGwKkxq2RZqyMWuAf0a4S_mOuhDa084,542
|
566
|
-
reconcile/typed_queries/status_board.py,sha256=
|
566
|
+
reconcile/typed_queries/status_board.py,sha256=XB8kn3qh2cIqGTPCImS5eUyZOaolvSNfWss5kUkARYg,1826
|
567
567
|
reconcile/typed_queries/tekton_pipeline_providers.py,sha256=LtoSnSRkuckYsXIU64L1Mf-o3iuUjaN-5O-ARzIROZA,515
|
568
568
|
reconcile/typed_queries/terraform_namespaces.py,sha256=4H9WE90jN_BVYBAt1DxJITS4vkL-vykbXZIS1H4EKNM,413
|
569
569
|
reconcile/typed_queries/unleash.py,sha256=7HDc4owF044xM9Thx4WsXV7DZgETxJjy4lbpwmqz1vU,282
|
@@ -733,7 +733,7 @@ reconcile/utils/ocm/products.py,sha256=UtWpkAvSMCxPOulEB7aV5ZY8ej_rmErlE_HVdm9Gn
|
|
733
733
|
reconcile/utils/ocm/search_filters.py,sha256=09p4Wq1d1HGrDiinf1dmLJ46VtFhkkRCOL4V-N-zwjY,14808
|
734
734
|
reconcile/utils/ocm/service_log.py,sha256=RG1f0MMn6joKaRCAm2xveSJCavdOPP1BVo9FXecDxaI,2018
|
735
735
|
reconcile/utils/ocm/sre_capability_labels.py,sha256=nqh0imrYczNeeeC7ZNX3pEwuAIVkKLTKZf0YHSPZYpE,1537
|
736
|
-
reconcile/utils/ocm/status_board.py,sha256=
|
736
|
+
reconcile/utils/ocm/status_board.py,sha256=8DYeIrOsW8Bh5PCtKdvGGpaxb9Wugcc5rLxZJ8Z7b_s,4181
|
737
737
|
reconcile/utils/ocm/subscriptions.py,sha256=hehKXsDXIhnhqvWOuiYvx6y2FGq3zt0APGYj7WiBIdI,2765
|
738
738
|
reconcile/utils/ocm/syncsets.py,sha256=9IQm1l5BodOVZa2OFbQmow3afmh4nXe5pn-CCJ5LxTI,1169
|
739
739
|
reconcile/utils/ocm/upgrades.py,sha256=W8-sLgETI_418ftY9vBlXswyjx_KdhJTJO9cwBL3hfY,4162
|
@@ -770,7 +770,7 @@ tools/app_sre_tekton_access_reporter.py,sha256=5qmkevJdlb2j_lpGC5Pu1Pmo0eomX5Zxz
|
|
770
770
|
tools/app_sre_tekton_access_revalidation.py,sha256=vwL1o_j7oSTOhrHNH1znpgjA2LHGzb8yc5iG3aaY4m0,2684
|
771
771
|
tools/glitchtip_access_reporter.py,sha256=wnaiDGW4MkYONV_erltnJ6nGkEj0kQrAiv04NNnOS0k,2859
|
772
772
|
tools/glitchtip_access_revalidation.py,sha256=jjeLO53LTbz_LfQw3G2Cs8lVLO_6xqU39BYyTH3cEPE,2764
|
773
|
-
tools/qontract_cli.py,sha256=
|
773
|
+
tools/qontract_cli.py,sha256=KyK2iCSh68cPolZygQtYb18ZtjIUlFw4aZT9D5p91kw,159892
|
774
774
|
tools/template_validation.py,sha256=Xn9X4sGFznx-rvBDnq9Kq16rfET8V3bqH1EwavsGBac,3335
|
775
775
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
776
776
|
tools/cli_commands/container_images_report.py,sha256=8mAjCS6XR0yD7k0mfiVBlt6xbYU47q_ftdYNi5o5VKE,5566
|
@@ -796,7 +796,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
796
796
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=uQv2QJAmUXP1g2GPIH30WTlvL9soY6m9lefpZEVDM5w,3965
|
797
797
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
798
798
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
799
|
-
qontract_reconcile-0.10.2.
|
800
|
-
qontract_reconcile-0.10.2.
|
801
|
-
qontract_reconcile-0.10.2.
|
802
|
-
qontract_reconcile-0.10.2.
|
799
|
+
qontract_reconcile-0.10.2.dev304.dist-info/METADATA,sha256=YgHRn5DrtN3RthvVsikCbu5lvctPQ019NE9Vu9iZLtI,24916
|
800
|
+
qontract_reconcile-0.10.2.dev304.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
801
|
+
qontract_reconcile-0.10.2.dev304.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
802
|
+
qontract_reconcile-0.10.2.dev304.dist-info/RECORD,,
|
@@ -51,19 +51,11 @@ query StatusBoard {
|
|
51
51
|
childrenApps {
|
52
52
|
name
|
53
53
|
onboardingStatus
|
54
|
-
saasFiles {
|
55
|
-
name
|
56
|
-
managedResourceTypes
|
57
|
-
}
|
58
54
|
}
|
59
55
|
parentApp {
|
60
56
|
name
|
61
57
|
onboardingStatus
|
62
58
|
}
|
63
|
-
saasFiles {
|
64
|
-
name
|
65
|
-
managedResourceTypes
|
66
|
-
}
|
67
59
|
}
|
68
60
|
}
|
69
61
|
}
|
@@ -104,15 +96,9 @@ class ProductV1(ConfiguredBaseModel):
|
|
104
96
|
name: str = Field(..., alias="name")
|
105
97
|
|
106
98
|
|
107
|
-
class SaasFileV2(ConfiguredBaseModel):
|
108
|
-
name: str = Field(..., alias="name")
|
109
|
-
managed_resource_types: list[str] = Field(..., alias="managedResourceTypes")
|
110
|
-
|
111
|
-
|
112
99
|
class AppV1_AppV1(ConfiguredBaseModel):
|
113
100
|
name: str = Field(..., alias="name")
|
114
101
|
onboarding_status: str = Field(..., alias="onboardingStatus")
|
115
|
-
saas_files: Optional[list[SaasFileV2]] = Field(..., alias="saasFiles")
|
116
102
|
|
117
103
|
|
118
104
|
class NamespaceV1_AppV1_AppV1(ConfiguredBaseModel):
|
@@ -120,17 +106,11 @@ class NamespaceV1_AppV1_AppV1(ConfiguredBaseModel):
|
|
120
106
|
onboarding_status: str = Field(..., alias="onboardingStatus")
|
121
107
|
|
122
108
|
|
123
|
-
class AppV1_SaasFileV2(ConfiguredBaseModel):
|
124
|
-
name: str = Field(..., alias="name")
|
125
|
-
managed_resource_types: list[str] = Field(..., alias="managedResourceTypes")
|
126
|
-
|
127
|
-
|
128
109
|
class AppV1(ConfiguredBaseModel):
|
129
110
|
name: str = Field(..., alias="name")
|
130
111
|
onboarding_status: str = Field(..., alias="onboardingStatus")
|
131
112
|
children_apps: Optional[list[AppV1_AppV1]] = Field(..., alias="childrenApps")
|
132
113
|
parent_app: Optional[NamespaceV1_AppV1_AppV1] = Field(..., alias="parentApp")
|
133
|
-
saas_files: Optional[list[AppV1_SaasFileV2]] = Field(..., alias="saasFiles")
|
134
114
|
|
135
115
|
|
136
116
|
class NamespaceV1(ConfiguredBaseModel):
|
reconcile/status_board.py
CHANGED
@@ -6,9 +6,6 @@ from abc import (
|
|
6
6
|
from collections.abc import Iterable, Mapping
|
7
7
|
from enum import Enum
|
8
8
|
from itertools import chain
|
9
|
-
from typing import (
|
10
|
-
Any,
|
11
|
-
)
|
12
9
|
|
13
10
|
from pydantic import BaseModel
|
14
11
|
|
@@ -16,7 +13,7 @@ from reconcile.gql_definitions.slo_documents.slo_documents import SLODocumentV1
|
|
16
13
|
from reconcile.gql_definitions.status_board.status_board import StatusBoardV1
|
17
14
|
from reconcile.typed_queries.slo_documents import get_slo_documents
|
18
15
|
from reconcile.typed_queries.status_board import (
|
19
|
-
|
16
|
+
get_selected_app_names,
|
20
17
|
get_status_board,
|
21
18
|
)
|
22
19
|
from reconcile.utils.differ import diff_mappings
|
@@ -34,7 +31,6 @@ from reconcile.utils.ocm.status_board import (
|
|
34
31
|
get_application_services,
|
35
32
|
get_managed_products,
|
36
33
|
get_product_applications,
|
37
|
-
update_application,
|
38
34
|
update_service,
|
39
35
|
)
|
40
36
|
from reconcile.utils.ocm_base_client import (
|
@@ -59,7 +55,6 @@ class AbstractStatusBoard(ABC, BaseModel):
|
|
59
55
|
id: str | None
|
60
56
|
name: str
|
61
57
|
fullname: str
|
62
|
-
metadata: dict[str, Any] | ServiceMetadataSpec | None
|
63
58
|
|
64
59
|
@abstractmethod
|
65
60
|
def create(self, ocm: OCMBaseClient) -> None:
|
@@ -127,7 +122,6 @@ class Product(AbstractStatusBoard):
|
|
127
122
|
class Application(AbstractStatusBoard):
|
128
123
|
product: Product
|
129
124
|
services: list["Service"] | None
|
130
|
-
metadata: dict[str, Any]
|
131
125
|
|
132
126
|
def create(self, ocm: OCMBaseClient) -> None:
|
133
127
|
if self.product.id:
|
@@ -137,11 +131,9 @@ class Application(AbstractStatusBoard):
|
|
137
131
|
logging.warning("Missing product id for application")
|
138
132
|
|
139
133
|
def update(self, ocm: OCMBaseClient) -> None:
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
spec = self.to_ocm_spec()
|
144
|
-
update_application(ocm, self.id, spec)
|
134
|
+
err_msg = "Called update on StatusBoardHandler that doesn't have update method"
|
135
|
+
logging.error(err_msg)
|
136
|
+
raise UpdateNotSupportedError(err_msg)
|
145
137
|
|
146
138
|
def delete(self, ocm: OCMBaseClient) -> None:
|
147
139
|
if not self.id:
|
@@ -157,7 +149,6 @@ class Application(AbstractStatusBoard):
|
|
157
149
|
return {
|
158
150
|
"name": self.name,
|
159
151
|
"fullname": self.fullname,
|
160
|
-
"metadata": self.metadata,
|
161
152
|
"product": {"id": product_id},
|
162
153
|
}
|
163
154
|
|
@@ -257,14 +248,12 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
257
248
|
return QONTRACT_INTEGRATION
|
258
249
|
|
259
250
|
@staticmethod
|
260
|
-
def get_product_apps(
|
261
|
-
sb: StatusBoardV1,
|
262
|
-
) -> dict[str, dict[str, dict[str, dict[str, set[str]]]]]:
|
251
|
+
def get_product_apps(sb: StatusBoardV1) -> dict[str, set[str]]:
|
263
252
|
global_selectors = (
|
264
253
|
sb.global_app_selectors.exclude or [] if sb.global_app_selectors else []
|
265
254
|
)
|
266
255
|
return {
|
267
|
-
p.product_environment.product.name:
|
256
|
+
p.product_environment.product.name: get_selected_app_names(
|
268
257
|
global_selectors, p
|
269
258
|
)
|
270
259
|
for p in sb.products
|
@@ -298,7 +287,7 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
298
287
|
|
299
288
|
@staticmethod
|
300
289
|
def desired_abstract_status_board_map(
|
301
|
-
desired_product_apps: Mapping[str,
|
290
|
+
desired_product_apps: Mapping[str, set[str]],
|
302
291
|
slodocs: list[SLODocumentV1],
|
303
292
|
) -> dict[str, AbstractStatusBoard]:
|
304
293
|
"""
|
@@ -310,11 +299,7 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
310
299
|
desired_abstract_status_board_map: dict[str, AbstractStatusBoard] = {}
|
311
300
|
for product_name, apps in desired_product_apps.items():
|
312
301
|
product = Product(
|
313
|
-
id=None,
|
314
|
-
name=product_name,
|
315
|
-
fullname=product_name,
|
316
|
-
applications=[],
|
317
|
-
metadata={},
|
302
|
+
id=None, name=product_name, fullname=product_name, applications=[]
|
318
303
|
)
|
319
304
|
desired_abstract_status_board_map[product_name] = product
|
320
305
|
for a in apps:
|
@@ -325,7 +310,6 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
325
310
|
fullname=key,
|
326
311
|
services=[],
|
327
312
|
product=product,
|
328
|
-
metadata=apps[a]["metadata"],
|
329
313
|
)
|
330
314
|
for slodoc in slodocs:
|
331
315
|
products = [
|
@@ -389,99 +373,6 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
389
373
|
|
390
374
|
return return_value
|
391
375
|
|
392
|
-
@staticmethod
|
393
|
-
def _compare_metadata(
|
394
|
-
current_metadata: dict[str, Any] | ServiceMetadataSpec,
|
395
|
-
desired_metadata: dict[str, Any] | ServiceMetadataSpec,
|
396
|
-
) -> bool:
|
397
|
-
"""
|
398
|
-
Compare metadata dictionaries with deep equality checking for nested structures.
|
399
|
-
|
400
|
-
:param current_metadata: The current metadata dictionary
|
401
|
-
:param desired_metadata: The desired metadata dictionary
|
402
|
-
:return: True if metadata are equal, False otherwise
|
403
|
-
"""
|
404
|
-
# Convert TypedDict to regular dict to allow variable key access
|
405
|
-
current_dict = dict(current_metadata)
|
406
|
-
desired_dict = dict(desired_metadata)
|
407
|
-
|
408
|
-
if current_dict.keys() != desired_dict.keys():
|
409
|
-
return False
|
410
|
-
|
411
|
-
for key, current_value in current_dict.items():
|
412
|
-
desired_value = desired_dict[key]
|
413
|
-
|
414
|
-
# Handle None values
|
415
|
-
if current_value is None or desired_value is None:
|
416
|
-
if current_value is not desired_value:
|
417
|
-
return False
|
418
|
-
continue
|
419
|
-
|
420
|
-
# Handle sets
|
421
|
-
if isinstance(current_value, set) and isinstance(desired_value, set):
|
422
|
-
if current_value != desired_value:
|
423
|
-
return False
|
424
|
-
# Handle lists and tuples
|
425
|
-
elif isinstance(current_value, (list, tuple)) and isinstance(
|
426
|
-
desired_value, (list, tuple)
|
427
|
-
):
|
428
|
-
if len(current_value) != len(desired_value):
|
429
|
-
return False
|
430
|
-
|
431
|
-
try:
|
432
|
-
sorted_current = sorted(current_value, key=repr)
|
433
|
-
sorted_desired = sorted(desired_value, key=repr)
|
434
|
-
except Exception:
|
435
|
-
# Fallback: compare without sorting
|
436
|
-
sorted_current = list(current_value)
|
437
|
-
sorted_desired = list(desired_value)
|
438
|
-
|
439
|
-
for c, d in zip(sorted_current, sorted_desired, strict=True):
|
440
|
-
if isinstance(c, dict) and isinstance(d, dict):
|
441
|
-
if not StatusBoardExporterIntegration._compare_metadata(c, d):
|
442
|
-
return False
|
443
|
-
elif isinstance(c, (list, tuple)) and isinstance(d, (list, tuple)):
|
444
|
-
if not StatusBoardExporterIntegration._compare_metadata(
|
445
|
-
{"x": c}, {"x": d}
|
446
|
-
):
|
447
|
-
return False
|
448
|
-
elif c != d:
|
449
|
-
return False
|
450
|
-
# Handle nested dictionaries
|
451
|
-
elif isinstance(current_value, dict) and isinstance(desired_value, dict):
|
452
|
-
if not StatusBoardExporterIntegration._compare_metadata(
|
453
|
-
current_value, desired_value
|
454
|
-
):
|
455
|
-
return False
|
456
|
-
# Handle primitive types
|
457
|
-
elif current_value != desired_value:
|
458
|
-
return False
|
459
|
-
|
460
|
-
return True
|
461
|
-
|
462
|
-
@staticmethod
|
463
|
-
def _status_board_objects_equal(
|
464
|
-
current: AbstractStatusBoard, desired: AbstractStatusBoard
|
465
|
-
) -> bool:
|
466
|
-
"""
|
467
|
-
Check if two AbstractStatusBoard objects are equal, including metadata comparison.
|
468
|
-
|
469
|
-
:param current: The current AbstractStatusBoard object
|
470
|
-
:param desired: The desired AbstractStatusBoard object
|
471
|
-
:return: True if objects are equal, False otherwise
|
472
|
-
"""
|
473
|
-
# Check basic equality first (name, fullname)
|
474
|
-
if current.name != desired.name or current.fullname != desired.fullname:
|
475
|
-
return False
|
476
|
-
|
477
|
-
# Compare metadata with deep equality
|
478
|
-
if current.metadata and desired.metadata:
|
479
|
-
return StatusBoardExporterIntegration._compare_metadata(
|
480
|
-
current.metadata, desired.metadata
|
481
|
-
)
|
482
|
-
else:
|
483
|
-
return True
|
484
|
-
|
485
376
|
@staticmethod
|
486
377
|
def get_diff(
|
487
378
|
desired_abstract_status_board_map: Mapping[str, AbstractStatusBoard],
|
@@ -492,7 +383,6 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
492
383
|
diff_result = diff_mappings(
|
493
384
|
current_abstract_status_board_map,
|
494
385
|
desired_abstract_status_board_map,
|
495
|
-
equal=StatusBoardExporterIntegration._status_board_objects_equal,
|
496
386
|
)
|
497
387
|
|
498
388
|
for pair in chain(diff_result.identical.values(), diff_result.change.values()):
|
@@ -508,18 +398,6 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
508
398
|
for o in diff_result.delete.values()
|
509
399
|
)
|
510
400
|
|
511
|
-
# Handle Applications that need updates (metadata changes)
|
512
|
-
applications_to_update = [
|
513
|
-
a.desired
|
514
|
-
for _, a in diff_result.change.items()
|
515
|
-
if isinstance(a.desired, Application)
|
516
|
-
]
|
517
|
-
|
518
|
-
return_list.extend(
|
519
|
-
StatusBoardHandler(action=Action.update, status_board_object=a)
|
520
|
-
for a in applications_to_update
|
521
|
-
)
|
522
|
-
|
523
401
|
services_to_update = [
|
524
402
|
s.desired
|
525
403
|
for _, s in diff_result.change.items()
|
@@ -567,9 +445,7 @@ class StatusBoardExporterIntegration(QontractReconcileIntegration):
|
|
567
445
|
ocm_api = init_ocm_base_client(sb.ocm, self.secret_reader)
|
568
446
|
|
569
447
|
# Desired state
|
570
|
-
desired_product_apps: dict[
|
571
|
-
str, dict[str, dict[str, dict[str, set[str]]]]
|
572
|
-
] = self.get_product_apps(sb)
|
448
|
+
desired_product_apps: dict[str, set[str]] = self.get_product_apps(sb)
|
573
449
|
desired_abstract_status_board_map = self.desired_abstract_status_board_map(
|
574
450
|
desired_product_apps, slodocs
|
575
451
|
)
|
@@ -9,10 +9,6 @@ from reconcile.gql_definitions.status_board.status_board import (
|
|
9
9
|
query,
|
10
10
|
)
|
11
11
|
from reconcile.utils import gql
|
12
|
-
from reconcile.utils.ocm.status_board import (
|
13
|
-
METADATA_MANAGED_BY_KEY,
|
14
|
-
METADATA_MANAGED_BY_VALUE,
|
15
|
-
)
|
16
12
|
|
17
13
|
|
18
14
|
def get_status_board(
|
@@ -23,11 +19,11 @@ def get_status_board(
|
|
23
19
|
return query(query_func).status_board_v1 or []
|
24
20
|
|
25
21
|
|
26
|
-
def
|
22
|
+
def get_selected_app_names(
|
27
23
|
global_selectors: Iterable[str],
|
28
24
|
product: StatusBoardProductV1,
|
29
|
-
) ->
|
30
|
-
|
25
|
+
) -> set[str]:
|
26
|
+
selected_app_names: set[str] = set()
|
31
27
|
|
32
28
|
apps: dict[str, Any] = {"apps": []}
|
33
29
|
for namespace in product.product_environment.namespaces or []:
|
@@ -35,45 +31,15 @@ def get_selected_app_data(
|
|
35
31
|
if namespace.app.parent_app:
|
36
32
|
prefix = f"{namespace.app.parent_app.name}-"
|
37
33
|
name = f"{prefix}{namespace.app.name}"
|
38
|
-
|
39
|
-
deployment_saas_files = set()
|
40
|
-
if namespace.app.saas_files:
|
41
|
-
deployment_saas_files = {
|
42
|
-
saas_file.name
|
43
|
-
for saas_file in namespace.app.saas_files
|
44
|
-
if "Deployment" in saas_file.managed_resource_types
|
45
|
-
or "ClowdApp" in saas_file.managed_resource_types
|
46
|
-
}
|
47
|
-
|
48
|
-
selected_app_data[name] = {
|
49
|
-
"metadata": {
|
50
|
-
METADATA_MANAGED_BY_KEY: METADATA_MANAGED_BY_VALUE,
|
51
|
-
"deploymentSaasFiles": set(deployment_saas_files),
|
52
|
-
},
|
53
|
-
}
|
54
|
-
|
34
|
+
selected_app_names.add(name)
|
55
35
|
app = namespace.app.dict(by_alias=True)
|
56
36
|
app["name"] = name
|
57
37
|
apps["apps"].append(app)
|
58
38
|
|
59
39
|
for child in namespace.app.children_apps or []:
|
60
40
|
name = f"{namespace.app.name}-{child.name}"
|
61
|
-
if name not in
|
62
|
-
|
63
|
-
if child.saas_files:
|
64
|
-
deployment_saas_files = {
|
65
|
-
saas_file.name
|
66
|
-
for saas_file in child.saas_files
|
67
|
-
if "Deployment" in saas_file.managed_resource_types
|
68
|
-
}
|
69
|
-
|
70
|
-
selected_app_data[name] = {
|
71
|
-
"metadata": {
|
72
|
-
METADATA_MANAGED_BY_KEY: METADATA_MANAGED_BY_VALUE,
|
73
|
-
"deploymentSaasFiles": set(deployment_saas_files),
|
74
|
-
},
|
75
|
-
}
|
76
|
-
|
41
|
+
if name not in selected_app_names:
|
42
|
+
selected_app_names.add(f"{namespace.app.name}-{child.name}")
|
77
43
|
child_dict = child.dict(by_alias=True)
|
78
44
|
child_dict["name"] = name
|
79
45
|
apps["apps"].append(child_dict)
|
@@ -86,7 +52,6 @@ def get_selected_app_data(
|
|
86
52
|
apps_to_remove: set[str] = set()
|
87
53
|
results = parser.parse(selector).find(apps)
|
88
54
|
apps_to_remove.update(match.value["name"] for match in results)
|
89
|
-
|
90
|
-
selected_app_data.pop(app_name, None)
|
55
|
+
selected_app_names -= apps_to_remove
|
91
56
|
|
92
|
-
return
|
57
|
+
return selected_app_names
|
@@ -21,7 +21,6 @@ class IDSpec(TypedDict):
|
|
21
21
|
|
22
22
|
|
23
23
|
class ApplicationOCMSpec(BaseOCMSpec):
|
24
|
-
metadata: dict[str, Any]
|
25
24
|
product: IDSpec
|
26
25
|
|
27
26
|
|
@@ -118,18 +117,6 @@ def create_service(ocm_api: OCMBaseClient, spec: ServiceOCMSpec) -> str:
|
|
118
117
|
return resp["id"]
|
119
118
|
|
120
119
|
|
121
|
-
def update_application(
|
122
|
-
ocm_api: OCMBaseClient,
|
123
|
-
application_id: str,
|
124
|
-
spec: ApplicationOCMSpec,
|
125
|
-
) -> None:
|
126
|
-
data = spec | {
|
127
|
-
"metadata": spec.get("metadata", {})
|
128
|
-
| {METADATA_MANAGED_BY_KEY: METADATA_MANAGED_BY_VALUE}
|
129
|
-
}
|
130
|
-
ocm_api.patch(f"/api/status-board/v1/applications/{application_id}", data=data)
|
131
|
-
|
132
|
-
|
133
120
|
def update_service(
|
134
121
|
ocm_api: OCMBaseClient,
|
135
122
|
service_id: str,
|
tools/qontract_cli.py
CHANGED
@@ -2772,7 +2772,7 @@ def slo_document_services(ctx: click.Context, status_board_instance: str) -> Non
|
|
2772
2772
|
print(f"Status-board instance '{status_board_instance}' not found.")
|
2773
2773
|
sys.exit(1)
|
2774
2774
|
|
2775
|
-
desired_product_apps: dict[str,
|
2775
|
+
desired_product_apps: dict[str, set[str]] = (
|
2776
2776
|
StatusBoardExporterIntegration.get_product_apps(sb)
|
2777
2777
|
)
|
2778
2778
|
|
{qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev304.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|