qontract-reconcile 0.10.1rc47__py3-none-any.whl → 0.10.1rc48__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.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/RECORD +18 -18
- reconcile/saas_auto_promotions_manager/publisher.py +10 -0
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +2 -38
- reconcile/test/saas_auto_promotions_manager/conftest.py +5 -0
- reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +1 -0
- reconcile/test/saas_auto_promotions_manager/test_integration_test.py +12 -0
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +1 -3
- reconcile/test/test_auto_promoter.py +15 -6
- reconcile/test/test_saasherder.py +8 -3
- reconcile/typed_queries/saas_files.py +29 -1
- reconcile/utils/promotion_state.py +32 -9
- reconcile/utils/saasherder/interfaces.py +5 -1
- reconcile/utils/saasherder/models.py +1 -0
- reconcile/utils/saasherder/saasherder.py +6 -1
- {qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.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.1rc48
|
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
|
@@ -266,14 +266,14 @@ reconcile/prometheus_rules_tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
266
266
|
reconcile/prometheus_rules_tester/integration.py,sha256=Sn6mjzC2lJQVcETS1J2Z3tOwm8M3DDW-1GVT-5ccNuA,8860
|
267
267
|
reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
268
268
|
reconcile/saas_auto_promotions_manager/integration.py,sha256=hmRWva3_ZEO845wMkttEt4X6Izl5p8ZKs09NXWp8mkY,5609
|
269
|
-
reconcile/saas_auto_promotions_manager/publisher.py,sha256=
|
269
|
+
reconcile/saas_auto_promotions_manager/publisher.py,sha256=8uh7YnR2IPkzJHSxMwvt_iFOnEn6JAHFz2UqLZ86qb8,2338
|
270
270
|
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=8w9q1ceA2XnuTntThg8v6mE3K28aG2Y2DwQSuTudkns,6942
|
271
271
|
reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
272
272
|
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=PNu7sE-tDUY61E03z5w0b93fdowZ8auCl0S4_vhYOKQ,1333
|
273
273
|
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py,sha256=SNJ9WLlaFnf_tblwC0xDBfrXi4SVadeFgV3llhTqbGM,10959
|
274
274
|
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=Ye3lmfWTbuHjMoCEOpGnGRK3QU0LwB_LVfnPXFdNxf4,4702
|
275
275
|
reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
276
|
-
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=
|
276
|
+
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=At9VXApH6n0R7DZoGxMUQ81JUzOQO3Ouf7csbBE14AA,6637
|
277
277
|
reconcile/saas_auto_promotions_manager/utils/vcs.py,sha256=wIB3DUazVpmysKuKmHZZ_yG9d04givRBulXrUuZyOgw,5240
|
278
278
|
reconcile/skupper_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
279
279
|
reconcile/skupper_network/integration.py,sha256=Xps2zaD80FY_e-2vl_skybhuzQmqaC8zQQOY7K1s78o,10746
|
@@ -295,7 +295,7 @@ reconcile/test/conftest.py,sha256=dBWwQMkcdONERlnBJg4J6Td5Fexpbvme5y-UuoI-c9M,31
|
|
295
295
|
reconcile/test/fixtures.py,sha256=VhvLXH0AWXEyu3FgPp7bcSTPmDPfMEa2v-_9cd8dCmw,572
|
296
296
|
reconcile/test/test_aggregated_list.py,sha256=iiWitQuNYC58aimWaiBoE4NROHjr1NCgQ91MnHEG_Ro,6412
|
297
297
|
reconcile/test/test_amtool.py,sha256=vxRhGieeydMBOb9UI2ziMHjJa8puMeGNsUhGhy-yMnk,1032
|
298
|
-
reconcile/test/test_auto_promoter.py,sha256=
|
298
|
+
reconcile/test/test_auto_promoter.py,sha256=unvv6F7vwIB_V0FG-G9rGmVVxDLQ2m6bWSnypB5q7Ek,10864
|
299
299
|
reconcile/test/test_aws_ami_share.py,sha256=eSITdDoXs8mMY7P2lFxAX2DA0sJ9RW6D1tG8Rek0gLE,1981
|
300
300
|
reconcile/test/test_aws_iam_keys.py,sha256=MfE9EvItyPNPAl5QaLlJFUvvrZFiar518TM2wWNjJn4,1829
|
301
301
|
reconcile/test/test_aws_iam_password_reset.py,sha256=fnkqB90adR7W4L4saNdrtIiwnQB9bXgqJ9R1CKxjSnk,860
|
@@ -340,7 +340,7 @@ reconcile/test/test_quay_repos.py,sha256=TdkcRF_a8PLp01Kti9eZZN-vGup2yPBT4Iba3k0
|
|
340
340
|
reconcile/test/test_queries.py,sha256=SpH3RmNpBjEr_ne3VjAMCgKK8RE1z1zo7bypkT5uoO4,1946
|
341
341
|
reconcile/test/test_repo_owners.py,sha256=uRYMLbMmh-9usF0TerabZTZV-Z1CS4I6ybT-LQqCLe8,1423
|
342
342
|
reconcile/test/test_requests_sender.py,sha256=7fd9C2kEFS0-CYtlsif66N1kO9c44pzuBPAJKR9igqU,5385
|
343
|
-
reconcile/test/test_saasherder.py,sha256=
|
343
|
+
reconcile/test/test_saasherder.py,sha256=cZ5SN93furNduYOjdsEZdra-Vo9n9yfG23k2J7k_SZM,37609
|
344
344
|
reconcile/test/test_saasherder_allowed_secret_paths.py,sha256=86ffYbbN0Xng8CTiXf3yR_3VD8qyqRpVTByJFycdXp0,4899
|
345
345
|
reconcile/test/test_secret_reader.py,sha256=kz7nzcPjvA08cytnvcA_PMA98AEyqJWsESkYeRn5xCk,4994
|
346
346
|
reconcile/test/test_slack_base.py,sha256=UqMjYt4hPmStJfog06qwJM_afbf-E9uzy-GX741KgTY,5058
|
@@ -401,8 +401,8 @@ reconcile/test/test_version_bump.py,sha256=q6-3Y1roriI6YWpFwaHOMN7emEP3yL33sh_0V
|
|
401
401
|
reconcile/test/test_vpc_peerings_validator.py,sha256=j4MlmIoGptMJsYNfJAChHRkilSxtqBEUJBQhL6Uqfmo,3710
|
402
402
|
reconcile/test/test_wrong_region.py,sha256=7KzL7OaICQ9Z3DW27zt_ykMN7_87owAFC-2CYjvGoyA,2138
|
403
403
|
reconcile/test/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
404
|
-
reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=
|
405
|
-
reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=
|
404
|
+
reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=DodxMN_hjE3GU7G_k5RYjAoc4Iu1vp0WiE_ISQEG9YA,2382
|
405
|
+
reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=8eW0kWCgwCs1gGEkzqKoG77z0Z9HMWpALYoK0iNl5DQ,5164
|
406
406
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
407
407
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
408
408
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py,sha256=LGEsqcjs4O4i29LJ0I7g8-uBog1QKFRGA5-8rSfrks0,3302
|
@@ -416,7 +416,7 @@ reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_
|
|
416
416
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py,sha256=w8BT3Z_M7Jz0Xn1OINWypWjmSGMBDGgjt_zY_3iOJoM,2667
|
417
417
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py,sha256=cwAPrQ_v3DR_CHU7Nt2xBGutC-1XslyJ5mXM8FXW-3o,1111
|
418
418
|
reconcile/test/saas_auto_promotions_manager/subscriber/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
419
|
-
reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py,sha256=
|
419
|
+
reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py,sha256=05BZqP5tapjhlcLD0teasbNO1DzBo_xoGhZdxebbWK8,2559
|
420
420
|
reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py,sha256=xaGGbeWtq0aYlJxC-7wJvX3yWnqDSNYMeR0h5rsYAh0,410
|
421
421
|
reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py,sha256=6Nkyix3Uyf7Zd9t2C6RnYlQG_y3NsZ6v6zu3G-qF4to,5186
|
422
422
|
reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py,sha256=naArIa1AZj8iaDjzJoYwLX5PqrSNakqsBXonOHEQ0PA,4957
|
@@ -425,7 +425,7 @@ reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_mo
|
|
425
425
|
reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py,sha256=zIkUg-Vx-Em0-0JY_zC1N3Of_PaB-8GRSqsW5FXLkM8,10244
|
426
426
|
reconcile/test/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
427
427
|
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
428
|
-
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py,sha256=
|
428
|
+
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py,sha256=1O1F-BVWAgcrfPJ7QDpMeQcrZRB0eWa9jCzDZ_o7QS8,2309
|
429
429
|
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py,sha256=qC_GapxJxfTEZ0o5xYuI4BA0cRcX4QLgtlW5MY691nw,2066
|
430
430
|
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py,sha256=F3ZGLzNa821yUw68YH9bA1cQEV82_hQxfPjkuJ-ELWw,2707
|
431
431
|
reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py,sha256=6EYKmXDN9ckkMvdUBZlUiunCKuwQ9UmnPijKvXU8iZo,2170
|
@@ -445,7 +445,7 @@ reconcile/typed_queries/namespaces_minimal.py,sha256=rUtqNQ0ORXXUTQfnpsMURymAJ4g
|
|
445
445
|
reconcile/typed_queries/ocp_release_mirror.py,sha256=jwX29Tcdvov8oEDNkE4t1j-2Hz8QJrjg9ITppP-panQ,313
|
446
446
|
reconcile/typed_queries/pagerduty_instances.py,sha256=QCHqEAakiH6eSob0Pnnn3IBd8Ga0zpEp1Z6Qu3v2uH4,733
|
447
447
|
reconcile/typed_queries/repos.py,sha256=RKBsf7IDS6NsXTtXxJ9Ol9G3bxG9sr3vW9QQ2bahEHo,512
|
448
|
-
reconcile/typed_queries/saas_files.py,sha256=
|
448
|
+
reconcile/typed_queries/saas_files.py,sha256=XU4nzvcD3kUT4Aw-mrupWESc6RANUAwCfBf5OVhD7Lk,12689
|
449
449
|
reconcile/typed_queries/smtp.py,sha256=aSLglYa5bHKmlGwKkxq2RZqyMWuAf0a4S_mOuhDa084,542
|
450
450
|
reconcile/typed_queries/tekton_pipeline_providers.py,sha256=2mpHBdsNPQB94tw0H9aenGuqj8EEjYolQ03YEq1CpiY,546
|
451
451
|
reconcile/typed_queries/terraform_namespaces.py,sha256=71ARJ-GzkU9tBM0IfJTL3NF4349SJy-Mgs_DwAgUz_g,444
|
@@ -504,7 +504,7 @@ reconcile/utils/output.py,sha256=htcMXMe0y2dNnwu8MW8x0JZ5YBaEJRy5w4tR8yLF0OU,173
|
|
504
504
|
reconcile/utils/pagerduty_api.py,sha256=LgfiGSmg1iLfTsc1ZuHrFh_8qXLz52YWTXv5sF1BpN8,7468
|
505
505
|
reconcile/utils/parse_dhms_duration.py,sha256=ZJGlB43MjhgckgO3OF_nacwTiKVRpxb5Yv7m-PnaQLk,1616
|
506
506
|
reconcile/utils/password_validator.py,sha256=XwuWg-8CPlcuG7dl_oQ1G1h2gSVSnfMym_VkuprpWVg,2183
|
507
|
-
reconcile/utils/promotion_state.py,sha256=
|
507
|
+
reconcile/utils/promotion_state.py,sha256=n7OucbDDkK-8OAzAnTWtHXn14amqtZ7cr-h1MJ-I8hc,3176
|
508
508
|
reconcile/utils/promtool.py,sha256=IYNCjj5xDAEdxv6Z0pLdrIcybDfHHtWE9Z6f4LSPcG4,2791
|
509
509
|
reconcile/utils/quay_api.py,sha256=EuOegpb-7ntEjkKLFwM2Oo4Nw7SyFtmyl3sQ9aXMtrM,8152
|
510
510
|
reconcile/utils/raw_github_api.py,sha256=ZHC-SZuAyRe1zaMoOU7Krt1-zecDxENd9c_NzQYqK9g,2968
|
@@ -557,9 +557,9 @@ reconcile/utils/runtime/meta.py,sha256=hQ_jHPY0zbyA08hzpfu4FzOw25NqMg_fgCr2r9gGX
|
|
557
557
|
reconcile/utils/runtime/runner.py,sha256=72cc-I6yXyPov8UCLHpyERRy1eiMLpGite2roO0yUlo,7979
|
558
558
|
reconcile/utils/runtime/sharding.py,sha256=S43RM_ycFUDVzJD69It91xHZNML_xaAlsbVPR-me5Bk,13638
|
559
559
|
reconcile/utils/saasherder/__init__.py,sha256=J3MBZBFa5YmhqYm08QsjBXz8mFcVOCiOCkyIcw41t7E,343
|
560
|
-
reconcile/utils/saasherder/interfaces.py,sha256=
|
561
|
-
reconcile/utils/saasherder/models.py,sha256=
|
562
|
-
reconcile/utils/saasherder/saasherder.py,sha256=
|
560
|
+
reconcile/utils/saasherder/interfaces.py,sha256=MWP9gJOac0NA8mdzCqzta4RYbr680pR8orZmRftv5VU,8840
|
561
|
+
reconcile/utils/saasherder/models.py,sha256=R_6Gx71GnK_eWBG1onBbHfHwkektecKGmMTttbKe33E,4725
|
562
|
+
reconcile/utils/saasherder/saasherder.py,sha256=hYQOAG3O1w-znNld6mv8xdimh7XIh7WEjYQq-f3qzwk,81112
|
563
563
|
reconcile/utils/terraform/__init__.py,sha256=zNbiyTWo35AT1sFTElL2j_AA0jJ_yWE_bfFn-nD2xik,250
|
564
564
|
reconcile/utils/terraform/config.py,sha256=5UVrd563TMcvi4ooa5JvWVDW1I3bIWg484u79evfV_8,164
|
565
565
|
reconcile/utils/terraform/config_client.py,sha256=t4novdX7GeYPMYms97C_BBtLmt0M8CJCmCT7QHENwxg,4687
|
@@ -583,8 +583,8 @@ tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y
|
|
583
583
|
tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
584
584
|
tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
|
585
585
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
586
|
-
qontract_reconcile-0.10.
|
587
|
-
qontract_reconcile-0.10.
|
588
|
-
qontract_reconcile-0.10.
|
589
|
-
qontract_reconcile-0.10.
|
590
|
-
qontract_reconcile-0.10.
|
586
|
+
qontract_reconcile-0.10.1rc48.dist-info/METADATA,sha256=IPX-uDN-ybEdMeUiV7zrZzcLvm2X80poZF9Nv72FFYo,2288
|
587
|
+
qontract_reconcile-0.10.1rc48.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
588
|
+
qontract_reconcile-0.10.1rc48.dist-info/entry_points.txt,sha256=Af70EWPJxsTiCNF6gA-pWdw1A0Heqn-PZF-oBc5NmiU,302
|
589
|
+
qontract_reconcile-0.10.1rc48.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
590
|
+
qontract_reconcile-0.10.1rc48.dist-info/RECORD,,
|
@@ -28,10 +28,19 @@ class Publisher:
|
|
28
28
|
def __init__(
|
29
29
|
self,
|
30
30
|
ref: str,
|
31
|
+
uid: str,
|
31
32
|
repo_url: str,
|
32
33
|
auth_code: Optional[HasSecret],
|
33
34
|
):
|
35
|
+
"""Init.
|
36
|
+
|
37
|
+
ref: The target git ref to fetch the commit sha from.
|
38
|
+
uid: The uid of the saas publisher target.
|
39
|
+
repo_url: The git repo url of the saas publisher target.
|
40
|
+
auth_code: The auth code to use to fetch the commit sha.
|
41
|
+
"""
|
34
42
|
self._ref = ref
|
43
|
+
self._uid = uid
|
35
44
|
self._repo_url = repo_url
|
36
45
|
self._auth_code = auth_code
|
37
46
|
self.channels: set[str] = set()
|
@@ -51,6 +60,7 @@ class Publisher:
|
|
51
60
|
promotion_data = deployment_state.get_promotion_data(
|
52
61
|
sha=self.commit_sha,
|
53
62
|
channel=channel,
|
63
|
+
saas_target_uid=self._uid,
|
54
64
|
)
|
55
65
|
if not (
|
56
66
|
promotion_data
|
@@ -34,25 +34,6 @@ class SaasFilesInventory:
|
|
34
34
|
self._assemble_publishers()
|
35
35
|
self._remove_unsupported()
|
36
36
|
|
37
|
-
def _assemble_channels(self) -> None:
|
38
|
-
for saas_file in self._saas_files:
|
39
|
-
for resource_template in saas_file.resource_templates:
|
40
|
-
for target in resource_template.targets:
|
41
|
-
if not target.promotion:
|
42
|
-
continue
|
43
|
-
for publish_channel in target.promotion.publish or []:
|
44
|
-
if publish_channel not in self._channels_by_name:
|
45
|
-
self._channels_by_name[publish_channel] = Channel(
|
46
|
-
name=publish_channel,
|
47
|
-
publishers=[],
|
48
|
-
)
|
49
|
-
for subscribe_channel in target.promotion.subscribe or []:
|
50
|
-
if subscribe_channel not in self._channels_by_name:
|
51
|
-
self._channels_by_name[subscribe_channel] = Channel(
|
52
|
-
name=subscribe_channel,
|
53
|
-
publishers=[],
|
54
|
-
)
|
55
|
-
|
56
37
|
def _assemble_publishers(self) -> None:
|
57
38
|
for saas_file in self._saas_files:
|
58
39
|
for resource_template in saas_file.resource_templates:
|
@@ -66,6 +47,7 @@ class SaasFilesInventory:
|
|
66
47
|
)
|
67
48
|
publisher = Publisher(
|
68
49
|
ref=target.ref,
|
50
|
+
uid=target.uid,
|
69
51
|
repo_url=resource_template.url,
|
70
52
|
auth_code=auth_code,
|
71
53
|
)
|
@@ -149,13 +131,6 @@ class SaasFilesInventory:
|
|
149
131
|
for subscriber in self.subscribers:
|
150
132
|
is_supported = True
|
151
133
|
for channel in subscriber.channels:
|
152
|
-
if len(channel.publishers) > 1:
|
153
|
-
logging.error(
|
154
|
-
"[%s] We do not support multiple publishers for a single channel - blocked by https://issues.redhat.com/browse/APPSRE-7414",
|
155
|
-
channel.name,
|
156
|
-
)
|
157
|
-
is_supported = False
|
158
|
-
break
|
159
134
|
if not channel.publishers:
|
160
135
|
logging.error(
|
161
136
|
"[%s] There must be at least one publisher per channel.",
|
@@ -163,18 +138,7 @@ class SaasFilesInventory:
|
|
163
138
|
)
|
164
139
|
is_supported = False
|
165
140
|
break
|
166
|
-
|
167
|
-
len(subscriber.config_hashes_by_channel_name.get(channel.name, []))
|
168
|
-
> 1
|
169
|
-
):
|
170
|
-
logging.error(
|
171
|
-
"[%s] We do not support multiple publishers for a single channel - blocked by https://issues.redhat.com/browse/APPSRE-7414",
|
172
|
-
channel.name,
|
173
|
-
)
|
174
|
-
is_supported = False
|
175
|
-
break
|
141
|
+
|
176
142
|
if is_supported:
|
177
143
|
supported_subscribers.append(subscriber)
|
178
144
|
self.subscribers = supported_subscribers
|
179
|
-
# Ideally we also remove the publishers that are left w/o subscriber.
|
180
|
-
# But lets solve APPSRE-7414 - then it wont be necessary in the first place.
|
@@ -32,6 +32,11 @@ def saas_files_builder(
|
|
32
32
|
d["imagePatterns"] = []
|
33
33
|
for rt in d.get("resourceTemplates", []):
|
34
34
|
for t in rt.get("targets", []):
|
35
|
+
if "parent_saas_file_name" not in t:
|
36
|
+
t["parent_saas_file_name"] = "saas-file-name"
|
37
|
+
if "parent_resource_template_name" not in t:
|
38
|
+
t["parent_resource_template_name"] = "resource-template-name"
|
39
|
+
|
35
40
|
ns = t["namespace"]
|
36
41
|
if "name" not in ns:
|
37
42
|
ns["name"] = "some_name"
|
@@ -92,6 +92,8 @@ def test_integration_test(
|
|
92
92
|
"ls": [
|
93
93
|
"/promotions/channel-1/new_sha",
|
94
94
|
"/promotions/channel-2/new_sha",
|
95
|
+
"/deployments/channel-3/target-uid/new_sha",
|
96
|
+
"/deployments/channel-4/target-uid/new_sha",
|
95
97
|
],
|
96
98
|
"get": {
|
97
99
|
"promotions/channel-1/new_sha": {
|
@@ -104,6 +106,16 @@ def test_integration_test(
|
|
104
106
|
"target_config_hash": "new_hash",
|
105
107
|
"saas_file": "saas_1",
|
106
108
|
},
|
109
|
+
"/deployments/channel-3/target-uid/new_sha": {
|
110
|
+
"success": True,
|
111
|
+
"target_config_hash": "new_hash",
|
112
|
+
"saas_file": "saas_1",
|
113
|
+
},
|
114
|
+
"/deployments/channel-4/target-uid/new_sha": {
|
115
|
+
"success": True,
|
116
|
+
"target_config_hash": "new_hash",
|
117
|
+
"saas_file": "saas_1",
|
118
|
+
},
|
107
119
|
},
|
108
120
|
}
|
109
121
|
)
|
@@ -65,6 +65,4 @@ def test_multiple_publishers_for_single_channel(
|
|
65
65
|
)
|
66
66
|
inventory = SaasFilesInventory(saas_files=saas_files)
|
67
67
|
assert len(inventory.publishers) == 2
|
68
|
-
|
69
|
-
# subscribers should be removed from the inventory
|
70
|
-
assert len(inventory.subscribers) == 0
|
68
|
+
assert len(inventory.subscribers) == 1
|
@@ -15,6 +15,7 @@ class TestPromotions(TestCase):
|
|
15
15
|
commit_sha="ahash",
|
16
16
|
saas_file="saas_file",
|
17
17
|
target_config_hash="123123123",
|
18
|
+
saas_target_uid="saas_target_uid",
|
18
19
|
)
|
19
20
|
|
20
21
|
expected = {
|
@@ -50,6 +51,7 @@ class TestPromotions(TestCase):
|
|
50
51
|
publish=["test-channel"],
|
51
52
|
commit_sha="ahash",
|
52
53
|
target_config_hash="111111111",
|
54
|
+
saas_target_uid="saas_target_uid",
|
53
55
|
)
|
54
56
|
|
55
57
|
target_promotion = {
|
@@ -74,6 +76,7 @@ class TestPromotions(TestCase):
|
|
74
76
|
commit_sha="ahash",
|
75
77
|
saas_file="saas_file",
|
76
78
|
target_config_hash="111111111",
|
79
|
+
saas_target_uid="saas_target_uid",
|
77
80
|
)
|
78
81
|
|
79
82
|
target_promotion = {
|
@@ -110,6 +113,7 @@ class TestPromotions(TestCase):
|
|
110
113
|
commit_sha="ahash",
|
111
114
|
saas_file="saas_file",
|
112
115
|
target_config_hash="111111111",
|
116
|
+
saas_target_uid="saas_target_uid",
|
113
117
|
)
|
114
118
|
|
115
119
|
target_promotion = {
|
@@ -142,11 +146,12 @@ class TestPromotions(TestCase):
|
|
142
146
|
commit_sha="ahash",
|
143
147
|
saas_file="saas_file",
|
144
148
|
target_config_hash="111111111",
|
149
|
+
saas_target_uid="saas_target_uid",
|
145
150
|
)
|
146
151
|
|
147
152
|
ap = AutoPromoter([promotion])
|
148
153
|
self.assertEqual(
|
149
|
-
ap.title, "[auto_promoter] openshift-saas-deploy automated promotion
|
154
|
+
ap.title, "[auto_promoter] openshift-saas-deploy automated promotion 0a3d57"
|
150
155
|
)
|
151
156
|
|
152
157
|
def test_description_property(self) -> None:
|
@@ -157,6 +162,7 @@ class TestPromotions(TestCase):
|
|
157
162
|
commit_sha="ahash",
|
158
163
|
saas_file="saas_file",
|
159
164
|
target_config_hash="111111111",
|
165
|
+
saas_target_uid="saas_target_uid",
|
160
166
|
)
|
161
167
|
|
162
168
|
ap = AutoPromoter([promotion])
|
@@ -170,15 +176,13 @@ class TestPromotions(TestCase):
|
|
170
176
|
commit_sha="ahash",
|
171
177
|
saas_file="saas_file",
|
172
178
|
target_config_hash="111111111",
|
179
|
+
saas_target_uid="saas_target_uid",
|
173
180
|
)
|
174
181
|
|
175
182
|
ap = AutoPromoter([promotion])
|
176
183
|
self.assertTrue(ap.gitlab_data["source_branch"].startswith("auto_promoter-"))
|
177
184
|
self.assertEqual(ap.gitlab_data["target_branch"], "master")
|
178
|
-
self.assertEqual(
|
179
|
-
ap.gitlab_data["title"],
|
180
|
-
"[auto_promoter] openshift-saas-deploy automated promotion 4af7b1",
|
181
|
-
)
|
185
|
+
self.assertEqual(ap.gitlab_data["title"], ap.title)
|
182
186
|
self.assertEqual(
|
183
187
|
ap.gitlab_data["description"], "openshift-saas-deploy automated promotion"
|
184
188
|
)
|
@@ -193,6 +197,7 @@ class TestPromotions(TestCase):
|
|
193
197
|
commit_sha="ahash",
|
194
198
|
saas_file="saas_file",
|
195
199
|
target_config_hash="111111111",
|
200
|
+
saas_target_uid="saas_target_uid",
|
196
201
|
)
|
197
202
|
|
198
203
|
ap = AutoPromoter([promotion])
|
@@ -210,6 +215,7 @@ class TestPromotions(TestCase):
|
|
210
215
|
"subscribe": None,
|
211
216
|
"promotion_data": None,
|
212
217
|
"saas_file_paths": ["destination-saas-file"],
|
218
|
+
"saas_target_uid": "saas_target_uid",
|
213
219
|
"target_paths": None,
|
214
220
|
}
|
215
221
|
],
|
@@ -224,6 +230,7 @@ class TestPromotions(TestCase):
|
|
224
230
|
commit_sha="ahash",
|
225
231
|
saas_file="saas_file",
|
226
232
|
target_config_hash="111111111",
|
233
|
+
saas_target_uid="saas_target_uid",
|
227
234
|
promotion_data=[
|
228
235
|
{
|
229
236
|
"channel": "test-channel",
|
@@ -239,7 +246,7 @@ class TestPromotions(TestCase):
|
|
239
246
|
)
|
240
247
|
|
241
248
|
ap = AutoPromoter([promotion])
|
242
|
-
sqs_json = '{"pr_type": "auto_promoter", "promotions": [{"commit_sha": "ahash", "saas_file": "saas_file", "target_config_hash": "111111111", "auto": true, "publish": ["test-channel"], "subscribe": null, "promotion_data": [{"channel": "test-channel", "data": [{"type": "parent_saas_config", "parent_saas": "saas_file", "target_config_hash": "111111111"}]}], "saas_file_paths": ["destination-saas-file"], "target_paths": null}]}'
|
249
|
+
sqs_json = '{"pr_type": "auto_promoter", "promotions": [{"commit_sha": "ahash", "saas_file": "saas_file", "target_config_hash": "111111111", "saas_target_uid": "saas_target_uid", "auto": true, "publish": ["test-channel"], "subscribe": null, "promotion_data": [{"channel": "test-channel", "data": [{"type": "parent_saas_config", "parent_saas": "saas_file", "target_config_hash": "111111111"}]}], "saas_file_paths": ["destination-saas-file"], "target_paths": null}]}'
|
243
250
|
self.assertEqual(json.dumps(ap.sqs_data), sqs_json)
|
244
251
|
|
245
252
|
def test_init_with_promotion_object(self) -> None:
|
@@ -250,6 +257,7 @@ class TestPromotions(TestCase):
|
|
250
257
|
commit_sha="ahash",
|
251
258
|
saas_file="saas_file",
|
252
259
|
target_config_hash="111111111",
|
260
|
+
saas_target_uid="saas_target_uid",
|
253
261
|
promotion_data=[
|
254
262
|
{
|
255
263
|
"channel": "test-channel",
|
@@ -276,6 +284,7 @@ class TestPromotions(TestCase):
|
|
276
284
|
commit_sha="ahash",
|
277
285
|
saas_file="saas_file",
|
278
286
|
target_config_hash="111111111",
|
287
|
+
saas_target_uid="saas_target_uid",
|
279
288
|
promotion_data=[
|
280
289
|
{
|
281
290
|
"channel": "test-channel",
|
@@ -28,10 +28,14 @@ from reconcile.gql_definitions.common.saas_files import (
|
|
28
28
|
SaasResourceTemplateTargetV2_SaasSecretParametersV1,
|
29
29
|
SaasResourceTemplateV2,
|
30
30
|
)
|
31
|
+
from reconcile.typed_queries.saas_files import (
|
32
|
+
SaasFile,
|
33
|
+
convert_saas_file_v2_to_saas_file,
|
34
|
+
)
|
31
35
|
from reconcile.utils.jjb_client import JJB
|
32
36
|
from reconcile.utils.openshift_resource import ResourceInventory
|
33
37
|
from reconcile.utils.saasherder import SaasHerder
|
34
|
-
from reconcile.utils.saasherder.interfaces import SaasFile
|
38
|
+
from reconcile.utils.saasherder.interfaces import SaasFile as SaasFileInterface
|
35
39
|
from reconcile.utils.saasherder.models import TriggerSpecMovingCommit
|
36
40
|
from reconcile.utils.secret_reader import SecretReaderBase
|
37
41
|
|
@@ -607,7 +611,7 @@ class TestPopulateDesiredState(TestCase):
|
|
607
611
|
self.saasherder.populate_desired_state(ri)
|
608
612
|
|
609
613
|
cnt = 0
|
610
|
-
for
|
614
|
+
for cluster, namespace, resource_type, data in ri:
|
611
615
|
for _, d_item in data["desired"].items():
|
612
616
|
expected = yaml.safe_load(
|
613
617
|
self.fxts.get(
|
@@ -763,6 +767,7 @@ class TestConfigHashPromotionsValidation(TestCase):
|
|
763
767
|
self.saas_file = self.gql_class_factory( # type: ignore[attr-defined] # it's set in the fixture
|
764
768
|
SaasFileV2, Fixtures("saasherder").get_anymarkup("saas.gql.yml")
|
765
769
|
)
|
770
|
+
self.saas_file = convert_saas_file_v2_to_saas_file(self.saas_file)
|
766
771
|
self.all_saas_files = [self.saas_file]
|
767
772
|
|
768
773
|
self.state_patcher = patch("reconcile.utils.state.State", autospec=True)
|
@@ -959,7 +964,7 @@ class TestRemoveNoneAttributes(TestCase):
|
|
959
964
|
|
960
965
|
|
961
966
|
def test_render_templated_parameters(
|
962
|
-
gql_class_factory: Callable[...,
|
967
|
+
gql_class_factory: Callable[..., SaasFileInterface]
|
963
968
|
) -> None:
|
964
969
|
saas_file = gql_class_factory(
|
965
970
|
SaasFileV2,
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import hashlib
|
1
2
|
import json
|
2
3
|
from collections.abc import Callable
|
3
4
|
from typing import (
|
@@ -23,6 +24,7 @@ from reconcile.gql_definitions.common.saas_files import (
|
|
23
24
|
PipelinesProviderV1,
|
24
25
|
RoleV1,
|
25
26
|
SaasFileAuthenticationV1,
|
27
|
+
SaasFileV2,
|
26
28
|
SaasResourceTemplateTargetImageV1,
|
27
29
|
SaasResourceTemplateTargetNamespaceSelectorV1,
|
28
30
|
SaasResourceTemplateTargetPromotionV1,
|
@@ -70,11 +72,27 @@ class SaasResourceTemplateTarget(ConfiguredBaseModel):
|
|
70
72
|
image: Optional[SaasResourceTemplateTargetImageV1] = Field(..., alias="image")
|
71
73
|
disable: Optional[bool] = Field(..., alias="disable")
|
72
74
|
delete: Optional[bool] = Field(..., alias="delete")
|
75
|
+
parent_saas_file_name: Optional[str] = None
|
76
|
+
parent_resource_template_name: Optional[str] = None
|
73
77
|
|
74
78
|
class Config:
|
75
79
|
# ignore `namespaceSelector` and 'provider' fields from the GQL schema
|
76
80
|
extra = Extra.ignore
|
77
81
|
|
82
|
+
@property
|
83
|
+
def uid(self) -> str:
|
84
|
+
"""Returns a unique identifier for a target."""
|
85
|
+
if not self.parent_resource_template_name:
|
86
|
+
raise ValueError(
|
87
|
+
"parent_resource_template_name must be set before calling uid()"
|
88
|
+
)
|
89
|
+
if not self.parent_saas_file_name:
|
90
|
+
raise ValueError("parent_saas_file_name must be set before calling uid()")
|
91
|
+
return hashlib.blake2s(
|
92
|
+
f"{self.parent_saas_file_name}:{self.parent_resource_template_name}:{self.name if self.name else 'default'}:{self.namespace.cluster.name}:{self.namespace.name}".encode(),
|
93
|
+
digest_size=20,
|
94
|
+
).hexdigest()
|
95
|
+
|
78
96
|
|
79
97
|
class SaasResourceTemplate(ConfiguredBaseModel):
|
80
98
|
name: str = Field(..., alias="name")
|
@@ -205,6 +223,16 @@ def create_targets_for_namespace_selector(
|
|
205
223
|
return targets
|
206
224
|
|
207
225
|
|
226
|
+
def convert_saas_file_v2_to_saas_file(saas_file_gql: SaasFileV2) -> SaasFile:
|
227
|
+
"""Convert a SaasFileV2 to a SaasFile and inject the parent objects."""
|
228
|
+
saas_file = SaasFile(**export_model(saas_file_gql))
|
229
|
+
for tmpl in saas_file.resource_templates:
|
230
|
+
for target in tmpl.targets:
|
231
|
+
target.parent_saas_file_name = saas_file.name
|
232
|
+
target.parent_resource_template_name = tmpl.name
|
233
|
+
return saas_file
|
234
|
+
|
235
|
+
|
208
236
|
def get_saas_files(
|
209
237
|
name: Optional[str] = None,
|
210
238
|
env_name: Optional[str] = None,
|
@@ -245,7 +273,7 @@ def get_saas_files(
|
|
245
273
|
)
|
246
274
|
# convert SaasFileV2 (with optional resource_templates.targets.namespace field)
|
247
275
|
# to SaasFile (with required resource_templates.targets.namespace field)
|
248
|
-
saas_files.append(
|
276
|
+
saas_files.append(convert_saas_file_v2_to_saas_file(saas_file_gql))
|
249
277
|
|
250
278
|
if name is None and env_name is None and app_name is None:
|
251
279
|
return saas_files
|
@@ -47,28 +47,51 @@ class PromotionState:
|
|
47
47
|
"""
|
48
48
|
all_keys = self._state.ls()
|
49
49
|
for commit in all_keys:
|
50
|
-
#
|
51
|
-
if
|
50
|
+
# for backwards compatibility - remove this after a while
|
51
|
+
if commit.startswith("/promotions/"):
|
52
|
+
# Format: /promotions/{channel}/{commit-sha}
|
53
|
+
_, _, channel_name, commit_sha = commit.split("/")
|
54
|
+
self._commits_by_channel[channel_name].add(commit_sha)
|
55
|
+
# / for backwards compatibility - remove this after a while
|
56
|
+
|
57
|
+
# Format: /deployments/{channel}/{saas-target-uid}/{commit-sha}
|
58
|
+
if not commit.startswith("/deployments/"):
|
52
59
|
continue
|
53
|
-
_, _, channel_name, commit_sha = commit.split("/")
|
54
|
-
self._commits_by_channel[channel_name].add(
|
60
|
+
_, _, channel_name, saas_target_uid, commit_sha = commit.split("/")
|
61
|
+
self._commits_by_channel[f"{channel_name}/{saas_target_uid}"].add(
|
62
|
+
commit_sha
|
63
|
+
)
|
55
64
|
|
56
65
|
def get_promotion_data(
|
57
|
-
self, sha: str, channel: str, local_lookup: bool = True
|
66
|
+
self, sha: str, channel: str, saas_target_uid: str, local_lookup: bool = True
|
58
67
|
) -> Optional[PromotionData]:
|
59
|
-
if
|
68
|
+
if (
|
69
|
+
local_lookup
|
70
|
+
and sha not in self._commits_by_channel[channel]
|
71
|
+
and sha not in self._commits_by_channel[f"{channel}/{saas_target_uid}"]
|
72
|
+
):
|
60
73
|
# Lets reduce unecessary calls to S3
|
61
74
|
return None
|
75
|
+
|
76
|
+
# for backwards compatibility - remove this after a while
|
62
77
|
key = f"promotions/{channel}/{sha}"
|
63
78
|
try:
|
64
79
|
data = self._state.get(key)
|
80
|
+
return PromotionData(**data)
|
81
|
+
except KeyError:
|
82
|
+
pass
|
83
|
+
# / for backwards compatibility - remove this after a while
|
84
|
+
|
85
|
+
key = f"deployments/{channel}/{saas_target_uid}/{sha}"
|
86
|
+
try:
|
87
|
+
data = self._state.get(key)
|
88
|
+
return PromotionData(**data)
|
65
89
|
except KeyError:
|
66
90
|
return None
|
67
|
-
return PromotionData(**data)
|
68
91
|
|
69
92
|
def publish_promotion_data(
|
70
|
-
self, sha: str, channel: str, data: PromotionData
|
93
|
+
self, sha: str, channel: str, saas_target_uid: str, data: PromotionData
|
71
94
|
) -> None:
|
72
|
-
state_key = f"
|
95
|
+
state_key = f"deployments/{channel}/{saas_target_uid}/{sha}"
|
73
96
|
self._state.add(state_key, data.dict(), force=True)
|
74
97
|
logging.info("Uploaded %s to %s", data, state_key)
|
@@ -332,7 +332,11 @@ class SaasResourceTemplateTarget(HasParameters, HasSecretParameters, Protocol):
|
|
332
332
|
...
|
333
333
|
|
334
334
|
def dict(self, *, by_alias: bool = False) -> dict[str, Any]:
|
335
|
-
|
335
|
+
"""Return a dictionary representation of the model."""
|
336
|
+
|
337
|
+
@property
|
338
|
+
def uid(self) -> str:
|
339
|
+
"""Return a unique identifier for the target."""
|
336
340
|
|
337
341
|
|
338
342
|
class SaasResourceTemplate(HasParameters, HasSecretParameters, Protocol):
|
@@ -996,6 +996,7 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
996
996
|
commit_sha=commit_sha,
|
997
997
|
saas_file=saas_file_name,
|
998
998
|
target_config_hash=target_config_hash,
|
999
|
+
saas_target_uid=target.uid,
|
999
1000
|
)
|
1000
1001
|
return resources, html_url, target_promotion
|
1001
1002
|
|
@@ -1768,7 +1769,10 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1768
1769
|
if promotion.subscribe:
|
1769
1770
|
for channel in promotion.subscribe:
|
1770
1771
|
info = self._promotion_state.get_promotion_data(
|
1771
|
-
sha=promotion.commit_sha,
|
1772
|
+
sha=promotion.commit_sha,
|
1773
|
+
channel=channel,
|
1774
|
+
saas_target_uid=promotion.saas_target_uid,
|
1775
|
+
local_lookup=False,
|
1772
1776
|
)
|
1773
1777
|
if not (info and info.success):
|
1774
1778
|
logging.error(
|
@@ -1860,6 +1864,7 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1860
1864
|
self._promotion_state.publish_promotion_data(
|
1861
1865
|
sha=promotion.commit_sha,
|
1862
1866
|
channel=channel,
|
1867
|
+
saas_target_uid=promotion.saas_target_uid,
|
1863
1868
|
data=PromotionData(
|
1864
1869
|
saas_file=promotion.saas_file,
|
1865
1870
|
success=success,
|
File without changes
|
{qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/entry_points.txt
RENAMED
File without changes
|
{qontract_reconcile-0.10.1rc47.dist-info → qontract_reconcile-0.10.1rc48.dist-info}/top_level.txt
RENAMED
File without changes
|