qontract-reconcile 0.10.1rc1035__py3-none-any.whl → 0.10.1rc1037__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.1rc1035
3
+ Version: 0.10.1rc1037
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=hl_9L53yQYRQxKs3IWrd69Cc60XK067g_bJRM9B0udo,2975
11
11
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
12
12
  reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
13
- reconcile/cli.py,sha256=2hjHLQED4DR41EHoov3uHiURb8dfAbDpaTwxnEvrVhk,107388
13
+ reconcile/cli.py,sha256=2Qxyuwrp90j9Pox_2px5LZDn8oomwrQuFtdY85xMBOE,107389
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=l34QDu1G96_Ctnh7ZXdxXgSeCE93GQMdLAkWxmN6vDA,4775
@@ -180,11 +180,12 @@ reconcile/cna/assets/asset.py,sha256=KWgA4fuDAEGsJwmR52WwK_YgSJMW-1cV2la3lmNf4iE
180
180
  reconcile/cna/assets/asset_factory.py,sha256=7T7X_J6xIsoGETqBRI45_EyIKEdQcnRPt_GAuVuLQcc,785
181
181
  reconcile/cna/assets/null.py,sha256=85mVh97atCoC0aLuX47poTZiyOthmziJeBsUw0c924w,1658
182
182
  reconcile/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
- reconcile/dynatrace_token_provider/dependencies.py,sha256=41q05A4C_eS3E8-MR4veeMxtQNsPoGdxmEa3d-OKxq4,2814
184
- reconcile/dynatrace_token_provider/integration.py,sha256=-oAZ40IHLbY99PZB9THtH2FnS5LHCKpQMIYFdy1bp4Q,22997
183
+ reconcile/dynatrace_token_provider/dependencies.py,sha256=FuRUnK18EyJIIgFwQBZSskIG08mN2VQAcAcaJFTf8zc,2812
184
+ reconcile/dynatrace_token_provider/integration.py,sha256=OaRX5B8KiBvXQ57U8dLchlY2pqep5OM1p8HUNJGKGkc,23196
185
185
  reconcile/dynatrace_token_provider/metrics.py,sha256=xiKkl8fTEBQaXJelGCPNTZhHAWdO1M3pCXNr_Tei63c,1285
186
186
  reconcile/dynatrace_token_provider/model.py,sha256=gkpqo5rRRueBXnIMjp4EEHqBUBuU65TRI8zpdb8GJ0A,241
187
187
  reconcile/dynatrace_token_provider/ocm.py,sha256=iHMsgbsLs-dlrB9UXmWNDF7E4UDe49JOsLa9rnowKfo,4282
188
+ reconcile/dynatrace_token_provider/validate.py,sha256=40_9QmHoB3-KBc0k_0D4QO00PpNNPS-gU9Z6cIcWga8,1920
188
189
  reconcile/endpoints_discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
190
  reconcile/endpoints_discovery/integration.py,sha256=q01DJgCv1YiDY-VUWDfQ5kfGm67BUhP-YP7c0JQObj8,12333
190
191
  reconcile/endpoints_discovery/merge_request.py,sha256=_yLb4tnvoZMCko8rta2C_CvOInJa9pa3HzSmHNtjgGU,2978
@@ -446,7 +447,7 @@ reconcile/saas_auto_promotions_manager/publisher.py,sha256=IZGu-PMffyk3fNL8QcZ2V
446
447
  reconcile/saas_auto_promotions_manager/s3_exporter.py,sha256=IKlVWZmiPnvl7sKeF6JgAlhXZe5CovKTxQc0SNkNSx4,2583
447
448
  reconcile/saas_auto_promotions_manager/subscriber.py,sha256=kIJKT1Xg5FF7EGT5ayK5ROyu_S7FbsYK91WBqrtYjfA,10030
448
449
  reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
449
- reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py,sha256=CP392gq0yntzEkqpMJl2j-N4CGfFDFbBfK77J7Oo5Pg,7817
450
+ reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py,sha256=R2CRtjdOggY5lSqt-A5qz2ymqomx4opVeVV_oqBAW0A,7804
450
451
  reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py,sha256=isY8frVsL3PlcdZmdZ4O0qyp76oczl4DUMX9uMArs5Y,1222
451
452
  reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=BeAJWLow7b4HQyZ9zz398sQkPeIz8chpMkCts2NU27c,1282
452
453
  reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py,sha256=-zWK-cqr_8o9ZEnNfD3cfkv3hrrU4HJ4UMzi4J2Hjhw,6223
@@ -866,8 +867,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
866
867
  tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
867
868
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
868
869
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
869
- qontract_reconcile-0.10.1rc1035.dist-info/METADATA,sha256=RiJA91vmFrk9nRO6TwYbz5-vOJcviyMBW3QeS4nOjTc,2213
870
- qontract_reconcile-0.10.1rc1035.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
871
- qontract_reconcile-0.10.1rc1035.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
872
- qontract_reconcile-0.10.1rc1035.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
873
- qontract_reconcile-0.10.1rc1035.dist-info/RECORD,,
870
+ qontract_reconcile-0.10.1rc1037.dist-info/METADATA,sha256=6F_72A6-bCXEcMeL8AmkvcyhzIc8L2tYbszCURoyl8w,2213
871
+ qontract_reconcile-0.10.1rc1037.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
872
+ qontract_reconcile-0.10.1rc1037.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
873
+ qontract_reconcile-0.10.1rc1037.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
874
+ qontract_reconcile-0.10.1rc1037.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -3124,7 +3124,7 @@ def dynatrace_token_provider(ctx, ocm_org_ids):
3124
3124
  run_class_integration(
3125
3125
  integration=DynatraceTokenProviderIntegration(
3126
3126
  DynatraceTokenProviderIntegrationParams(
3127
- ocm_organization_ids=parsed_ocm_org_ids
3127
+ ocm_organization_ids=parsed_ocm_org_ids,
3128
3128
  )
3129
3129
  ),
3130
3130
  ctx=ctx.obj,
@@ -36,16 +36,16 @@ class Dependencies:
36
36
  self.ocm_client_by_env_name: dict[str, OCMClient] = dict(ocm_client_by_env_name)
37
37
  self.token_spec_by_name = dict(token_spec_by_name)
38
38
 
39
- def populate(self) -> None:
40
- self._populate_dynatrace_client_map()
41
- self._populate_ocm_clients()
42
- self._populate_token_specs()
39
+ def populate_all(self) -> None:
40
+ self.populate_dynatrace_client_map()
41
+ self.populate_ocm_clients()
42
+ self.populate_token_specs()
43
43
 
44
- def _populate_token_specs(self) -> None:
44
+ def populate_token_specs(self) -> None:
45
45
  token_specs = get_dynatrace_token_provider_token_specs()
46
46
  self.token_spec_by_name = {spec.name: spec for spec in token_specs}
47
47
 
48
- def _populate_dynatrace_client_map(self) -> None:
48
+ def populate_dynatrace_client_map(self) -> None:
49
49
  dynatrace_environments = get_dynatrace_environments()
50
50
  if not dynatrace_environments:
51
51
  raise RuntimeError("No Dynatrace environment defined.")
@@ -59,7 +59,7 @@ class Dependencies:
59
59
  tenant_id = tenant.environment_url.split(".")[0].removeprefix("https://")
60
60
  self.dynatrace_client_by_tenant_id[tenant_id] = dt_client
61
61
 
62
- def _populate_ocm_clients(self) -> None:
62
+ def populate_ocm_clients(self) -> None:
63
63
  ocm_environments = get_ocm_environments()
64
64
  self.ocm_client_by_env_name = {
65
65
  env.name: OCMClient(
@@ -17,6 +17,7 @@ from reconcile.dynatrace_token_provider.ocm import (
17
17
  Cluster,
18
18
  OCMClient,
19
19
  )
20
+ from reconcile.dynatrace_token_provider.validate import validate_token_specs
20
21
  from reconcile.gql_definitions.dynatrace_token_provider.token_specs import (
21
22
  DynatraceAPITokenV1,
22
23
  DynatraceTokenProviderTokenSpecV1,
@@ -66,10 +67,13 @@ class DynatraceTokenProviderIntegration(
66
67
  ocm_client_by_env_name={},
67
68
  token_spec_by_name={},
68
69
  )
69
- dependencies.populate()
70
+ dependencies.populate_all()
70
71
  self.reconcile(dry_run=dry_run, dependencies=dependencies)
71
72
 
72
73
  def reconcile(self, dry_run: bool, dependencies: Dependencies) -> None:
74
+ token_specs = list(dependencies.token_spec_by_name.values())
75
+ validate_token_specs(specs=token_specs)
76
+
73
77
  with metrics.transactional_metrics(self.name):
74
78
  unhandled_exceptions = []
75
79
  for ocm_env_name, ocm_client in dependencies.ocm_client_by_env_name.items():
@@ -0,0 +1,48 @@
1
+ from collections.abc import Iterable
2
+
3
+ from reconcile.gql_definitions.dynatrace_token_provider.token_specs import (
4
+ DynatraceTokenProviderTokenSpecV1,
5
+ )
6
+
7
+
8
+ class SecretNotUniqueError(Exception):
9
+ pass
10
+
11
+
12
+ class TokenNameNotUniqueInSecretError(Exception):
13
+ pass
14
+
15
+
16
+ class KeyNameNotUniqueInSecretError(Exception):
17
+ pass
18
+
19
+
20
+ def validate_token_specs(specs: Iterable[DynatraceTokenProviderTokenSpecV1]) -> None:
21
+ """
22
+ We cannot catch all potential errors through json schema definition.
23
+ """
24
+ for spec in specs:
25
+ seen_secrets: set[str] = set()
26
+ for secret in spec.secrets:
27
+ secret_definition_key = f"{secret.namespace}/{secret.name}"
28
+ if secret_definition_key in seen_secrets:
29
+ raise SecretNotUniqueError(
30
+ f"A secret cannot be re-defined and must be unique per spec. Secret '{secret.name}' in namespace '{secret.namespace}' is defined multiple times in spec '{spec.name}'."
31
+ )
32
+ seen_secrets.add(secret_definition_key)
33
+
34
+ seen_tokens: set[str] = set()
35
+ seen_key_names: set[str] = set()
36
+ for token in secret.tokens:
37
+ if token.name in seen_tokens:
38
+ raise TokenNameNotUniqueInSecretError(
39
+ f"A token name must be unique within a secret. Token name '{token.name}' is used more than once in secret '{secret.name}' in token spec '{spec.name}'."
40
+ )
41
+ seen_tokens.add(token.name)
42
+
43
+ secret_key = token.key_name_in_secret or token.name
44
+ if secret_key in seen_key_names:
45
+ raise KeyNameNotUniqueInSecretError(
46
+ f"A key name must be unique within a secret. Key name '{secret_key}' is used more than once in secret '{secret.name}' in token spec '{spec.name}'."
47
+ )
48
+ seen_key_names.add(secret_key)
@@ -8,7 +8,7 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.open_merge_req
8
8
 
9
9
 
10
10
  class Reason(Enum):
11
- MISSING_UNBATCHING = "Closing this MR because it failed MR check and isn't marked as un-batchable yet. cc @kfischer"
11
+ MISSING_UNBATCHING = "Closing this MR because it failed MR check and isn't marked as un-batchable yet."
12
12
  OUTDATED_CONTENT = "Closing this MR because it has out-dated content."
13
13
  NEW_BATCH = "Closing this MR in favor of a new batch MR."
14
14