qontract-reconcile 0.10.1rc995__py3-none-any.whl → 0.10.1rc996__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.1rc995
3
+ Version: 0.10.1rc996
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=7-GNgB05b5MGrnEuD0resVNL3hOsQNSYcAAHrR68sS0,105755
13
+ reconcile/cli.py,sha256=lLVw-FxEUR8zU6UAKZzJk7XwRbjsXPaGUAQqXuBYSaU,105825
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
@@ -187,9 +187,9 @@ reconcile/dynatrace_token_provider/ocm.py,sha256=iHMsgbsLs-dlrB9UXmWNDF7E4UDe49J
187
187
  reconcile/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
188
  reconcile/external_resources/aws.py,sha256=JvjKaABy2Pg8u8Lq82Acv4zMvpE3_qGKes7OG-zlHOM,2956
189
189
  reconcile/external_resources/factories.py,sha256=DXgaLxoO87zZ76VOpRpu2GeYGhsbfOnOx5mrzgo4Gf4,4767
190
- reconcile/external_resources/integration.py,sha256=PJOpz-wUf7NzWvqCDalRWu5OxKjgi5RwiiB6HZfJs0k,5122
190
+ reconcile/external_resources/integration.py,sha256=y1gJ16woMBC3J9qniMmS5y3lCkAs7V_ETZRUwjKqaO0,6628
191
191
  reconcile/external_resources/integration_secrets_sync.py,sha256=cMEZhgCvABAMf-DWF051L6CRnJQdfbsISA_b1xuS940,1670
192
- reconcile/external_resources/manager.py,sha256=5X9HjANMUGkZgC5RUA0r2TvZIbHw0UID1odn2QWrND4,14675
192
+ reconcile/external_resources/manager.py,sha256=8lHOFyA_xF8thQXbmJp8zzA2-oJ0MUhfnCcFpkexwjU,15089
193
193
  reconcile/external_resources/meta.py,sha256=cMT9OsKcUY26qwEjlQ02EkorvOBNqWj0JVMwfJa3Mg0,634
194
194
  reconcile/external_resources/metrics.py,sha256=m2TIOao2N7pD6k45driFbBGVCC_N7ai44m-lLPfa5qk,454
195
195
  reconcile/external_resources/model.py,sha256=oXxJkjhV53lwwAuxUCBrjJ8aCJmQdgcKWv68ugJPK4k,7229
@@ -854,8 +854,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
854
854
  tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
855
855
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
856
856
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
857
- qontract_reconcile-0.10.1rc995.dist-info/METADATA,sha256=O45HKoKnz-vWM-qm9KKu_RKXfZNVmO9fhTPKN4PKROk,2262
858
- qontract_reconcile-0.10.1rc995.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
859
- qontract_reconcile-0.10.1rc995.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
860
- qontract_reconcile-0.10.1rc995.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
861
- qontract_reconcile-0.10.1rc995.dist-info/RECORD,,
857
+ qontract_reconcile-0.10.1rc996.dist-info/METADATA,sha256=1yk8ORxJ5XgceH637jz-GGaURn1NIRcEEF228Yd0_UM,2262
858
+ qontract_reconcile-0.10.1rc996.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
859
+ qontract_reconcile-0.10.1rc996.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
860
+ qontract_reconcile-0.10.1rc996.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
861
+ qontract_reconcile-0.10.1rc996.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -3714,20 +3714,20 @@ def deadmanssnitch(ctx):
3714
3714
  )
3715
3715
  def external_resources(
3716
3716
  ctx,
3717
- workers_cluster: str,
3718
- workers_namespace: str,
3719
3717
  dry_run_job_suffix: str,
3720
3718
  thread_pool_size: int,
3719
+ workers_cluster: str,
3720
+ workers_namespace: str,
3721
3721
  ):
3722
3722
  import reconcile.external_resources.integration
3723
3723
 
3724
3724
  run_integration(
3725
3725
  reconcile.external_resources.integration,
3726
3726
  ctx.obj,
3727
- dry_run_job_suffix,
3728
- thread_pool_size,
3729
- workers_cluster,
3730
- workers_namespace,
3727
+ dry_run_job_suffix=dry_run_job_suffix,
3728
+ thread_pool_size=thread_pool_size,
3729
+ workers_cluster=workers_cluster,
3730
+ workers_namespace=workers_namespace,
3731
3731
  )
3732
3732
 
3733
3733
 
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  from collections.abc import Callable
3
+ from typing import Any
3
4
 
4
5
  from reconcile.external_resources.manager import (
5
6
  ExternalResourcesInventory,
@@ -73,6 +74,62 @@ def get_aws_api(
73
74
  return AWSApi(aws_credentials)
74
75
 
75
76
 
77
+ def create_er_manager(
78
+ aws_api: AWSApi,
79
+ workers_cluster: str | None,
80
+ workers_namespace: str | None,
81
+ thread_pool_size: int,
82
+ dry_run: bool,
83
+ dry_run_job_suffix: str,
84
+ ) -> ExternalResourcesManager:
85
+ vault_settings = get_app_interface_vault_settings()
86
+ secret_reader = create_secret_reader(use_vault=vault_settings.vault)
87
+ er_settings = get_settings()[0]
88
+ m_inventory = load_module_inventory(get_modules())
89
+ namespaces = [ns for ns in get_namespaces() if ns.external_resources]
90
+ er_inventory = ExternalResourcesInventory(namespaces)
91
+
92
+ if not workers_cluster:
93
+ workers_cluster = er_settings.workers_cluster.name
94
+ if not workers_namespace:
95
+ workers_namespace = er_settings.workers_namespace.name
96
+
97
+ return ExternalResourcesManager(
98
+ thread_pool_size=thread_pool_size,
99
+ settings=er_settings,
100
+ secret_reader=secret_reader,
101
+ factories=setup_factories(
102
+ er_settings, m_inventory, er_inventory, secret_reader
103
+ ),
104
+ er_inventory=er_inventory,
105
+ module_inventory=m_inventory,
106
+ state_manager=ExternalResourcesStateDynamoDB(
107
+ aws_api=aws_api,
108
+ table_name=er_settings.state_dynamodb_table,
109
+ ),
110
+ reconciler=K8sExternalResourcesReconciler(
111
+ controller=build_job_controller(
112
+ integration=QONTRACT_INTEGRATION,
113
+ integration_version=QONTRACT_INTEGRATION_VERSION,
114
+ cluster=workers_cluster,
115
+ namespace=workers_namespace,
116
+ secret_reader=secret_reader,
117
+ dry_run=dry_run,
118
+ ),
119
+ dry_run=dry_run,
120
+ dry_run_job_suffix=dry_run_job_suffix,
121
+ ),
122
+ secrets_reconciler=build_incluster_secrets_reconciler(
123
+ workers_cluster,
124
+ workers_namespace,
125
+ secret_reader,
126
+ vault_path=er_settings.vault_secrets_path,
127
+ thread_pool_size=thread_pool_size,
128
+ dry_run=dry_run,
129
+ ),
130
+ )
131
+
132
+
76
133
  def run(
77
134
  dry_run: bool,
78
135
  dry_run_job_suffix: str,
@@ -83,9 +140,6 @@ def run(
83
140
  vault_settings = get_app_interface_vault_settings()
84
141
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
85
142
  er_settings = get_settings()[0]
86
- m_inventory = load_module_inventory(get_modules())
87
- namespaces = [ns for ns in get_namespaces() if ns.external_resources]
88
- er_inventory = ExternalResourcesInventory(namespaces)
89
143
 
90
144
  if not workers_cluster:
91
145
  workers_cluster = er_settings.workers_cluster.name
@@ -98,41 +152,14 @@ def run(
98
152
  region=er_settings.state_dynamodb_region,
99
153
  secret_reader=secret_reader,
100
154
  ) as aws_api:
101
- er_mgr = ExternalResourcesManager(
102
- thread_pool_size=thread_pool_size,
103
- settings=er_settings,
104
- secret_reader=secret_reader,
105
- factories=setup_factories(
106
- er_settings, m_inventory, er_inventory, secret_reader
107
- ),
108
- er_inventory=er_inventory,
109
- module_inventory=m_inventory,
110
- state_manager=ExternalResourcesStateDynamoDB(
111
- aws_api=aws_api,
112
- table_name=er_settings.state_dynamodb_table,
113
- ),
114
- reconciler=K8sExternalResourcesReconciler(
115
- controller=build_job_controller(
116
- integration=QONTRACT_INTEGRATION,
117
- integration_version=QONTRACT_INTEGRATION_VERSION,
118
- cluster=workers_cluster,
119
- namespace=workers_namespace,
120
- secret_reader=secret_reader,
121
- dry_run=dry_run,
122
- ),
123
- dry_run=dry_run,
124
- dry_run_job_suffix=dry_run_job_suffix,
125
- ),
126
- secrets_reconciler=build_incluster_secrets_reconciler(
127
- workers_cluster,
128
- workers_namespace,
129
- secret_reader,
130
- vault_path=er_settings.vault_secrets_path,
131
- thread_pool_size=thread_pool_size,
132
- dry_run=dry_run,
133
- ),
155
+ er_mgr = create_er_manager(
156
+ aws_api,
157
+ workers_cluster,
158
+ workers_namespace,
159
+ thread_pool_size,
160
+ dry_run,
161
+ dry_run_job_suffix,
134
162
  )
135
-
136
163
  if dry_run:
137
164
  er_mgr.handle_dry_run_resources()
138
165
  if er_mgr.errors:
@@ -141,3 +168,25 @@ def run(
141
168
  logging.error("ExternalResourceKey: %s, Error: %s" % (k, e))
142
169
  else:
143
170
  er_mgr.handle_resources()
171
+
172
+
173
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
174
+ vault_settings = get_app_interface_vault_settings()
175
+ secret_reader = create_secret_reader(use_vault=vault_settings.vault)
176
+ er_settings = get_settings()[0]
177
+
178
+ with get_aws_api(
179
+ query_func=gql.get_api().query,
180
+ account_name=er_settings.state_dynamodb_account.name,
181
+ region=er_settings.state_dynamodb_region,
182
+ secret_reader=secret_reader,
183
+ ) as aws_api:
184
+ er_mgr = create_er_manager(
185
+ aws_api,
186
+ workers_cluster=kwargs["workers_cluster"],
187
+ workers_namespace=kwargs["workers_namespace"],
188
+ thread_pool_size=kwargs["thread_pool_size"],
189
+ dry_run=True,
190
+ dry_run_job_suffix=kwargs["dry_run_job_suffix"],
191
+ )
192
+ return er_mgr.get_all_reconciliations()
@@ -116,7 +116,7 @@ class ExternalResourcesManager:
116
116
  return ReconcileAction.APPLY_NOT_EXISTS
117
117
  case ResourceStatus.ERROR:
118
118
  return ReconcileAction.APPLY_ERROR
119
- case ResourceStatus.CREATED:
119
+ case ResourceStatus.CREATED | ResourceStatus.PENDING_SECRET_SYNC:
120
120
  if (
121
121
  reconciliation.resource_hash
122
122
  != state.reconciliation.resource_hash
@@ -154,6 +154,14 @@ class ExternalResourcesManager:
154
154
  )
155
155
  return reconcile
156
156
 
157
+ def get_all_reconciliations(self) -> dict[str, set[Reconciliation]]:
158
+ """Returns all reconciliations in a dict. Useful to return all data
159
+ from app-interface to make comparisions (early-exit)"""
160
+ return {
161
+ "desired": self._get_desired_objects_reconciliations(),
162
+ "deleted": self._get_deleted_objects_reconciliations(),
163
+ }
164
+
157
165
  def _get_desired_objects_reconciliations(self) -> set[Reconciliation]:
158
166
  r: set[Reconciliation] = set()
159
167
  for key, spec in self.er_inventory.items():