qontract-reconcile 0.10.1rc886__py3-none-any.whl → 0.10.1rc888__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc886
3
+ Version: 0.10.1rc888
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
@@ -10,7 +10,7 @@ reconcile/aws_iam_password_reset.py,sha256=q96mwr2KeEQ5bpNniGlgIMZTxiuLSodcYfX-t
10
10
  reconcile/aws_support_cases_sos.py,sha256=Jk6_XjDeJSYxgRGqcEAOcynt9qJF2r5HPIPcSKmoBv8,2974
11
11
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
12
12
  reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
13
- reconcile/cli.py,sha256=6N_nkpjSm4L-q9fxW6CW07Pof1y412R7eQ54z_30vLA,105113
13
+ reconcile/cli.py,sha256=YHpIxOaOuRlpBCXtlbiJR2fRjAMK0_4vJULYnRO9CS4,105636
14
14
  reconcile/closedbox_endpoint_monitoring_base.py,sha256=rLh16BOlBOxTmJ8Si3wWyyEpmMlhh4Znx1Gc36qsmOc,4865
15
15
  reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
16
16
  reconcile/dashdotdb_base.py,sha256=4gJ_VXOOPXPNrJIkSlOr8N1PD60ciZZqSBobNPhXvUA,4768
@@ -179,7 +179,9 @@ reconcile/cna/assets/asset.py,sha256=KWgA4fuDAEGsJwmR52WwK_YgSJMW-1cV2la3lmNf4iE
179
179
  reconcile/cna/assets/asset_factory.py,sha256=7T7X_J6xIsoGETqBRI45_EyIKEdQcnRPt_GAuVuLQcc,785
180
180
  reconcile/cna/assets/null.py,sha256=85mVh97atCoC0aLuX47poTZiyOthmziJeBsUw0c924w,1658
181
181
  reconcile/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
- reconcile/dynatrace_token_provider/integration.py,sha256=Tt3Nayf1TOdizBStXdEaJKfKqlOkJljw22lWlN2GB2s,16518
182
+ reconcile/dynatrace_token_provider/integration.py,sha256=Q7XCnlqoXb4uRsatLciEQlbTSU-HjCRmTd0AHhkxagU,16541
183
+ reconcile/dynatrace_token_provider/integration_v2.py,sha256=Si-hwvGSnC4kVF33-QBZ9FTc4Jfsl_PcESbfl_XmVL8,558
184
+ reconcile/dynatrace_token_provider/meta.py,sha256=f1EdgTS-fuQMUnBmzQFNwvo3Rr9mzNO2R5aOH44oCYg,50
183
185
  reconcile/dynatrace_token_provider/metrics.py,sha256=xiKkl8fTEBQaXJelGCPNTZhHAWdO1M3pCXNr_Tei63c,1285
184
186
  reconcile/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
187
  reconcile/external_resources/aws.py,sha256=JvjKaABy2Pg8u8Lq82Acv4zMvpE3_qGKes7OG-zlHOM,2956
@@ -428,7 +430,7 @@ reconcile/saas_auto_promotions_manager/integration.py,sha256=haXTpwi0rEQtN9-MadB
428
430
  reconcile/saas_auto_promotions_manager/meta.py,sha256=76Jp50r6Y_KyJoXFfSjrt5YrCtXyg_A4FXXxHYiS3TE,161
429
431
  reconcile/saas_auto_promotions_manager/publisher.py,sha256=IZGu-PMffyk3fNL8QcZ2VBmYTZ5zigoCwNJ4_Ak6-C8,2966
430
432
  reconcile/saas_auto_promotions_manager/s3_exporter.py,sha256=IKlVWZmiPnvl7sKeF6JgAlhXZe5CovKTxQc0SNkNSx4,2583
431
- reconcile/saas_auto_promotions_manager/subscriber.py,sha256=YPzlv8jptvvWgMIoXn4Jtk7-LST8grrVyi0-qTpqWQQ,8474
433
+ reconcile/saas_auto_promotions_manager/subscriber.py,sha256=A-d_qIUo5jbseEaAN3YlVU46MQAVCw28j5HvORgaGtw,9149
432
434
  reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
433
435
  reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py,sha256=CP392gq0yntzEkqpMJl2j-N4CGfFDFbBfK77J7Oo5Pg,7817
434
436
  reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py,sha256=isY8frVsL3PlcdZmdZ4O0qyp76oczl4DUMX9uMArs5Y,1222
@@ -439,7 +441,7 @@ reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py,sha256
439
441
  reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py,sha256=-qGQOh6Jdp4lomNDij3zWVC0pl6uPHFWS5Woqcp5HQk,410
440
442
  reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=IZ7cuH6uOi7f0aIPVi1irBmP0CIK5vmEuhKBJz4YA1s,7235
441
443
  reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
442
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=ZZ7JL6VPfKasq-XXi6CL2UZ89jOcC9uwLW1e8LMvgws,8187
444
+ reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=rGvBWGcpryM-W3nasBET-PHAXY2ZZL9ihcTe70qoQEA,8660
443
445
  reconcile/skupper_network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
444
446
  reconcile/skupper_network/integration.py,sha256=GEFlQTjK4DYXnvrQtsvFdZlYsbiFabM7IdBX69ZXWcY,10757
445
447
  reconcile/skupper_network/models.py,sha256=HEwlVKsbmMaKaaBGvITIiSYNEVdjwXVhLaOJgLSZ2xQ,6604
@@ -560,7 +562,7 @@ reconcile/test/test_version_bump.py,sha256=q6-3Y1roriI6YWpFwaHOMN7emEP3yL33sh_0V
560
562
  reconcile/test/test_vpc_peerings_validator.py,sha256=dFSmjc_dMN2GqMbntCFpa7PUZmyYuQ9DKffh-T5wmxM,6639
561
563
  reconcile/test/test_wrong_region.py,sha256=7KzL7OaICQ9Z3DW27zt_ykMN7_87owAFC-2CYjvGoyA,2138
562
564
  reconcile/test/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
563
- reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=WqTFZAqCtWBCl8vdY1xGXpxLTMxXDAaZJ65UmaMSs1Y,5966
565
+ reconcile/test/saas_auto_promotions_manager/conftest.py,sha256=tF6YMgeh9PHxlKsihL8qdLEgixk_k6mOGV1qS7ukHYI,6029
564
566
  reconcile/test/saas_auto_promotions_manager/test_integration_test.py,sha256=S30eXJSy2Vc3YLbCP7AfLkOiFGUVoKhEvEBL5vwnbfg,1848
565
567
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
566
568
  reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -841,8 +843,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
841
843
  tools/test/test_saas_promotion_state.py,sha256=48Qe5UA5WTI5NVgL7Nz0TSS77osetcijfHNCNdsHfSI,2726
842
844
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
843
845
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
844
- qontract_reconcile-0.10.1rc886.dist-info/METADATA,sha256=4g0A5WsMn09DnEGihlWR7RXjtoeEjfpaBn6La8GQvmQ,2273
845
- qontract_reconcile-0.10.1rc886.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
846
- qontract_reconcile-0.10.1rc886.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
847
- qontract_reconcile-0.10.1rc886.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
848
- qontract_reconcile-0.10.1rc886.dist-info/RECORD,,
846
+ qontract_reconcile-0.10.1rc888.dist-info/METADATA,sha256=Jdlu3njSekBAi5WRIsJmrYWirEt8p6xfH9Iz73XPjK8,2273
847
+ qontract_reconcile-0.10.1rc888.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
848
+ qontract_reconcile-0.10.1rc888.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
849
+ qontract_reconcile-0.10.1rc888.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
850
+ qontract_reconcile-0.10.1rc888.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -3045,8 +3045,25 @@ def dynatrace_token_provider(ctx, ocm_org_ids):
3045
3045
  DynatraceTokenProviderIntegration,
3046
3046
  DynatraceTokenProviderIntegrationParams,
3047
3047
  )
3048
+ from reconcile.dynatrace_token_provider.integration_v2 import (
3049
+ DynatraceTokenProviderIntegrationParamsV2,
3050
+ DynatraceTokenProviderIntegrationV2,
3051
+ )
3048
3052
 
3049
3053
  parsed_ocm_org_ids = set(ocm_org_ids.split(",")) if ocm_org_ids else None
3054
+
3055
+ # We will remove V1 once migrations towards new token declaration is done
3056
+ # Run V2
3057
+ run_class_integration(
3058
+ integration=DynatraceTokenProviderIntegrationV2(
3059
+ DynatraceTokenProviderIntegrationParamsV2(
3060
+ ocm_organization_ids=parsed_ocm_org_ids
3061
+ )
3062
+ ),
3063
+ ctx=ctx.obj,
3064
+ )
3065
+
3066
+ # Run V1
3050
3067
  run_class_integration(
3051
3068
  integration=DynatraceTokenProviderIntegration(
3052
3069
  DynatraceTokenProviderIntegrationParams(
@@ -8,6 +8,7 @@ from typing import Any
8
8
  from dynatrace import Dynatrace
9
9
  from dynatrace.environment_v2.tokens_api import ApiTokenCreated
10
10
 
11
+ from reconcile.dynatrace_token_provider.meta import QONTRACT_INTEGRATION
11
12
  from reconcile.dynatrace_token_provider.metrics import (
12
13
  DTPClustersManagedGauge,
13
14
  DTPOrganizationErrorRate,
@@ -52,7 +53,6 @@ from reconcile.utils.runtime.integration import (
52
53
  )
53
54
  from reconcile.utils.secret_reader import SecretReaderBase
54
55
 
55
- QONTRACT_INTEGRATION = "dynatrace-token-provider"
56
56
  SYNCSET_ID = "ext-dynatrace-tokens-dtp"
57
57
  SECRET_NAME = "dynatrace-token-dtp"
58
58
  SECRET_NAMESPACE = "dynatrace"
@@ -0,0 +1,20 @@
1
+ from reconcile.dynatrace_token_provider.meta import QONTRACT_INTEGRATION
2
+ from reconcile.utils.runtime.integration import (
3
+ PydanticRunParams,
4
+ QontractReconcileIntegration,
5
+ )
6
+
7
+
8
+ class DynatraceTokenProviderIntegrationParamsV2(PydanticRunParams):
9
+ ocm_organization_ids: set[str] | None = None
10
+
11
+
12
+ class DynatraceTokenProviderIntegrationV2(
13
+ QontractReconcileIntegration[DynatraceTokenProviderIntegrationParamsV2]
14
+ ):
15
+ @property
16
+ def name(self) -> str:
17
+ return QONTRACT_INTEGRATION
18
+
19
+ def run(self, dry_run: bool) -> None:
20
+ pass
@@ -0,0 +1 @@
1
+ QONTRACT_INTEGRATION = "dynatrace-token-provider"
@@ -44,6 +44,7 @@ class Subscriber:
44
44
  use_target_config_hash: bool,
45
45
  uid: str,
46
46
  soak_days: int,
47
+ blocked_versions: set[str],
47
48
  ):
48
49
  self.saas_name = saas_name
49
50
  self.template_name = template_name
@@ -58,6 +59,7 @@ class Subscriber:
58
59
  self.soak_days = soak_days
59
60
  self._content_hash = ""
60
61
  self._use_target_config_hash = use_target_config_hash
62
+ self._blocked_versions = blocked_versions
61
63
 
62
64
  def has_diff(self) -> bool:
63
65
  current_hashes = {
@@ -141,22 +143,42 @@ class Subscriber:
141
143
  break
142
144
  publisher_refs.add(publisher.commit_sha)
143
145
 
144
- if len(publisher_refs) > 1:
146
+ # By default we keep current state
147
+ self.desired_ref = self.ref
148
+
149
+ if any_bad_deployment:
150
+ logging.info(
151
+ "Subscriber at path %s promotion stopped because of bad publisher deployment",
152
+ self.target_file_path,
153
+ )
154
+ return
155
+
156
+ if len(publisher_refs) != 1:
145
157
  logging.info(
146
158
  "Publishers for subscriber at path %s have mismatching refs: %s",
147
159
  self.target_file_path,
148
160
  publisher_refs,
149
161
  )
150
- if (
151
- len(publisher_refs) != 1
152
- or any_bad_deployment
153
- or not self._passed_accumulated_soak_days()
154
- ):
155
- # We keep current state
156
- self.desired_ref = self.ref
157
- else:
158
- # We have a common single publisher ref w/o any deployment issues
159
- self.desired_ref = next(iter(publisher_refs))
162
+ return
163
+
164
+ if not self._passed_accumulated_soak_days():
165
+ logging.debug(
166
+ "Subscriber at path %s promotion stopped because of soak days",
167
+ self.target_file_path,
168
+ )
169
+ return
170
+
171
+ desired_ref = next(iter(publisher_refs))
172
+ if desired_ref in self._blocked_versions:
173
+ logging.info(
174
+ "Subscriber at path %s promotion stopped because of blocked ref: %s",
175
+ self.target_file_path,
176
+ desired_ref,
177
+ )
178
+ return
179
+
180
+ # Passed all gates -> lets promote desired ref
181
+ self.desired_ref = desired_ref
160
182
 
161
183
  def _compute_desired_config_hashes(self) -> None:
162
184
  """
@@ -86,6 +86,10 @@ class SaasFilesInventory:
86
86
 
87
87
  def _assemble_subscribers_with_auto_promotions(self) -> None:
88
88
  for saas_file in self._saas_files:
89
+ blocked_versions: dict[str, set[str]] = {}
90
+ for code_component in saas_file.app.code_components or []:
91
+ for version in code_component.blocked_versions or []:
92
+ blocked_versions.setdefault(code_component.url, set()).add(version)
89
93
  for resource_template in saas_file.resource_templates:
90
94
  for target in resource_template.targets:
91
95
  file_path = target.path if target.path else saas_file.path
@@ -98,6 +102,7 @@ class SaasFilesInventory:
98
102
  soak_days = (
99
103
  target.promotion.soak_days if target.promotion.soak_days else 0
100
104
  )
105
+ resource_template.url
101
106
  subscriber = Subscriber(
102
107
  uid=target.uid(
103
108
  parent_saas_file_name=saas_file.name,
@@ -109,6 +114,9 @@ class SaasFilesInventory:
109
114
  ref=target.ref,
110
115
  target_namespace=target.namespace,
111
116
  soak_days=soak_days,
117
+ blocked_versions=blocked_versions.get(
118
+ resource_template.url, set()
119
+ ),
112
120
  # Note: this will be refactored at a later point.
113
121
  # https://issues.redhat.com/browse/APPSRE-7516
114
122
  use_target_config_hash=bool(saas_file.publish_job_logs),
@@ -158,6 +158,7 @@ def subscriber_builder(
158
158
  template_name="",
159
159
  use_target_config_hash=data.get("USE_TARGET_CONFIG_HASH", True),
160
160
  soak_days=data.get("SOAK_DAYS", 0),
161
+ blocked_versions=data.get("BLOCKED_VERSIONS", {}),
161
162
  )
162
163
  subscriber.channels = channels
163
164
  subscriber.config_hashes_by_channel_name = cur_config_hashes_by_channel