qontract-reconcile 0.10.1rc878__py3-none-any.whl → 0.10.1rc879__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.1rc878
3
+ Version: 0.10.1rc879
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
@@ -258,8 +258,8 @@ reconcile/gql_definitions/common/pgp_reencryption_settings.py,sha256=NPLmO6J-zSu
258
258
  reconcile/gql_definitions/common/pipeline_providers.py,sha256=JJgmmghqLIwjKOdcWYHPnf4PDgAq4GF7046i0ozrqgI,9127
259
259
  reconcile/gql_definitions/common/quay_instances.py,sha256=toBkdYYVTmEafezAHZKgaW-mQ29xEW6jeronzsAlNyI,1786
260
260
  reconcile/gql_definitions/common/reserved_networks.py,sha256=yP9qSQCaSQcva-ZgTnZp09qH27ur5_qK080ToIs04MY,2560
261
- reconcile/gql_definitions/common/saas_files.py,sha256=rt-ugGWWO148cE_8-cbRkNPJ4peYDQoAnSZ3c5qT_dk,16390
262
- reconcile/gql_definitions/common/saas_target_namespaces.py,sha256=ZmX9SYoLQnjTc9zU6ehFNUs_GgOedim3v73A-83Gnsc,2813
261
+ reconcile/gql_definitions/common/saas_files.py,sha256=8JoysSi-lAjsdGKTK3YBTBPYy95B47guXzfp71JHh1I,16516
262
+ reconcile/gql_definitions/common/saas_target_namespaces.py,sha256=4VYP2VbwY8WVwtSFk2-jsUNhSmRD3X4FWKxetOKvmd0,2835
263
263
  reconcile/gql_definitions/common/saasherder_settings.py,sha256=nqQLcMwYxLseqq0BEcVvmrpIj2eQq0h8XDSpLN6GGCw,1793
264
264
  reconcile/gql_definitions/common/slack_workspaces.py,sha256=2o0kgi4QiaRuNmZJnc_By4F6NsKIdRaXkrufRQw7Nok,1753
265
265
  reconcile/gql_definitions/common/smtp_client_settings.py,sha256=JU6t6D-Qj-z1gLlgUiHKe0W7AxWQdty9jlv-ig_43tM,2248
@@ -299,7 +299,7 @@ reconcile/gql_definitions/fragments/prometheus_instance.py,sha256=12ltnV9kdEw6Ln
299
299
  reconcile/gql_definitions/fragments/resource_limits_requirements.py,sha256=ucskQ_a8RxvFl5-IWxz5kk3g4-5Pvh_W4N3nLmuKxi0,744
300
300
  reconcile/gql_definitions/fragments/resource_requests_requirements.py,sha256=TFKO4YALFPanSvZvIJFz0dCioBU7i73Q6hkDtGMvs9I,736
301
301
  reconcile/gql_definitions/fragments/resource_values.py,sha256=-N2lNRhWp8PgocmIeX3U9f3l90Q97N2lXoq1pXdb_LE,742
302
- reconcile/gql_definitions/fragments/saas_target_namespace.py,sha256=Ei39iL5J5TzeYtoBqbUF6zog3ctXTK-ZQyvbIVcUI20,3921
302
+ reconcile/gql_definitions/fragments/saas_target_namespace.py,sha256=8kMXeD7u2bmdjn10zHmMJ80ScOhUp6KqSfWfjWZW-40,4001
303
303
  reconcile/gql_definitions/fragments/terraform_state.py,sha256=S5QuTR9YlvUObiU7hevS9ybxZEssWoRGqCR9YtGwePs,1024
304
304
  reconcile/gql_definitions/fragments/upgrade_policy.py,sha256=cVza8zfra1E3yBsHiS-hKbys17fvv572GFnKshJjluE,1246
305
305
  reconcile/gql_definitions/fragments/user.py,sha256=84RGYYSYnZmyrwHlCX89-EgAu7UaLFOTMQXobmHCfz8,939
@@ -535,7 +535,7 @@ reconcile/test/test_quay_repos.py,sha256=TdkcRF_a8PLp01Kti9eZZN-vGup2yPBT4Iba3k0
535
535
  reconcile/test/test_queries.py,sha256=SpH3RmNpBjEr_ne3VjAMCgKK8RE1z1zo7bypkT5uoO4,1946
536
536
  reconcile/test/test_repo_owners.py,sha256=uRYMLbMmh-9usF0TerabZTZV-Z1CS4I6ybT-LQqCLe8,1423
537
537
  reconcile/test/test_requests_sender.py,sha256=7fd9C2kEFS0-CYtlsif66N1kO9c44pzuBPAJKR9igqU,5385
538
- reconcile/test/test_saasherder.py,sha256=fdjcygNFPz1YyU2uB-8IU3yQZr6MlD8np2_fYUsL2b8,54440
538
+ reconcile/test/test_saasherder.py,sha256=C2vwkdjk2cccS14GML2ByG8WKcRP8wgTJfzwaEUKdtw,54603
539
539
  reconcile/test/test_saasherder_allowed_secret_paths.py,sha256=5NHQwNJO66at6HiyMZ5sVRTQDwxdvlOQo0KmkBWCw5Q,4853
540
540
  reconcile/test/test_secret_reader.py,sha256=kz7nzcPjvA08cytnvcA_PMA98AEyqJWsESkYeRn5xCk,4994
541
541
  reconcile/test/test_slack_base.py,sha256=gpbWOLNxMMX6fyAbs1JakhLTnwfedb3f7WpUae4tQZE,5060
@@ -787,9 +787,9 @@ reconcile/utils/runtime/meta.py,sha256=X44HzyXIBprf3zcsGr2XLCgoeFkz6r3U2nlFXM1H7
787
787
  reconcile/utils/runtime/runner.py,sha256=72cc-I6yXyPov8UCLHpyERRy1eiMLpGite2roO0yUlo,7979
788
788
  reconcile/utils/runtime/sharding.py,sha256=roCdbnBklhTK_g34zbgQYqzpKPaNQ8J6Xd9XLO9-t6Q,16258
789
789
  reconcile/utils/saasherder/__init__.py,sha256=J3MBZBFa5YmhqYm08QsjBXz8mFcVOCiOCkyIcw41t7E,343
790
- reconcile/utils/saasherder/interfaces.py,sha256=q7Xhs95RMwOCCqlfjelqWJOiUqhPYkpL20XaOMRxEZs,9321
790
+ reconcile/utils/saasherder/interfaces.py,sha256=UG3O5zuamNrP1bgbfhQAtNfN_8W9_iSv7UBESnR-mXE,9363
791
791
  reconcile/utils/saasherder/models.py,sha256=iLQZGXMx4FYnK62MJKkVp1T32BpsZ88NOcU7RW0WyAk,5579
792
- reconcile/utils/saasherder/saasherder.py,sha256=cQhyuBGUbtFL8_1lMDRwnrSaYC88C_ApgcaBruZ7BZ4,87523
792
+ reconcile/utils/saasherder/saasherder.py,sha256=boCEscTR7Vu6Zjjd7pJIQDO5B_gYiOljwgBa_KDUVLM,88141
793
793
  reconcile/utils/terraform/__init__.py,sha256=zNbiyTWo35AT1sFTElL2j_AA0jJ_yWE_bfFn-nD2xik,250
794
794
  reconcile/utils/terraform/config.py,sha256=5UVrd563TMcvi4ooa5JvWVDW1I3bIWg484u79evfV_8,164
795
795
  reconcile/utils/terraform/config_client.py,sha256=py-Ree-QUYD6Hvng6bM40VgSuttteehIKNgwOSoJO1o,4706
@@ -837,8 +837,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
837
837
  tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jrss,4941
838
838
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
839
839
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
840
- qontract_reconcile-0.10.1rc878.dist-info/METADATA,sha256=yc6zH-3Cqe1m2HcHSAx5gtwBQGqkbkGv3wpeOBz8b2M,2273
841
- qontract_reconcile-0.10.1rc878.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
842
- qontract_reconcile-0.10.1rc878.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
843
- qontract_reconcile-0.10.1rc878.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
844
- qontract_reconcile-0.10.1rc878.dist-info/RECORD,,
840
+ qontract_reconcile-0.10.1rc879.dist-info/METADATA,sha256=4h4jN56Q5GugfmWXxRkczGqc0xzefD2xu-AnO3BlsBc,2273
841
+ qontract_reconcile-0.10.1rc879.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
842
+ qontract_reconcile-0.10.1rc879.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
843
+ qontract_reconcile-0.10.1rc879.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
844
+ qontract_reconcile-0.10.1rc879.dist-info/RECORD,,
@@ -84,6 +84,7 @@ fragment SaasTargetNamespace on Namespace_v1 {
84
84
  }
85
85
  codeComponents {
86
86
  url
87
+ blockedVersions
87
88
  hotfixVersions
88
89
  }
89
90
  }
@@ -143,6 +144,7 @@ query SaasFiles {
143
144
  }
144
145
  codeComponents {
145
146
  url
147
+ blockedVersions
146
148
  hotfixVersions
147
149
  }
148
150
  }
@@ -330,6 +332,7 @@ class OwnerV1(ConfiguredBaseModel):
330
332
 
331
333
  class AppCodeComponentsV1(ConfiguredBaseModel):
332
334
  url: str = Field(..., alias="url")
335
+ blocked_versions: Optional[list[str]] = Field(..., alias="blockedVersions")
333
336
  hotfix_versions: Optional[list[str]] = Field(..., alias="hotfixVersions")
334
337
 
335
338
 
@@ -63,6 +63,7 @@ fragment SaasTargetNamespace on Namespace_v1 {
63
63
  }
64
64
  codeComponents {
65
65
  url
66
+ blockedVersions
66
67
  hotfixVersions
67
68
  }
68
69
  }
@@ -54,6 +54,7 @@ class OwnerV1(ConfiguredBaseModel):
54
54
 
55
55
  class AppCodeComponentsV1(ConfiguredBaseModel):
56
56
  url: str = Field(..., alias="url")
57
+ blocked_versions: Optional[list[str]] = Field(..., alias="blockedVersions")
57
58
  hotfix_versions: Optional[list[str]] = Field(..., alias="hotfixVersions")
58
59
 
59
60
 
@@ -1354,7 +1354,7 @@ class TestRemoveNoneAttributes(TestCase):
1354
1354
 
1355
1355
 
1356
1356
  @pytest.mark.usefixtures("inject_gql_class_factory")
1357
- class TestPromotionHoxfixVersions(TestCase):
1357
+ class TestPromotionBlockedHoxfixVersions(TestCase):
1358
1358
  def setUp(self) -> None:
1359
1359
  self.saas_file = self.gql_class_factory( # type: ignore[attr-defined] # it's set in the fixture
1360
1360
  SaasFile,
@@ -1382,7 +1382,7 @@ class TestPromotionHoxfixVersions(TestCase):
1382
1382
  self.state_patcher.stop()
1383
1383
  self.promotion_state_patcher.stop()
1384
1384
 
1385
- def test_hotfix_version_valid_promotion(self) -> None:
1385
+ def test_blocked_hotfix_version_promotion_validity(self) -> None:
1386
1386
  code_component_url = "https://github.com/app-sre/test-saas-deployments"
1387
1387
  hotfix_version = "1234567890123456789012345678901234567890"
1388
1388
  # code_component = self.saas_file.app.code_components[0]
@@ -1408,6 +1408,9 @@ class TestPromotionHoxfixVersions(TestCase):
1408
1408
  self.saasherder.hotfix_versions[code_component_url] = {hotfix_version}
1409
1409
  self.assertTrue(self.saasherder.validate_promotions())
1410
1410
 
1411
+ self.saasherder.blocked_versions[code_component_url] = {hotfix_version}
1412
+ self.assertFalse(self.saasherder.validate_promotions())
1413
+
1411
1414
 
1412
1415
  def test_render_templated_parameters(
1413
1416
  gql_class_factory: Callable[..., SaasFileInterface],
@@ -361,6 +361,7 @@ class SaasServiceOwner(Protocol):
361
361
 
362
362
  class AppCodeComponent(Protocol):
363
363
  url: str
364
+ blocked_versions: Optional[list[str]]
364
365
  hotfix_versions: Optional[list[str]]
365
366
 
366
367
 
@@ -150,6 +150,7 @@ class SaasHerder: # pylint: disable=too-many-public-methods
150
150
  self._promotion_state = PromotionState(state=state) if state else None
151
151
  self._channel_map = self._assemble_channels(saas_files=all_saas_files)
152
152
  self.images: set[str] = set()
153
+ self.blocked_versions = self._collect_blocked_versions()
153
154
  self.hotfix_versions = self._collect_hotfix_versions()
154
155
 
155
156
  # each namespace is in fact a target,
@@ -1100,6 +1101,14 @@ class SaasHerder: # pylint: disable=too-many-public-methods
1100
1101
  channel_map[publish].publisher_uids.append(publisher_uid)
1101
1102
  return channel_map
1102
1103
 
1104
+ def _collect_blocked_versions(self) -> dict[str, set[str]]:
1105
+ blocked_versions: dict[str, set[str]] = {}
1106
+ for saas_file in self.saas_files:
1107
+ for cc in saas_file.app.code_components or []:
1108
+ for v in cc.blocked_versions or []:
1109
+ blocked_versions.setdefault(cc.url, set()).add(v)
1110
+ return blocked_versions
1111
+
1103
1112
  def _collect_hotfix_versions(self) -> dict[str, set[str]]:
1104
1113
  hotfix_versions: dict[str, set[str]] = {}
1105
1114
  for saas_file in self.saas_files:
@@ -1899,6 +1908,10 @@ class SaasHerder: # pylint: disable=too-many-public-methods
1899
1908
  if not promotion.subscribe:
1900
1909
  return True
1901
1910
 
1911
+ if promotion.commit_sha in self.blocked_versions.get(promotion.url, set()):
1912
+ logging.error(f"Commit {promotion.commit_sha} is blocked!")
1913
+ return False
1914
+
1902
1915
  # hotfix must run before further gates are evaluated to override them
1903
1916
  if promotion.commit_sha in self.hotfix_versions.get(promotion.url, set()):
1904
1917
  return True