qontract-reconcile 0.10.1rc529__py3-none-any.whl → 0.10.1rc531__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.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/RECORD +11 -12
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +12 -0
- reconcile/saas_auto_promotions_manager/integration.py +1 -20
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +8 -7
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -9
- reconcile/utils/terrascript_aws_client.py +24 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -190
- {qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.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.1rc531
|
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
|
{qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/RECORD
RENAMED
@@ -303,7 +303,7 @@ reconcile/gql_definitions/terraform_repo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
303
303
|
reconcile/gql_definitions/terraform_repo/terraform_repo.py,sha256=pefTRhb0ZcWm_j6dYz6m6qNqZFteqgrQ25SgUqRAVaI,3173
|
304
304
|
reconcile/gql_definitions/terraform_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
305
305
|
reconcile/gql_definitions/terraform_resources/database_access_manager.py,sha256=yv0_YC-LmhaKD_gyGG3le1w5BtypBjlsO894-Zgdg4U,4813
|
306
|
-
reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py,sha256=
|
306
|
+
reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py,sha256=GMV0sch1Mdznjd3Vwgj_gMS1fb56d5xa2dFtOM57yUA,41126
|
307
307
|
reconcile/gql_definitions/terraform_tgw_attachments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
308
308
|
reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py,sha256=GjCuLHOgm3eHbkpK7Q2i7l6tori5Y62uFlz3M89BYtA,2602
|
309
309
|
reconcile/gql_definitions/vault_instances/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -345,16 +345,15 @@ reconcile/rhidp/sso_client/base.py,sha256=EfQ2ewcOKh5idg46UKAkY6z0m_nGQfvnQKffa2
|
|
345
345
|
reconcile/rhidp/sso_client/integration.py,sha256=kA8g7c38ZBSdrRtyfEqy_WgSreD1PbwY7ZIN-3tZRPc,2221
|
346
346
|
reconcile/rhidp/sso_client/metrics.py,sha256=Tq7tSOsqL3XdcPUdozxqzSPIodUeOV87UCTqpuuqqhw,1013
|
347
347
|
reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
348
|
-
reconcile/saas_auto_promotions_manager/integration.py,sha256=
|
348
|
+
reconcile/saas_auto_promotions_manager/integration.py,sha256=G_IRL85fNI8Knw31KstDPE_AXJv6VFzc5AsqMeU7CBs,5788
|
349
349
|
reconcile/saas_auto_promotions_manager/publisher.py,sha256=4_M9Oykhj-kEZPUn05E2DY5gD6-x32Dgf7K3NPOkGEg,2029
|
350
350
|
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=cLhPlkT71J2LIice3SLmH1WpsqzV46gd0peMxrnqyRw,7452
|
351
351
|
reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
352
352
|
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=BeAJWLow7b4HQyZ9zz398sQkPeIz8chpMkCts2NU27c,1282
|
353
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/
|
354
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py,sha256=eEKT8lqS7Dw0oG_oykRRIYNlWmncHk-Npc1LCpcVrAw,5785
|
353
|
+
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py,sha256=gm00k4zFVIjd9ThK1PRn_YNLSd4LZIQpa6cPjX8Pqn0,6005
|
355
354
|
reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py,sha256=x8Gg-YjEFWEeDPJH3Y8SrfcJbwhLuAqCz4kIhfEyaaA,7060
|
356
355
|
reconcile/saas_auto_promotions_manager/merge_request_manager/reconciler.py,sha256=_gZ0ef-5E9hCdpkSw4b8SdTfpcaTS722KPWey4LhD5I,7644
|
357
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=
|
356
|
+
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=lgJpMOEoluGV_UcMQ2dNJrCv-2qTlsvZzX50Luoyafo,6959
|
358
357
|
reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
359
358
|
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=mihuWynroB1Cea1Lsvf6V8Nb8PGiBdcLC0uhCX_52Y0,6966
|
360
359
|
reconcile/skupper_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -454,7 +453,7 @@ reconcile/test/test_vpc_peerings_validator.py,sha256=dFSmjc_dMN2GqMbntCFpa7PUZmy
|
|
454
453
|
reconcile/test/test_wrong_region.py,sha256=7KzL7OaICQ9Z3DW27zt_ykMN7_87owAFC-2CYjvGoyA,2138
|
455
454
|
reconcile/test/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
456
455
|
reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=tZNs35EuWulP53Cqt61RteOGY_uH4gfhtXfGQ8-awwM,3081
|
457
|
-
reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=
|
456
|
+
reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=fQB3V5kyTOzODbt43jQ03pfOLuAWq3nW3R9tVTWkTrQ,1729
|
458
457
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
459
458
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
460
459
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py,sha256=7O3lbk1EmEtUofqGncfiwMYvDPXrkQNPB59zlQ_zXkM,4588
|
@@ -581,7 +580,7 @@ reconcile/utils/state.py,sha256=SAa6QLHu9lr0yqLCBy2AypNx1IPCJWlrRBrvlzAKsOU,1450
|
|
581
580
|
reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
|
582
581
|
reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
|
583
582
|
reconcile/utils/terraform_client.py,sha256=V7AMQOEU4tvUOT-LQN2cXLqcphD5L93PMGMfurQQyPY,31753
|
584
|
-
reconcile/utils/terrascript_aws_client.py,sha256=
|
583
|
+
reconcile/utils/terrascript_aws_client.py,sha256=wA6AcAqbS2tIuqh8soMfpdpuf0IbAJWjONMmffJ-0vA,265467
|
585
584
|
reconcile/utils/three_way_diff_strategy.py,sha256=nyqeQsLCoPI6e16k2CF3b9KNgQLU-rPf5RtfdUfVMwE,4468
|
586
585
|
reconcile/utils/throughput.py,sha256=iP4UWAe2LVhDo69mPPmgo9nQ7RxHD6_GS8MZe-aSiuM,344
|
587
586
|
reconcile/utils/unleash.py,sha256=1D56CsZfE3ShDtN3IErE1T2eeIwNmxhK-yYbCotJ99E,3601
|
@@ -668,8 +667,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
668
667
|
tools/test/test_qontract_cli.py,sha256=d18KrdhtUGqoC7_kWZU128U0-VJEj-0rjFkLVufcI6I,2755
|
669
668
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
670
669
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
671
|
-
qontract_reconcile-0.10.
|
672
|
-
qontract_reconcile-0.10.
|
673
|
-
qontract_reconcile-0.10.
|
674
|
-
qontract_reconcile-0.10.
|
675
|
-
qontract_reconcile-0.10.
|
670
|
+
qontract_reconcile-0.10.1rc531.dist-info/METADATA,sha256=4TYoXCYpS3NBGBMMhRuMy8JQtax2EAWVDjQ0PVvlW4o,2349
|
671
|
+
qontract_reconcile-0.10.1rc531.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
672
|
+
qontract_reconcile-0.10.1rc531.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
|
673
|
+
qontract_reconcile-0.10.1rc531.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
674
|
+
qontract_reconcile-0.10.1rc531.dist-info/RECORD,,
|
@@ -168,6 +168,11 @@ query TerraformResourcesNamespaces {
|
|
168
168
|
role_policy
|
169
169
|
output_resource_name
|
170
170
|
annotations
|
171
|
+
lifecycle {
|
172
|
+
create_before_destroy
|
173
|
+
prevent_destroy
|
174
|
+
ignore_changes
|
175
|
+
}
|
171
176
|
}
|
172
177
|
... on NamespaceTerraformResourceSQS_v1 {
|
173
178
|
region
|
@@ -614,6 +619,12 @@ class AssumeRoleV1(ConfiguredBaseModel):
|
|
614
619
|
federated: Optional[str] = Field(..., alias="Federated")
|
615
620
|
|
616
621
|
|
622
|
+
class NamespaceTerraformResourceLifecycleV1(ConfiguredBaseModel):
|
623
|
+
create_before_destroy: Optional[bool] = Field(..., alias="create_before_destroy")
|
624
|
+
prevent_destroy: Optional[bool] = Field(..., alias="prevent_destroy")
|
625
|
+
ignore_changes: Optional[list[str]] = Field(..., alias="ignore_changes")
|
626
|
+
|
627
|
+
|
617
628
|
class NamespaceTerraformResourceRoleV1(NamespaceTerraformResourceAWSV1):
|
618
629
|
identifier: str = Field(..., alias="identifier")
|
619
630
|
assume_role: AssumeRoleV1 = Field(..., alias="assume_role")
|
@@ -623,6 +634,7 @@ class NamespaceTerraformResourceRoleV1(NamespaceTerraformResourceAWSV1):
|
|
623
634
|
role_policy: Optional[str] = Field(..., alias="role_policy")
|
624
635
|
output_resource_name: Optional[str] = Field(..., alias="output_resource_name")
|
625
636
|
annotations: Optional[str] = Field(..., alias="annotations")
|
637
|
+
lifecycle: Optional[NamespaceTerraformResourceLifecycleV1] = Field(..., alias="lifecycle")
|
626
638
|
|
627
639
|
|
628
640
|
class KeyValueV1(ConfiguredBaseModel):
|
@@ -6,9 +6,6 @@ from sretoolbox.utils import threaded
|
|
6
6
|
from reconcile.openshift_saas_deploy import (
|
7
7
|
QONTRACT_INTEGRATION as OPENSHIFT_SAAS_DEPLOY,
|
8
8
|
)
|
9
|
-
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager import (
|
10
|
-
MergeRequestManager,
|
11
|
-
)
|
12
9
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager_v2 import (
|
13
10
|
MergeRequestManagerV2,
|
14
11
|
)
|
@@ -52,7 +49,6 @@ class SaasAutoPromotionsManager:
|
|
52
49
|
vcs: VCS,
|
53
50
|
saas_file_inventory: SaasFilesInventory,
|
54
51
|
merge_request_manager_v2: MergeRequestManagerV2,
|
55
|
-
merge_request_manager: MergeRequestManager,
|
56
52
|
thread_pool_size: int,
|
57
53
|
dry_run: bool,
|
58
54
|
):
|
@@ -60,7 +56,6 @@ class SaasAutoPromotionsManager:
|
|
60
56
|
self._vcs = vcs
|
61
57
|
self._saas_file_inventory = saas_file_inventory
|
62
58
|
self._merge_request_manager_v2 = merge_request_manager_v2
|
63
|
-
self._merge_request_manager = merge_request_manager
|
64
59
|
self._thread_pool_size = thread_pool_size
|
65
60
|
self._dry_run = dry_run
|
66
61
|
|
@@ -92,18 +87,12 @@ class SaasAutoPromotionsManager:
|
|
92
87
|
self._fetch_publisher_real_world_states()
|
93
88
|
self._compute_desired_subscriber_states()
|
94
89
|
subscribers_with_diff = self._get_subscribers_with_diff()
|
95
|
-
self._merge_request_manager.housekeeping()
|
96
|
-
self._merge_request_manager.create_promotion_merge_requests(
|
97
|
-
subscribers=subscribers_with_diff
|
98
|
-
)
|
99
90
|
self._merge_request_manager_v2.reconcile(subscribers=subscribers_with_diff)
|
100
91
|
|
101
92
|
|
102
93
|
def init_external_dependencies(
|
103
94
|
dry_run: bool,
|
104
|
-
) -> tuple[
|
105
|
-
PromotionState, VCS, SaasFilesInventory, MergeRequestManagerV2, MergeRequestManager
|
106
|
-
]:
|
95
|
+
) -> tuple[PromotionState, VCS, SaasFilesInventory, MergeRequestManagerV2]:
|
107
96
|
"""
|
108
97
|
Lets initialize everything that involves calls to external dependencies:
|
109
98
|
- VCS -> Gitlab / Github queries
|
@@ -137,11 +126,6 @@ def init_external_dependencies(
|
|
137
126
|
mr_parser=mr_parser,
|
138
127
|
renderer=Renderer(),
|
139
128
|
)
|
140
|
-
merge_request_manager = MergeRequestManager(
|
141
|
-
mr_parser=mr_parser,
|
142
|
-
renderer=Renderer(),
|
143
|
-
vcs=vcs,
|
144
|
-
)
|
145
129
|
saas_files = get_saas_files()
|
146
130
|
saas_inventory = SaasFilesInventory(saas_files=saas_files)
|
147
131
|
deployment_state = PromotionState(
|
@@ -152,7 +136,6 @@ def init_external_dependencies(
|
|
152
136
|
vcs,
|
153
137
|
saas_inventory,
|
154
138
|
merge_request_manager_v2,
|
155
|
-
merge_request_manager,
|
156
139
|
)
|
157
140
|
|
158
141
|
|
@@ -167,7 +150,6 @@ def run(
|
|
167
150
|
vcs,
|
168
151
|
saas_inventory,
|
169
152
|
merge_request_manager_v2,
|
170
|
-
merge_request_manager,
|
171
153
|
) = init_external_dependencies(dry_run=dry_run)
|
172
154
|
if defer:
|
173
155
|
defer(vcs.cleanup)
|
@@ -176,7 +158,6 @@ def run(
|
|
176
158
|
deployment_state=deployment_state,
|
177
159
|
vcs=vcs,
|
178
160
|
saas_file_inventory=saas_inventory,
|
179
|
-
merge_request_manager=merge_request_manager,
|
180
161
|
merge_request_manager_v2=merge_request_manager_v2,
|
181
162
|
thread_pool_size=thread_pool_size,
|
182
163
|
dry_run=dry_run,
|
@@ -19,20 +19,21 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer impor
|
|
19
19
|
Renderer,
|
20
20
|
)
|
21
21
|
from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
|
22
|
-
from reconcile.utils.mr.labels import
|
22
|
+
from reconcile.utils.mr.labels import AUTO_MERGE
|
23
23
|
from reconcile.utils.vcs import VCS
|
24
24
|
|
25
25
|
BATCH_SIZE_LIMIT = 5
|
26
|
-
SAPM_LABEL = "SAPMCanary"
|
27
|
-
SAPM_MR_LABELS = [SAPM_LABEL, DO_NOT_MERGE_HOLD]
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
SAPM_LABEL = "SAPM"
|
28
|
+
SAPM_MR_LABELS = [SAPM_LABEL, AUTO_MERGE]
|
31
29
|
|
32
|
-
|
30
|
+
MR_DESC = """
|
31
|
+
This is an auto-promotion triggered by app-interface's [saas-auto-promotions-manager](https://github.com/app-sre/qontract-reconcile/tree/master/reconcile/saas_auto_promotions_manager) (SAPM).
|
32
|
+
This MR promotes all subscribers with auto-promotions for the channel(s) listed below.
|
33
33
|
|
34
|
-
Please **do not
|
34
|
+
Please **do not manually modify** this MR in any way, as it might result in blocking the auto-promotion.
|
35
35
|
|
36
|
+
This description is used by SAPM to manage auto-promotions.
|
36
37
|
"""
|
37
38
|
|
38
39
|
|
@@ -19,7 +19,7 @@ from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
|
|
19
19
|
PROMOTION_DATA_SEPARATOR = (
|
20
20
|
"**SAPM Data - DO NOT MANUALLY CHANGE ANYTHING BELOW THIS LINE**"
|
21
21
|
)
|
22
|
-
SAPM_VERSION = "2.
|
22
|
+
SAPM_VERSION = "2.1.0"
|
23
23
|
CONTENT_HASHES = "content_hashes"
|
24
24
|
CHANNELS_REF = "channels"
|
25
25
|
IS_BATCHABLE = "is_batchable"
|
@@ -1,9 +1,6 @@
|
|
1
1
|
from unittest.mock import create_autospec
|
2
2
|
|
3
3
|
from reconcile.saas_auto_promotions_manager.integration import SaasAutoPromotionsManager
|
4
|
-
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager import (
|
5
|
-
MergeRequestManager,
|
6
|
-
)
|
7
4
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager_v2 import (
|
8
5
|
MergeRequestManagerV2,
|
9
6
|
)
|
@@ -39,17 +36,11 @@ def test_integration_test():
|
|
39
36
|
mr_parser=create_autospec(spec=MRParser),
|
40
37
|
renderer=create_autospec(spec=Renderer),
|
41
38
|
)
|
42
|
-
merge_request_manager = MergeRequestManager(
|
43
|
-
vcs=vcs,
|
44
|
-
mr_parser=create_autospec(spec=MRParser),
|
45
|
-
renderer=create_autospec(spec=Renderer),
|
46
|
-
)
|
47
39
|
manager = SaasAutoPromotionsManager(
|
48
40
|
deployment_state=create_autospec(spec=PromotionState),
|
49
41
|
saas_file_inventory=SaasFilesInventory(saas_files=[]),
|
50
42
|
vcs=vcs,
|
51
43
|
merge_request_manager_v2=merge_request_manager_v2,
|
52
|
-
merge_request_manager=merge_request_manager,
|
53
44
|
thread_pool_size=1,
|
54
45
|
dry_run=False,
|
55
46
|
)
|
@@ -143,6 +143,9 @@ import reconcile.openshift_resources_base as orb
|
|
143
143
|
import reconcile.utils.aws_helper as awsh
|
144
144
|
from reconcile import queries
|
145
145
|
from reconcile.github_org import get_default_config
|
146
|
+
from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
|
147
|
+
NamespaceTerraformResourceLifecycleV1,
|
148
|
+
)
|
146
149
|
from reconcile.utils import gql
|
147
150
|
from reconcile.utils.aws_api import (
|
148
151
|
AmiTag,
|
@@ -238,6 +241,7 @@ VARIABLE_KEYS = [
|
|
238
241
|
"subscriptions",
|
239
242
|
"records",
|
240
243
|
"extra_tags",
|
244
|
+
"lifecycle",
|
241
245
|
]
|
242
246
|
|
243
247
|
EMAIL_REGEX = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
|
@@ -870,6 +874,23 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
870
874
|
role_name = awsh.get_id_from_arn(account["assume_role"])
|
871
875
|
return f"account-{uid}-{role_name}"
|
872
876
|
|
877
|
+
@staticmethod
|
878
|
+
def get_resource_lifecycle(
|
879
|
+
common_values: dict[str, Any],
|
880
|
+
) -> Optional[dict[str, Any]]:
|
881
|
+
if lifecycle := common_values.get("lifecycle"):
|
882
|
+
lifecycle = NamespaceTerraformResourceLifecycleV1(**lifecycle)
|
883
|
+
if lifecycle.create_before_destroy is None:
|
884
|
+
lifecycle.create_before_destroy = False
|
885
|
+
if lifecycle.prevent_destroy is None:
|
886
|
+
lifecycle.prevent_destroy = False
|
887
|
+
if lifecycle.ignore_changes is None:
|
888
|
+
lifecycle.ignore_changes = []
|
889
|
+
if "all" in lifecycle.ignore_changes:
|
890
|
+
lifecycle.ignore_changes = "all"
|
891
|
+
return lifecycle.dict(by_alias=True)
|
892
|
+
return None
|
893
|
+
|
873
894
|
def populate_additional_providers(self, infra_account_name: str, accounts):
|
874
895
|
for account in accounts:
|
875
896
|
account_name = account["name"]
|
@@ -2459,6 +2480,9 @@ class TerrascriptClient: # pylint: disable=too-many-public-methods
|
|
2459
2480
|
if inline_policy:
|
2460
2481
|
values["inline_policy"] = {"name": identifier, "policy": inline_policy}
|
2461
2482
|
|
2483
|
+
if lifecycle := self.get_resource_lifecycle(common_values):
|
2484
|
+
values["lifecycle"] = lifecycle
|
2485
|
+
|
2462
2486
|
role_tf_resource = aws_iam_role(identifier, **values)
|
2463
2487
|
tf_resources.append(role_tf_resource)
|
2464
2488
|
|
@@ -1,190 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import re
|
3
|
-
from collections import defaultdict
|
4
|
-
from collections.abc import Iterable
|
5
|
-
|
6
|
-
from gitlab.exceptions import GitlabGetError
|
7
|
-
|
8
|
-
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request import (
|
9
|
-
SAPMMR,
|
10
|
-
)
|
11
|
-
from reconcile.saas_auto_promotions_manager.merge_request_manager.mr_parser import (
|
12
|
-
MRParser,
|
13
|
-
OpenMergeRequest,
|
14
|
-
)
|
15
|
-
from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer import (
|
16
|
-
CHANNELS_REF,
|
17
|
-
CONTENT_HASHES,
|
18
|
-
IS_BATCHABLE,
|
19
|
-
VERSION_REF,
|
20
|
-
Renderer,
|
21
|
-
)
|
22
|
-
from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
|
23
|
-
from reconcile.utils.mr.labels import AUTO_MERGE
|
24
|
-
from reconcile.utils.vcs import VCS
|
25
|
-
|
26
|
-
ITEM_SEPARATOR = ","
|
27
|
-
|
28
|
-
SAPM_LABEL = "SAPM"
|
29
|
-
SAPM_MR_LABELS = [SAPM_LABEL, AUTO_MERGE]
|
30
|
-
|
31
|
-
MR_DESC = """
|
32
|
-
This is an auto-promotion triggered by app-interface's [saas-auto-promotions-manager](https://github.com/app-sre/qontract-reconcile/tree/master/reconcile/saas_auto_promotions_manager) (SAPM).
|
33
|
-
The channel(s) mentioned in the MR title had an event.
|
34
|
-
This MR promotes all subscribers with auto-promotions for these channel(s).
|
35
|
-
|
36
|
-
Please **do not remove or change any label** from this MR.
|
37
|
-
|
38
|
-
Parts of this description are used by SAPM to manage auto-promotions.
|
39
|
-
"""
|
40
|
-
|
41
|
-
|
42
|
-
class MergeRequestManager:
|
43
|
-
"""
|
44
|
-
Manager for SAPM merge requests. This class
|
45
|
-
is responsible for housekeeping (closing old/bad MRs) and
|
46
|
-
opening new MRs for subscribers with a state diff.
|
47
|
-
|
48
|
-
The idea is that for every channel combination there exists
|
49
|
-
maximum one open MR in app-interface. I.e., all changes for
|
50
|
-
a channel combination at a minumum are batched in a single MR.
|
51
|
-
The MR description is used to store current state for SAPM.
|
52
|
-
Channels can also be batched together into a single MR to reduce the overall
|
53
|
-
amount of MRs.
|
54
|
-
"""
|
55
|
-
|
56
|
-
def __init__(self, vcs: VCS, mr_parser: MRParser, renderer: Renderer):
|
57
|
-
self._vcs = vcs
|
58
|
-
self._mr_parser = mr_parser
|
59
|
-
self._renderer = renderer
|
60
|
-
self._version_ref_regex = re.compile(rf"{VERSION_REF}: (.*)$", re.MULTILINE)
|
61
|
-
self._content_hash_regex = re.compile(rf"{CONTENT_HASHES}: (.*)$", re.MULTILINE)
|
62
|
-
self._channels_regex = re.compile(rf"{CHANNELS_REF}: (.*)$", re.MULTILINE)
|
63
|
-
self._is_batchable_regex = re.compile(rf"{IS_BATCHABLE}: (.*)$", re.MULTILINE)
|
64
|
-
self._open_mrs: list[OpenMergeRequest] = []
|
65
|
-
self._unbatchable_hashes: set[str] = set()
|
66
|
-
|
67
|
-
def _unbatch_failed_mrs(self) -> None:
|
68
|
-
"""
|
69
|
-
We optimistically batch MRs together that didnt run through MR check yet.
|
70
|
-
Vast majority of auto-promotion MRs are succeeding checks, so we can stay optimistic.
|
71
|
-
In the rare case of an MR failing the check, we want to unbatch it.
|
72
|
-
I.e., we open a dedicated MR for each channel in the batched MR, mark the new MRs as non-batchable
|
73
|
-
and close the old batched MR. By doing so, we ensure that unrelated MRs are not blocking each other.
|
74
|
-
Unbatched MRs are marked and will never be batched again.
|
75
|
-
"""
|
76
|
-
open_mrs_after_unbatching: list[OpenMergeRequest] = []
|
77
|
-
for mr in self._open_mrs:
|
78
|
-
if mr.is_batchable and mr.failed_mr_check:
|
79
|
-
self._vcs.close_app_interface_mr(
|
80
|
-
mr.raw,
|
81
|
-
"Closing this MR because it failed MR check and isn't marked un-batchable yet.",
|
82
|
-
)
|
83
|
-
# Remember these hashes as unbatchable
|
84
|
-
self._unbatchable_hashes.update(mr.content_hashes)
|
85
|
-
else:
|
86
|
-
open_mrs_after_unbatching.append(mr)
|
87
|
-
self._open_mrs = open_mrs_after_unbatching
|
88
|
-
|
89
|
-
def housekeeping(self) -> None:
|
90
|
-
self._open_mrs = self._mr_parser.retrieve_open_mrs(label=SAPM_LABEL)
|
91
|
-
self._unbatch_failed_mrs()
|
92
|
-
|
93
|
-
def _aggregate_subscribers_per_channel_combo(
|
94
|
-
self, subscribers: Iterable[Subscriber]
|
95
|
-
) -> dict[str, list[Subscriber]]:
|
96
|
-
subscribers_per_channel_combo: dict[str, list[Subscriber]] = defaultdict(list)
|
97
|
-
for subscriber in subscribers:
|
98
|
-
channel_combo = ",".join([c.name for c in subscriber.channels])
|
99
|
-
subscribers_per_channel_combo[channel_combo].append(subscriber)
|
100
|
-
return subscribers_per_channel_combo
|
101
|
-
|
102
|
-
def _merge_request_already_exists(self, channels: str, content_hash: str) -> bool:
|
103
|
-
return any(
|
104
|
-
True
|
105
|
-
for mr in self._open_mrs
|
106
|
-
if content_hash in mr.content_hashes and channels in mr.channels
|
107
|
-
)
|
108
|
-
|
109
|
-
def create_promotion_merge_requests(
|
110
|
-
self, subscribers: Iterable[Subscriber]
|
111
|
-
) -> None:
|
112
|
-
"""
|
113
|
-
Open new MR for channel combinations with new content.
|
114
|
-
If there is new content, close any existing MR for that
|
115
|
-
channel combination.
|
116
|
-
"""
|
117
|
-
subscribers_per_channel_combo = self._aggregate_subscribers_per_channel_combo(
|
118
|
-
subscribers=subscribers
|
119
|
-
)
|
120
|
-
for channel_combo, subs in subscribers_per_channel_combo.items():
|
121
|
-
combined_content_hash = Subscriber.combined_content_hash(subscribers=subs)
|
122
|
-
if self._merge_request_already_exists(
|
123
|
-
content_hash=combined_content_hash, channels=channel_combo
|
124
|
-
):
|
125
|
-
logging.info(
|
126
|
-
"There is already an open merge request for channel(s) %s - skipping",
|
127
|
-
channel_combo,
|
128
|
-
)
|
129
|
-
continue
|
130
|
-
for mr in self._open_mrs:
|
131
|
-
if channel_combo not in mr.channels:
|
132
|
-
continue
|
133
|
-
if combined_content_hash not in mr.content_hashes:
|
134
|
-
logging.info(
|
135
|
-
"Closing MR %s because it has out-dated content",
|
136
|
-
mr.raw.attributes.get("web_url", "NO_WEBURL"),
|
137
|
-
)
|
138
|
-
self._vcs.close_app_interface_mr(
|
139
|
-
mr=mr.raw,
|
140
|
-
comment="Closing this MR because it has out-dated content.",
|
141
|
-
)
|
142
|
-
content_by_path: dict[str, str] = {}
|
143
|
-
has_error = False
|
144
|
-
for sub in subs:
|
145
|
-
if sub.target_file_path not in content_by_path:
|
146
|
-
try:
|
147
|
-
content_by_path[sub.target_file_path] = (
|
148
|
-
self._vcs.get_file_content_from_app_interface_master(
|
149
|
-
file_path=sub.target_file_path
|
150
|
-
)
|
151
|
-
)
|
152
|
-
except GitlabGetError as e:
|
153
|
-
if e.response_code == 404:
|
154
|
-
logging.error(
|
155
|
-
"The saas file %s does not exist anylonger. Most likely qontract-server data not in synch. This should resolve soon on its own.",
|
156
|
-
sub.target_file_path,
|
157
|
-
)
|
158
|
-
has_error = True
|
159
|
-
break
|
160
|
-
raise e
|
161
|
-
content_by_path[sub.target_file_path] = (
|
162
|
-
self._renderer.render_merge_request_content(
|
163
|
-
subscriber=sub,
|
164
|
-
current_content=content_by_path[sub.target_file_path],
|
165
|
-
)
|
166
|
-
)
|
167
|
-
if has_error:
|
168
|
-
continue
|
169
|
-
|
170
|
-
description = self._renderer.render_description(
|
171
|
-
message=MR_DESC,
|
172
|
-
content_hashes=combined_content_hash,
|
173
|
-
channels=channel_combo,
|
174
|
-
is_batchable=combined_content_hash not in self._unbatchable_hashes,
|
175
|
-
)
|
176
|
-
title = self._renderer.render_title(
|
177
|
-
is_draft=False, canary=False, channels=channel_combo
|
178
|
-
)
|
179
|
-
logging.info(
|
180
|
-
"Open MR for update in channel(s) %s",
|
181
|
-
channel_combo,
|
182
|
-
)
|
183
|
-
self._vcs.open_app_interface_merge_request(
|
184
|
-
mr=SAPMMR(
|
185
|
-
labels=SAPM_MR_LABELS,
|
186
|
-
content_by_path=content_by_path,
|
187
|
-
title=title,
|
188
|
-
description=description,
|
189
|
-
)
|
190
|
-
)
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc529.dist-info → qontract_reconcile-0.10.1rc531.dist-info}/top_level.txt
RENAMED
File without changes
|