qontract-reconcile 0.10.1rc764__py3-none-any.whl → 0.10.1rc765__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.
Files changed (31) hide show
  1. {qontract_reconcile-0.10.1rc764.dist-info → qontract_reconcile-0.10.1rc765.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.1rc764.dist-info → qontract_reconcile-0.10.1rc765.dist-info}/RECORD +16 -31
  3. reconcile/saas_auto_promotions_manager/meta.py +1 -1
  4. reconcile/saas_auto_promotions_manager/subscriber.py +52 -2
  5. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +4 -0
  6. reconcile/test/saas_auto_promotions_manager/conftest.py +63 -0
  7. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -37
  8. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_desired_state.py +20 -14
  9. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -43
  10. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +4 -11
  11. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +12 -19
  12. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +6 -12
  13. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_json_path_selector.py +8 -15
  14. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  15. reconcile/test/saas_auto_promotions_manager/subscriber/__init__.py +0 -0
  16. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -89
  17. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  18. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -130
  19. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -161
  20. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -218
  21. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -216
  22. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_publishers_moving_ref.py +0 -129
  23. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -330
  24. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/__init__.py +0 -0
  25. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -68
  26. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -62
  27. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -73
  28. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -64
  29. {qontract_reconcile-0.10.1rc764.dist-info → qontract_reconcile-0.10.1rc765.dist-info}/WHEEL +0 -0
  30. {qontract_reconcile-0.10.1rc764.dist-info → qontract_reconcile-0.10.1rc765.dist-info}/entry_points.txt +0 -0
  31. {qontract_reconcile-0.10.1rc764.dist-info → qontract_reconcile-0.10.1rc765.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc764
3
+ Version: 0.10.1rc765
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
@@ -407,10 +407,10 @@ reconcile/rhidp/sso_client/integration.py,sha256=kA8g7c38ZBSdrRtyfEqy_WgSreD1Pbw
407
407
  reconcile/rhidp/sso_client/metrics.py,sha256=Tq7tSOsqL3XdcPUdozxqzSPIodUeOV87UCTqpuuqqhw,1013
408
408
  reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
409
409
  reconcile/saas_auto_promotions_manager/integration.py,sha256=shWQ--FWfeh_1rHJUwOWDiZWnvzKxYJYuRUIGQv22RI,6759
410
- reconcile/saas_auto_promotions_manager/meta.py,sha256=2b44ik-qpACNtW72QlDa2YOQqxeN8FHZfLPDmKoH3Rg,161
410
+ reconcile/saas_auto_promotions_manager/meta.py,sha256=jzqK6qM2JDdCE5kzkcj1e1TBMAL9f6lM2Hse8yFb8W8,161
411
411
  reconcile/saas_auto_promotions_manager/publisher.py,sha256=psrthZGgCQDUO3rwQjKSBMlwcTgfij6sxdebGuxkNv4,2739
412
412
  reconcile/saas_auto_promotions_manager/s3_exporter.py,sha256=IKlVWZmiPnvl7sKeF6JgAlhXZe5CovKTxQc0SNkNSx4,2583
413
- reconcile/saas_auto_promotions_manager/subscriber.py,sha256=cLhPlkT71J2LIice3SLmH1WpsqzV46gd0peMxrnqyRw,7452
413
+ reconcile/saas_auto_promotions_manager/subscriber.py,sha256=NPhlagNF8om7ikrjRlYNSQ2Ra7wgW_3-OlEWapnjtW0,9405
414
414
  reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
415
415
  reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py,sha256=jgfgKv4UTYFxtDao_JwNEGEKmu4GpeMm5vbaat0289c,1225
416
416
  reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=BeAJWLow7b4HQyZ9zz398sQkPeIz8chpMkCts2NU27c,1282
@@ -420,7 +420,7 @@ reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py,sha256
420
420
  reconcile/saas_auto_promotions_manager/merge_request_manager/reconciler.py,sha256=KZVAkFJR75Qu7-feV4mzg1S8ua-pkbuu1oC7PebSpDs,7801
421
421
  reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=iu0wMyyEvro5r5SBJVN3HGmVSIcxTyLN0Xxx3mhbYXE,7066
422
422
  reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
423
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=ZNxwqp9kdUSoxb3kTdM4KrtPyd3V5O4jMfjrVT2IJfs,7605
423
+ reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=7LlTQCzYotWCbtYBaNQP81CFlLUOvsyGMBQE-Ha0cKY,7820
424
424
  reconcile/skupper_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
425
425
  reconcile/skupper_network/integration.py,sha256=178Q9RSYuZ9NmrCK4jRMLMekrewUaaRdclccI6zBsQ8,10786
426
426
  reconcile/skupper_network/models.py,sha256=DNTI7HZv-rqY42GIIxyRuvroHLvdH6rJerjIq9lj3RU,6663
@@ -534,38 +534,23 @@ reconcile/test/test_version_bump.py,sha256=q6-3Y1roriI6YWpFwaHOMN7emEP3yL33sh_0V
534
534
  reconcile/test/test_vpc_peerings_validator.py,sha256=dFSmjc_dMN2GqMbntCFpa7PUZmyYuQ9DKffh-T5wmxM,6639
535
535
  reconcile/test/test_wrong_region.py,sha256=7KzL7OaICQ9Z3DW27zt_ykMN7_87owAFC-2CYjvGoyA,2138
536
536
  reconcile/test/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
537
- reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=tZNs35EuWulP53Cqt61RteOGY_uH4gfhtXfGQ8-awwM,3081
537
+ reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=4BtuxVZ0Lsmdp6AhG8kbtowkwG7e-pSjIKv35Wm1hI0,5803
538
538
  reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=x7QgHDMKIoPRY8k2SRSWa7qY3Z5Vabsyh9xWCtMXtfY,1857
539
539
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
540
540
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
541
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py,sha256=7O3lbk1EmEtUofqGncfiwMYvDPXrkQNPB59zlQ_zXkM,4588
541
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py,sha256=HikuDsdDxJ6HW48WY50s_7fmeGr07kcRdBZxgHzwc-0,3514
542
542
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py,sha256=Z1IV51OUuzhd-3S8W-k7ixC-fkaglCokn0eakK0Z73s,606
543
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_desired_state.py,sha256=x5DDZog0SA-Z8noxwalZniGtkovaPvR0V9Pqa5QaFFY,2302
543
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_desired_state.py,sha256=OLtJ11SsznoT39_tudsozcksK0N3TVNv-JWhIrCVaQk,2356
544
544
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py,sha256=h8lnorFPZIxTtbaaXGLoiEsBbB4Qj-Mg9BKV62ZqEBQ,2389
545
545
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_mr_parser.py,sha256=dcGHzxuafKSxmswSO1qF2WlKaqsmEvtERC6Lb8kDAN0,10019
546
546
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_reconciler.py,sha256=_bzfJzjFJgubu--7wyXIiusUrdbmLtFbHmkbat4SX_M,17828
547
547
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
548
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py,sha256=2rCSstewp4LPoEJHm5N7dGJexEtY8ndLHvoGZYjmpsc,1678
549
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py,sha256=beHYQ9kgDLeBZgC2FvxQA3tHx1PO-RAMN8_kVcSdikI,90
550
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py,sha256=mlsSuTKHTPEMDFmDJnpeZ5j9R0eZOK2KMj8kAm4nvRU,1116
551
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py,sha256=tS57UbNsJGb4kTnHNCPTfUEpLWwxprhtCeJOnvIt8A0,2527
552
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py,sha256=6g4s2c--W4l_PMTcCA_8aNM85YejwDZttQOz5Iowido,1908
553
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_json_path_selector.py,sha256=k_jA4x_9fRGGAT1T0aeAFiZwZ7zlDZpPPgqMDeuR7y8,2189
554
- reconcile/test/saas_auto_promotions_manager/subscriber/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
555
- reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py,sha256=5hMe91UEp_GQm49OeTee4ALv_xq2KhWwF6NfzzQwpnc,3101
556
- reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py,sha256=2j4Ue-njmK53Xm4vJScT2MJJeKV7wk9xf_95pmNfLWE,402
557
- reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py,sha256=viw-p42vDOC2telE5lelssRBL7V35aNJ1qUg6D-QGWw,4546
558
- reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py,sha256=BkxCoWBlUahY5Vq36FX_t_UyIdzIc64CumzAd3imUAQ,4529
559
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py,sha256=0MeFuJnKUHdMXGe8v2Fzge1mhihTcKqr2OAMLEAyHP4,6439
560
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py,sha256=rcF2tHltCsZiPQo23b-xjBuEqBHzVn4TMzHv_x0778o,6209
561
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_publishers_moving_ref.py,sha256=tGAjetYspWeevuuUCfbeU33noM-dP4lsb96UUAHkxWw,3588
562
- reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py,sha256=YDXCzrclRyKRW7qRBg9GB2HinJP_HPqzTcWMGD1rbFI,9452
548
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py,sha256=MjTLg7KwvdIYvxkCzgJG-gByD1fZxaq6c4SI6rWWUu8,552
549
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py,sha256=6LMsnbPx5svTF1nL6oQGLTp1NgjLG_tO56c0hbA2Di4,1059
550
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py,sha256=dc7vMOiVLl5yRUEfjF4eE7HfMZTbtT2dz1CMGJVLUZA,2526
551
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py,sha256=FY9pzmvE8uXvvt_P_G3M7_br8Zt1s428H23FlAj9nuY,1881
552
+ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_json_path_selector.py,sha256=jCtG0hVCqJ-A4XBjwexDww5LQUXJFRc44O5rEMA7_7E,2160
563
553
  reconcile/test/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
564
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
565
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py,sha256=jX8ade2615gRYiJ_Bui4F2kvv3rUyod5sdiMFhzcnsw,2168
566
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py,sha256=TThr7UeF8k7lNBeknknEcE4H9z-_K4jKdzNA_SqFKoY,1948
567
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py,sha256=OSSdVEQ72npDRrbkx5JHhXus-0ku699wG7ecsco4axM,2545
568
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py,sha256=6GoZ6ogpXBVYlRwag2wu9Z-1ES9LzyPxMqZkcX7oTA0,2040
569
554
  reconcile/typed_queries/__init__.py,sha256=rRk4CyslLsBr4vAh1pIPgt6s3P4R1M9NSEPLnyQgBpk,61
570
555
  reconcile/typed_queries/alerting_services_settings.py,sha256=sX6s8GY-BB0UHogMC1ICeREVab-IYrNm1c-hqMGEdYQ,864
571
556
  reconcile/typed_queries/app_interface_custom_messages.py,sha256=5HWr68_kb4bEL8pDCIH0ez6GOrdwdbGF6w88xV0_Ccs,718
@@ -797,8 +782,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
797
782
  tools/test/test_qontract_cli.py,sha256=w2l4BHB09k1d-BGJ1jBUNCqDv7zkqYrMHojQXg-21kQ,4155
798
783
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
799
784
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
800
- qontract_reconcile-0.10.1rc764.dist-info/METADATA,sha256=Eov5cvApy_dlSvDlyNdI1Uk8pAO7tJZfv4cOMjUfeEA,2382
801
- qontract_reconcile-0.10.1rc764.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
802
- qontract_reconcile-0.10.1rc764.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
803
- qontract_reconcile-0.10.1rc764.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
804
- qontract_reconcile-0.10.1rc764.dist-info/RECORD,,
785
+ qontract_reconcile-0.10.1rc765.dist-info/METADATA,sha256=jvfPojPDE35EHICj36iXRI8v0jcPR9pHsqy5dacJiVE,2382
786
+ qontract_reconcile-0.10.1rc765.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
787
+ qontract_reconcile-0.10.1rc765.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
788
+ qontract_reconcile-0.10.1rc765.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
789
+ qontract_reconcile-0.10.1rc765.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  from reconcile.utils.semver_helper import make_semver
2
2
 
3
3
  QONTRACT_INTEGRATION = "saas-auto-promotions-manager"
4
- QONTRACT_INTEGRATION_VERSION = make_semver(2, 1, 4)
4
+ QONTRACT_INTEGRATION_VERSION = make_semver(2, 2, 0)
@@ -1,8 +1,8 @@
1
1
  import hashlib
2
2
  import logging
3
- from collections.abc import Iterable
3
+ from collections.abc import Iterable, Mapping
4
4
  from dataclasses import dataclass
5
- from typing import Optional
5
+ from typing import Any, Optional
6
6
 
7
7
  from reconcile.gql_definitions.fragments.saas_target_namespace import (
8
8
  SaasTargetNamespace,
@@ -42,6 +42,7 @@ class Subscriber:
42
42
  target_file_path: str,
43
43
  target_namespace: SaasTargetNamespace,
44
44
  use_target_config_hash: bool,
45
+ uid: str,
45
46
  ):
46
47
  self.saas_name = saas_name
47
48
  self.template_name = template_name
@@ -52,6 +53,7 @@ class Subscriber:
52
53
  self.desired_ref = ""
53
54
  self.desired_hashes: list[ConfigHash] = []
54
55
  self.target_namespace = target_namespace
56
+ self.uid = uid
55
57
  self._content_hash = ""
56
58
  self._use_target_config_hash = use_target_config_hash
57
59
 
@@ -73,6 +75,54 @@ class Subscriber:
73
75
  self._compute_desired_ref()
74
76
  self._compute_desired_config_hashes()
75
77
 
78
+ @staticmethod
79
+ def from_exported_dict(data: Mapping[str, Any]) -> "Subscriber":
80
+ subscriber = Subscriber(
81
+ saas_name=data["1"],
82
+ template_name=data["2"],
83
+ ref=data["3"],
84
+ target_file_path=data["4"],
85
+ use_target_config_hash=data["5"],
86
+ target_namespace=SaasTargetNamespace(**data["6"]),
87
+ uid=data["7"],
88
+ )
89
+ subscriber.desired_hashes = data["8"]
90
+ subscriber.desired_ref = data["9"]
91
+ return subscriber
92
+
93
+ def to_exportable_dict(self) -> dict[str, Any]:
94
+ """
95
+ We will later persist subscriber data as json in MRs. We keep key size small to use less space.
96
+ Note, the data will be encoded and encrypted in another component.
97
+ """
98
+ data: dict[str, Any] = {}
99
+ data["1"] = self.saas_name
100
+ data["2"] = self.template_name
101
+ data["3"] = self.ref
102
+ data["4"] = self.target_file_path
103
+ data["5"] = self._use_target_config_hash
104
+ data["6"] = self.target_namespace.dict(by_alias=True)
105
+ data["7"] = self.uid
106
+ data["8"] = self.desired_hashes
107
+ data["9"] = self.desired_ref
108
+ return data
109
+
110
+ def __eq__(self, other: object) -> bool:
111
+ if not isinstance(other, Subscriber):
112
+ # don't attempt to compare against unrelated types
113
+ return False
114
+ return (
115
+ self.saas_name == other.saas_name
116
+ and self.template_name == other.template_name
117
+ and self.ref == other.ref
118
+ and self.target_file_path == other.target_file_path
119
+ and self._use_target_config_hash == other._use_target_config_hash
120
+ and self.desired_ref == other.desired_ref
121
+ and self.desired_hashes == other.desired_hashes
122
+ and self.target_namespace == other.target_namespace
123
+ and self.uid == other.uid
124
+ )
125
+
76
126
  def _validate_deployment(
77
127
  self, publisher: Publisher, channel: Channel
78
128
  ) -> Optional[DeploymentInfo]:
@@ -92,6 +92,10 @@ class SaasFilesInventory:
92
92
  if not target.promotion.auto:
93
93
  continue
94
94
  subscriber = Subscriber(
95
+ uid=target.uid(
96
+ parent_saas_file_name=saas_file.name,
97
+ parent_resource_template_name=resource_template.name,
98
+ ),
95
99
  saas_name=saas_file.name,
96
100
  template_name=resource_template.name,
97
101
  target_file_path=file_path,
@@ -1,9 +1,11 @@
1
+ from collections import defaultdict
1
2
  from collections.abc import (
2
3
  Callable,
3
4
  Iterable,
4
5
  Mapping,
5
6
  MutableMapping,
6
7
  )
8
+ from typing import Any
7
9
  from unittest.mock import (
8
10
  MagicMock,
9
11
  create_autospec,
@@ -14,6 +16,12 @@ import pytest
14
16
  from reconcile.gql_definitions.fragments.saas_target_namespace import (
15
17
  SaasTargetNamespace,
16
18
  )
19
+ from reconcile.saas_auto_promotions_manager.publisher import DeploymentInfo, Publisher
20
+ from reconcile.saas_auto_promotions_manager.subscriber import (
21
+ Channel,
22
+ ConfigHash,
23
+ Subscriber,
24
+ )
17
25
  from reconcile.typed_queries.saas_files import SaasFile
18
26
  from reconcile.utils.gitlab_api import GitLabApi
19
27
  from reconcile.utils.promotion_state import (
@@ -100,3 +108,58 @@ def promotion_state_builder() -> Callable[..., PromotionState]:
100
108
  return promotion_state
101
109
 
102
110
  return builder
111
+
112
+
113
+ @pytest.fixture
114
+ def subscriber_builder(
115
+ saas_target_namespace_builder: Callable[..., SaasTargetNamespace],
116
+ ) -> Callable[[Mapping[str, Any]], Subscriber]:
117
+ def builder(data: Mapping[str, Any]) -> Subscriber:
118
+ channels: list[Channel] = []
119
+ for channel_name, channel_data in data.get("CHANNELS", {}).items():
120
+ channel = Channel(name=channel_name, publishers=[])
121
+ for publisher_name, publisher_data in channel_data.items():
122
+ publisher = Publisher(
123
+ ref="",
124
+ uid="",
125
+ repo_url="",
126
+ cluster_name="",
127
+ namespace_name="",
128
+ saas_name="",
129
+ saas_file_path="",
130
+ app_name="",
131
+ resource_template_name="",
132
+ target_name=None,
133
+ publish_job_logs=True,
134
+ has_subscriber=True,
135
+ auth_code=None,
136
+ )
137
+ publisher.commit_sha = publisher_data["REAL_WORLD_SHA"]
138
+ publisher.deployment_info_by_channel[channel_name] = DeploymentInfo(
139
+ success=publisher_data.get("SUCCESSFUL_DEPLOYMENT", True),
140
+ target_config_hash=publisher_data.get("CONFIG_HASH", ""),
141
+ saas_file=publisher_name,
142
+ )
143
+ channel.publishers.append(publisher)
144
+ channels.append(channel)
145
+ cur_config_hashes_by_channel: dict[str, list[ConfigHash]] = defaultdict(list)
146
+ for cur_config_hash in data.get("CUR_CONFIG_HASHES", []):
147
+ cur_config_hashes_by_channel[cur_config_hash.channel].append(
148
+ cur_config_hash
149
+ )
150
+ subscriber = Subscriber(
151
+ uid=data.get("SUB_UID", "default"),
152
+ target_namespace=saas_target_namespace_builder(data.get("NAMESPACE", {})),
153
+ ref=data.get("CUR_SUBSCRIBER_REF", ""),
154
+ saas_name="",
155
+ target_file_path=data.get("TARGET_FILE_PATH", ""),
156
+ template_name="",
157
+ use_target_config_hash=data.get("USE_TARGET_CONFIG_HASH", True),
158
+ )
159
+ subscriber.channels = channels
160
+ subscriber.config_hashes_by_channel_name = cur_config_hashes_by_channel
161
+ subscriber.desired_ref = data.get("DESIRED_REF", "")
162
+ subscriber.desired_hashes = data.get("DESIRED_TARGET_HASHES", [])
163
+ return subscriber
164
+
165
+ return builder
@@ -8,9 +8,6 @@ from unittest.mock import create_autospec
8
8
  import pytest
9
9
  from gitlab.v4.objects import ProjectMergeRequest
10
10
 
11
- from reconcile.gql_definitions.fragments.saas_target_namespace import (
12
- SaasTargetNamespace,
13
- )
14
11
  from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager_v2 import (
15
12
  SAPM_LABEL,
16
13
  )
@@ -31,24 +28,17 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer impor
31
28
  VERSION_REF,
32
29
  Renderer,
33
30
  )
34
- from reconcile.saas_auto_promotions_manager.subscriber import (
35
- Channel,
36
- Subscriber,
37
- )
38
31
  from reconcile.utils.vcs import VCS, MRCheckStatus
39
32
 
40
33
  from .data_keys import (
41
- CHANNEL,
42
34
  DESCRIPTION,
43
35
  HAS_CONFLICTS,
44
36
  LABELS,
45
37
  OPEN_MERGE_REQUESTS,
46
38
  PIPELINE_RESULTS,
47
- REF,
48
39
  SUBSCRIBER_BATCHABLE,
49
40
  SUBSCRIBER_CHANNELS,
50
41
  SUBSCRIBER_CONTENT_HASH,
51
- SUBSCRIBER_TARGET_PATH,
52
42
  )
53
43
 
54
44
 
@@ -120,33 +110,6 @@ def reconciler_builder() -> Callable[[Diff], Reconciler]:
120
110
  return builder
121
111
 
122
112
 
123
- @pytest.fixture
124
- def subscriber_builder(
125
- saas_target_namespace_builder: Callable[..., SaasTargetNamespace],
126
- ) -> Callable[..., Subscriber]:
127
- def builder(data: Mapping) -> Subscriber:
128
- subscriber = Subscriber(
129
- saas_name="",
130
- template_name="",
131
- target_namespace=saas_target_namespace_builder({}),
132
- ref="",
133
- target_file_path=data.get(SUBSCRIBER_TARGET_PATH, ""),
134
- use_target_config_hash=True,
135
- )
136
- subscriber.desired_hashes = []
137
- subscriber.desired_ref = data.get(REF, "")
138
- for channel in data.get(CHANNEL, []):
139
- subscriber.channels.append(
140
- Channel(
141
- name=channel,
142
- publishers=[],
143
- )
144
- )
145
- return subscriber
146
-
147
- return builder
148
-
149
-
150
113
  @pytest.fixture
151
114
  def renderer() -> Renderer:
152
115
  return create_autospec(spec=Renderer)
@@ -5,10 +5,6 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.desired_state
5
5
  )
6
6
  from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
7
7
 
8
- from .data_keys import (
9
- CHANNEL,
10
- )
11
-
12
8
 
13
9
  def test_desired_state_empty() -> None:
14
10
  desired_state = DesiredState(subscribers=[])
@@ -29,10 +25,14 @@ def test_desired_state_single_subscriber(
29
25
  def test_desired_state_multiple_subscribers_same_channel_combo(
30
26
  subscriber_builder: Callable[..., Subscriber],
31
27
  ) -> None:
32
- subscriber_a = subscriber_builder({CHANNEL: ["channel-a", "channel-b"]})
33
- subscriber_a.desired_ref = "ref-a"
34
- subscriber_b = subscriber_builder({CHANNEL: ["channel-a", "channel-b"]})
35
- subscriber_b.desired_ref = "ref-b"
28
+ subscriber_a = subscriber_builder({
29
+ "CHANNELS": {"channel-a": {}, "channel-b": {}},
30
+ "DESIRED_REF": "ref-a",
31
+ })
32
+ subscriber_b = subscriber_builder({
33
+ "CHANNELS": {"channel-a": {}, "channel-b": {}},
34
+ "DESIRED_REF": "ref-b",
35
+ })
36
36
  desired_state = DesiredState(subscribers=[subscriber_a, subscriber_b])
37
37
  assert len(desired_state.promotions) == 1
38
38
  assert desired_state.promotions[0].content_hashes == {
@@ -43,12 +43,18 @@ def test_desired_state_multiple_subscribers_same_channel_combo(
43
43
  def test_desired_state_multiple_subscribers_different_channel_combo(
44
44
  subscriber_builder: Callable[..., Subscriber],
45
45
  ) -> None:
46
- subscriber_a = subscriber_builder({CHANNEL: ["channel-a", "channel-b"]})
47
- subscriber_a.desired_ref = "ref-a"
48
- subscriber_b = subscriber_builder({CHANNEL: ["channel-a", "channel-b"]})
49
- subscriber_b.desired_ref = "ref-b"
50
- subscriber_c = subscriber_builder({CHANNEL: ["channel-b", "channel-c"]})
51
- subscriber_c.desired_ref = "ref-c"
46
+ subscriber_a = subscriber_builder({
47
+ "CHANNELS": {"channel-a": {}, "channel-b": {}},
48
+ "DESIRED_REF": "ref-a",
49
+ })
50
+ subscriber_b = subscriber_builder({
51
+ "CHANNELS": {"channel-a": {}, "channel-b": {}},
52
+ "DESIRED_REF": "ref-b",
53
+ })
54
+ subscriber_c = subscriber_builder({
55
+ "CHANNELS": {"channel-b": {}, "channel-c": {}},
56
+ "DESIRED_REF": "ref-c",
57
+ })
52
58
  desired_state = DesiredState(subscribers=[subscriber_a, subscriber_b, subscriber_c])
53
59
  sorted_promotions = sorted(desired_state.promotions)
54
60
  assert len(desired_state.promotions) == 2
@@ -1,26 +1,10 @@
1
1
  import os
2
2
  from collections.abc import (
3
3
  Callable,
4
- Mapping,
5
4
  )
6
5
 
7
6
  import pytest
8
7
 
9
- from reconcile.gql_definitions.fragments.saas_target_namespace import (
10
- SaasTargetNamespace,
11
- )
12
- from reconcile.saas_auto_promotions_manager.subscriber import (
13
- Channel,
14
- Subscriber,
15
- )
16
-
17
- from .data_keys import (
18
- CHANNELS,
19
- CONFIG_HASHES,
20
- NAMESPACE,
21
- REF,
22
- )
23
-
24
8
 
25
9
  @pytest.fixture
26
10
  def file_contents() -> Callable[[str], tuple[str, str]]:
@@ -39,30 +23,3 @@ def file_contents() -> Callable[[str], tuple[str, str]]:
39
23
  return (a, b)
40
24
 
41
25
  return contents
42
-
43
-
44
- @pytest.fixture
45
- def subscriber_builder(
46
- saas_target_namespace_builder: Callable[..., SaasTargetNamespace],
47
- ) -> Callable[[Mapping], Subscriber]:
48
- def builder(data: Mapping) -> Subscriber:
49
- subscriber = Subscriber(
50
- target_namespace=saas_target_namespace_builder(data.get(NAMESPACE, {})),
51
- ref="",
52
- saas_name="",
53
- target_file_path="",
54
- template_name="",
55
- use_target_config_hash=True,
56
- )
57
- subscriber.desired_ref = data[REF]
58
- subscriber.desired_hashes = data[CONFIG_HASHES]
59
- for channel in data.get(CHANNELS, []):
60
- subscriber.channels.append(
61
- Channel(
62
- name=channel,
63
- publishers=[],
64
- )
65
- )
66
- return subscriber
67
-
68
- return builder
@@ -11,29 +11,22 @@ from reconcile.saas_auto_promotions_manager.subscriber import (
11
11
  Subscriber,
12
12
  )
13
13
 
14
- from .data_keys import (
15
- CHANNELS,
16
- CONFIG_HASHES,
17
- NAMESPACE,
18
- REF,
19
- )
20
-
21
14
 
22
15
  def test_content_multiple_namespaces(
23
16
  file_contents: Callable[[str], tuple[str, str]],
24
17
  subscriber_builder: Callable[[Mapping], Subscriber],
25
18
  ):
26
19
  subscriber = subscriber_builder({
27
- NAMESPACE: {"path": "/some/namespace.yml"},
28
- REF: "new_sha",
29
- CONFIG_HASHES: [
20
+ "NAMESPACE": {"path": "/some/namespace.yml"},
21
+ "DESIRED_REF": "new_sha",
22
+ "DESIRED_TARGET_HASHES": [
30
23
  ConfigHash(
31
24
  channel="channel-a",
32
25
  target_config_hash="new_hash",
33
26
  parent_saas="parent_saas",
34
27
  )
35
28
  ],
36
- CHANNELS: ["channel-a"],
29
+ "CHANNELS": {"channel-a": {}},
37
30
  })
38
31
  saas_content, expected = file_contents("multiple_namespaces")
39
32
  renderer = Renderer()
@@ -11,29 +11,22 @@ from reconcile.saas_auto_promotions_manager.subscriber import (
11
11
  Subscriber,
12
12
  )
13
13
 
14
- from .data_keys import (
15
- CHANNELS,
16
- CONFIG_HASHES,
17
- NAMESPACE,
18
- REF,
19
- )
20
-
21
14
 
22
15
  def test_content_single_namespace(
23
16
  file_contents: Callable[[str], tuple[str, str]],
24
17
  subscriber_builder: Callable[[Mapping], Subscriber],
25
18
  ):
26
19
  subscriber = subscriber_builder({
27
- NAMESPACE: {"path": "/some/namespace.yml"},
28
- REF: "new_sha",
29
- CONFIG_HASHES: [
20
+ "NAMESPACE": {"path": "/some/namespace.yml"},
21
+ "DESIRED_REF": "new_sha",
22
+ "DESIRED_TARGET_HASHES": [
30
23
  ConfigHash(
31
24
  channel="channel-a",
32
25
  target_config_hash="current_hash",
33
26
  parent_saas="parent_saas",
34
27
  )
35
28
  ],
36
- CHANNELS: ["channel-a"],
29
+ "CHANNELS": {"channel-a": {}},
37
30
  })
38
31
  saas_content, expected = file_contents("single_namespace")
39
32
  renderer = Renderer()
@@ -49,16 +42,16 @@ def test_content_single_namespace_no_previous_hash(
49
42
  subscriber_builder: Callable[[Mapping], Subscriber],
50
43
  ):
51
44
  subscriber = subscriber_builder({
52
- NAMESPACE: {"path": "/some/namespace.yml"},
53
- REF: "new_sha",
54
- CONFIG_HASHES: [
45
+ "NAMESPACE": {"path": "/some/namespace.yml"},
46
+ "DESIRED_REF": "new_sha",
47
+ "DESIRED_TARGET_HASHES": [
55
48
  ConfigHash(
56
49
  channel="channel-a",
57
50
  target_config_hash="new_hash",
58
51
  parent_saas="parent_saas",
59
52
  )
60
53
  ],
61
- CHANNELS: ["channel-a"],
54
+ "CHANNELS": {"channel-a": {}},
62
55
  })
63
56
  saas_content, expected = file_contents("single_namespace_no_hash")
64
57
  renderer = Renderer()
@@ -74,10 +67,10 @@ def test_content_single_namespace_no_desired_hash(
74
67
  subscriber_builder: Callable[[Mapping], Subscriber],
75
68
  ):
76
69
  subscriber = subscriber_builder({
77
- NAMESPACE: {"path": "/some/namespace.yml"},
78
- REF: "new_sha",
79
- CONFIG_HASHES: [],
80
- CHANNELS: ["channel-a"],
70
+ "NAMESPACE": {"path": "/some/namespace.yml"},
71
+ "DESIRED_REF": "new_sha",
72
+ "DESIRED_TARGET_HASHES": [],
73
+ "CHANNELS": {"channel-a": {}},
81
74
  })
82
75
  saas_content, expected = file_contents("single_namespace_ignore_hash")
83
76
  renderer = Renderer()
@@ -11,21 +11,15 @@ from reconcile.saas_auto_promotions_manager.subscriber import (
11
11
  Subscriber,
12
12
  )
13
13
 
14
- from .data_keys import (
15
- CONFIG_HASHES,
16
- NAMESPACE,
17
- REF,
18
- )
19
-
20
14
 
21
15
  def test_content_single_target(
22
16
  file_contents: Callable[[str], tuple[str, str]],
23
17
  subscriber_builder: Callable[[Mapping], Subscriber],
24
18
  ):
25
19
  subscriber = subscriber_builder({
26
- NAMESPACE: {"path": "/some/namespace.yml"},
27
- REF: "new_sha",
28
- CONFIG_HASHES: [
20
+ "NAMESPACE": {"path": "/some/namespace.yml"},
21
+ "DESIRED_REF": "new_sha",
22
+ "DESIRED_TARGET_HASHES": [
29
23
  ConfigHash(
30
24
  channel="channel-a",
31
25
  target_config_hash="new_hash",
@@ -48,9 +42,9 @@ def test_must_not_line_wrap(
48
42
  ):
49
43
  namespace_name = "/services/sosososolong/namespaces/loooooooooooooooooooooooooooooooooooooooooooooooooooooooooong.yml"
50
44
  subscriber = subscriber_builder({
51
- NAMESPACE: {"path": namespace_name},
52
- REF: "new_sha",
53
- CONFIG_HASHES: [
45
+ "NAMESPACE": {"path": namespace_name},
46
+ "DESIRED_REF": "new_sha",
47
+ "DESIRED_TARGET_HASHES": [
54
48
  ConfigHash(
55
49
  channel="channel-a",
56
50
  target_config_hash="new_hash",