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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev303
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
@@ -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=Wt8aqCmhTbKxRa9GUj5U_aoqif18z9XL5hRK3zy8too,20091
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=qm7TkvvBvkMvf_9SQ50wz8ke8LEvwZYQjMkUDrN-BV0,5370
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=ghu3jRJVzEPm5qHQUJWSCGLUdQzBcrtxU4mEeCCdXjo,3091
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=1T9iD3DxWiVlY_8sK94twH01j_WrUbh-A2FC9dpXYPE,4548
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=oOyvoY5-9UzLZbl7iUhENVs8DSH4bORbG90Dxww8GrQ,159925
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.dev303.dist-info/METADATA,sha256=-71qdSLUInk-owzDEw5ShwjQ96x3W206KgjWZ2E4VxQ,24916
800
- qontract_reconcile-0.10.2.dev303.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
801
- qontract_reconcile-0.10.2.dev303.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
802
- qontract_reconcile-0.10.2.dev303.dist-info/RECORD,,
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
- get_selected_app_data,
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
- if not self.id:
141
- logging.error(f'Trying to update Application "{self.name}" without id')
142
- return
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: get_selected_app_data(
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, dict[str, dict[str, dict[str, set[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 get_selected_app_data(
22
+ def get_selected_app_names(
27
23
  global_selectors: Iterable[str],
28
24
  product: StatusBoardProductV1,
29
- ) -> dict[str, dict[str, dict[str, set[str]]]]:
30
- selected_app_data: dict[str, dict[str, dict[str, Any]]] = {}
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 selected_app_data:
62
- deployment_saas_files = set()
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
- for app_name in apps_to_remove:
90
- selected_app_data.pop(app_name, None)
55
+ selected_app_names -= apps_to_remove
91
56
 
92
- return selected_app_data
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, dict[str, dict[str, dict[str, set[str]]]]] = (
2775
+ desired_product_apps: dict[str, set[str]] = (
2776
2776
  StatusBoardExporterIntegration.get_product_apps(sb)
2777
2777
  )
2778
2778