qontract-reconcile 0.10.1rc1198__py3-none-any.whl → 0.10.1rc1199__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.1rc1198
3
+ Version: 0.10.1rc1199
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
@@ -192,16 +192,16 @@ reconcile/endpoints_discovery/integration.py,sha256=znfnlm8bZesfcNbQnaR2aaVM-DTB
192
192
  reconcile/endpoints_discovery/merge_request.py,sha256=_yLb4tnvoZMCko8rta2C_CvOInJa9pa3HzSmHNtjgGU,2978
193
193
  reconcile/endpoints_discovery/merge_request_manager.py,sha256=wUMsumxv8RnWaRattax4HfoRlhtVzmgro3GiJJ1C4Vc,6392
194
194
  reconcile/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
- reconcile/external_resources/aws.py,sha256=EN2Vz6IRp6TNWX5vwGAGESrD09_8sTFzKgZjdDR6cmg,7072
196
- reconcile/external_resources/factories.py,sha256=KrJDh52_8PeCEVjwfeVr1jwAJDdhMXRQ_XcBETfnKY4,4988
195
+ reconcile/external_resources/aws.py,sha256=NSaOeHqFEcMaMxNjJwuQZosolgsJ8XRVvwkEEBj9vrw,7730
196
+ reconcile/external_resources/factories.py,sha256=TyJMaijDfPIFYks9i6dhKN7nSR1BoCkoBs1iPExKpcE,5493
197
197
  reconcile/external_resources/integration.py,sha256=gBVO5dE8JyZ3xYcYik-MTIp_18oU7_hpYc_oztyfElQ,6753
198
198
  reconcile/external_resources/integration_secrets_sync.py,sha256=dX09O3r6KURziUYYfiki10orNjOGVma-XojhVqd0ww4,1667
199
- reconcile/external_resources/manager.py,sha256=M_duB1JjQ3xRghvErbmAAbb3mWCo4bFf_2LHqAJVK7E,14991
199
+ reconcile/external_resources/manager.py,sha256=X5ErbtpCKsgAcUi65ZSXICPGxo5MAvNgWPHm_oNlaA8,15445
200
200
  reconcile/external_resources/meta.py,sha256=noaytFzmShpzLA_ebGh7wuP45mOfHIOnnoUxivjDa1I,672
201
201
  reconcile/external_resources/metrics.py,sha256=8MZgNtNZzIRSYTX97KEUIUTETZBhitULzWxbShGyMO8,3193
202
- reconcile/external_resources/model.py,sha256=HVbt2dUJSoIj4MTNlAJeweKp4L0Af0XaNZXoCER7nVw,10571
202
+ reconcile/external_resources/model.py,sha256=8F2-ks-MomF9pQLkplYayTWdjnKf74szce3o_QkFkLs,10889
203
203
  reconcile/external_resources/reconciler.py,sha256=K9QvbQCIOCuOHnPIxQE_P_jFtrkF3dGo8d_cCCh08Ys,8973
204
- reconcile/external_resources/secrets_sync.py,sha256=fxzrNreggWJvASonIPUr3CB5M637M1ljZLZr6dct9xU,16329
204
+ reconcile/external_resources/secrets_sync.py,sha256=H8JfI3JW1XEau1jqv15AhYg49mCZeHwZmqMzMv_6tFc,16344
205
205
  reconcile/external_resources/state.py,sha256=7DBzVhIvYqeZWrWapmU_bXXftTQa_m-EOwJFVlIFnDw,9583
206
206
  reconcile/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
207
  reconcile/glitchtip/integration.py,sha256=XtewM9nfTPLnPSpYebP50GrveYOnhTvKNq3seSvL6u8,8343
@@ -882,8 +882,8 @@ tools/test/test_qontract_cli.py,sha256=iuzKbQ6ahinvjoQmQLBrG4shey0z-1rB6qCgS8T6d
882
882
  tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
883
883
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
884
884
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
885
- qontract_reconcile-0.10.1rc1198.dist-info/METADATA,sha256=Cm6U5Z2jCGWiZmnTJGDeU-yaw7dCIkonvABx3Wf_6KA,2213
886
- qontract_reconcile-0.10.1rc1198.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
887
- qontract_reconcile-0.10.1rc1198.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
888
- qontract_reconcile-0.10.1rc1198.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
889
- qontract_reconcile-0.10.1rc1198.dist-info/RECORD,,
885
+ qontract_reconcile-0.10.1rc1199.dist-info/METADATA,sha256=L2cXRJAPGUQMnGZHs38z11biOeCYbgwMUvcdrg0EpII,2213
886
+ qontract_reconcile-0.10.1rc1199.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
887
+ qontract_reconcile-0.10.1rc1199.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
888
+ qontract_reconcile-0.10.1rc1199.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
889
+ qontract_reconcile-0.10.1rc1199.dist-info/RECORD,,
@@ -3,6 +3,7 @@ from typing import Any
3
3
 
4
4
  from reconcile.external_resources.model import (
5
5
  ExternalResource,
6
+ ExternalResourceKey,
6
7
  ExternalResourcesInventory,
7
8
  )
8
9
  from reconcile.utils.external_resource_spec import (
@@ -25,6 +26,13 @@ class AWSResourceFactory(ABC):
25
26
  @abstractmethod
26
27
  def validate(self, resource: ExternalResource) -> None: ...
27
28
 
29
+ def find_linked_resources(
30
+ self, spec: ExternalResourceSpec
31
+ ) -> set[ExternalResourceKey]:
32
+ """Method to find dependant resources. Resources in this list
33
+ will be reconciled every time the parent resource finishes its reconciliation."""
34
+ return set()
35
+
28
36
 
29
37
  class AWSDefaultResourceFactory(AWSResourceFactory):
30
38
  def resolve(self, spec: ExternalResourceSpec) -> dict[str, Any]:
@@ -136,6 +144,17 @@ class AWSRdsFactory(AWSDefaultResourceFactory):
136
144
 
137
145
  def validate(self, resource: ExternalResource) -> None: ...
138
146
 
147
+ def find_linked_resources(
148
+ self, spec: ExternalResourceSpec
149
+ ) -> set[ExternalResourceKey]:
150
+ return {
151
+ k
152
+ for k, s in self.er_inventory.items()
153
+ if s.provision_provider == "aws"
154
+ and s.provider == "rds"
155
+ and s.resource["replica_source"] == spec.identifier
156
+ }
157
+
139
158
 
140
159
  class AWSMskFactory(AWSDefaultResourceFactory):
141
160
  def _get_source_db_spec(
@@ -60,6 +60,13 @@ class ExternalResourceFactory(ABC):
60
60
  def validate_external_resource(self, resource: ExternalResource) -> None:
61
61
  pass
62
62
 
63
+ def find_linked_resources(
64
+ self, spec: ExternalResourceSpec
65
+ ) -> set[ExternalResourceKey]:
66
+ """Method to find dependant resources. Resources in this list
67
+ will be reconciled every time the parent resource finishes its reconciliation."""
68
+ return set()
69
+
63
70
 
64
71
  class ModuleProvisionDataFactory(ABC):
65
72
  @abstractmethod
@@ -148,3 +155,9 @@ class AWSExternalResourceFactory(ExternalResourceFactory):
148
155
  def validate_external_resource(self, resource: ExternalResource) -> None:
149
156
  f = self.resource_factories.get_factory(resource.provision.provider)
150
157
  f.validate(resource)
158
+
159
+ def find_linked_resources(
160
+ self, spec: ExternalResourceSpec
161
+ ) -> set[ExternalResourceKey]:
162
+ f = self.resource_factories.get_factory(spec.provider)
163
+ return f.find_linked_resources(spec)
@@ -161,7 +161,7 @@ class ExternalResourcesManager:
161
161
  continue
162
162
  module = self.module_inventory.get_from_spec(spec)
163
163
  try:
164
- resource = self._build_external_resource(spec, self.er_inventory)
164
+ resource = self._build_external_resource(spec)
165
165
  except ExternalResourceValidationError as e:
166
166
  self.errors[key] = e
167
167
  continue
@@ -169,11 +169,12 @@ class ExternalResourcesManager:
169
169
  reconciliation = Reconciliation(
170
170
  key=key,
171
171
  resource_hash=resource.hash(),
172
- input=self._serialize_resource_input(resource),
172
+ input=resource.json(),
173
173
  action=Action.APPLY,
174
174
  module_configuration=ExternalResourceModuleConfiguration.resolve_configuration(
175
175
  module, spec, self.settings
176
176
  ),
177
+ linked_resources=self._find_linked_resources(spec),
177
178
  )
178
179
  r.add(reconciliation)
179
180
  return r
@@ -273,6 +274,13 @@ class ExternalResourcesManager:
273
274
  state.update_resource_status(reconciliation_status)
274
275
  self.state_mgr.set_external_resource_state(state)
275
276
 
277
+ if r.linked_resources:
278
+ for lr in r.linked_resources:
279
+ lrs = self.state_mgr.get_external_resource_state(lr)
280
+ if not lrs.resource_status.is_in_progress:
281
+ lrs.resource_status = ResourceStatus.RECONCILIATION_REQUESTED
282
+ self.state_mgr.set_external_resource_state(lrs)
283
+
276
284
  def _set_resource_reconciliation_in_progress(
277
285
  self, r: Reconciliation, state: ExternalResourceState
278
286
  ) -> None:
@@ -317,16 +325,17 @@ class ExternalResourcesManager:
317
325
  )
318
326
  self.state_mgr.update_resource_status(key, ResourceStatus.CREATED)
319
327
 
320
- def _build_external_resource(
321
- self, spec: ExternalResourceSpec, er_inventory: ExternalResourcesInventory
322
- ) -> ExternalResource:
328
+ def _build_external_resource(self, spec: ExternalResourceSpec) -> ExternalResource:
323
329
  f = self.factories.get_factory(spec.provision_provider)
324
330
  resource = f.create_external_resource(spec)
325
331
  f.validate_external_resource(resource)
326
332
  return resource
327
333
 
328
- def _serialize_resource_input(self, resource: ExternalResource) -> str:
329
- return resource.json()
334
+ def _find_linked_resources(
335
+ self, spec: ExternalResourceSpec
336
+ ) -> set[ExternalResourceKey]:
337
+ f = self.factories.get_factory(spec.provision_provider)
338
+ return f.find_linked_resources(spec)
330
339
 
331
340
  def handle_resources(self) -> None:
332
341
  desired_r = self._get_desired_objects_reconciliations()
@@ -3,11 +3,7 @@ import json
3
3
  from abc import (
4
4
  ABC,
5
5
  )
6
- from collections.abc import (
7
- Iterable,
8
- Iterator,
9
- MutableMapping,
10
- )
6
+ from collections.abc import ItemsView, Iterable, Iterator, MutableMapping
11
7
  from enum import StrEnum
12
8
  from typing import Any
13
9
 
@@ -82,17 +78,17 @@ class ExternalResourcesInventory(MutableMapping):
82
78
  def __init__(self, namespaces: Iterable[NamespaceV1]) -> None:
83
79
  self._inventory: dict[ExternalResourceKey, ExternalResourceSpec] = {}
84
80
 
85
- desired_providers = [
86
- (p, ns)
81
+ resource_providers = [
82
+ (rp, ns)
87
83
  for ns in namespaces
88
- for p in ns.external_resources or []
89
- if isinstance(p, SUPPORTED_RESOURCE_PROVIDERS) and p.resources
84
+ for rp in ns.external_resources or []
85
+ if isinstance(rp, SUPPORTED_RESOURCE_PROVIDERS) and rp.resources
90
86
  ]
91
87
 
92
88
  desired_specs = [
93
- self._build_external_resource_spec(ns, p, r)
94
- for (p, ns) in desired_providers
95
- for r in p.resources
89
+ self._build_external_resource_spec(ns, rp, r)
90
+ for (rp, ns) in resource_providers
91
+ for r in rp.resources
96
92
  if isinstance(r, SUPPORTED_RESOURCE_TYPES) and r.managed_by_erv2
97
93
  ]
98
94
 
@@ -136,6 +132,9 @@ class ExternalResourcesInventory(MutableMapping):
136
132
  def __len__(self) -> int:
137
133
  return len(self._inventory)
138
134
 
135
+ def items(self) -> ItemsView[ExternalResourceKey, ExternalResourceSpec]:
136
+ return self._inventory.items()
137
+
139
138
  def get_inventory_spec(
140
139
  self, provision_provider: str, provisioner: str, provider: str, identifier: str
141
140
  ) -> ExternalResourceSpec:
@@ -281,6 +280,9 @@ class Reconciliation(BaseModel, frozen=True):
281
280
  module_configuration: ExternalResourceModuleConfiguration = (
282
281
  ExternalResourceModuleConfiguration()
283
282
  )
283
+ # linked_resources store dependants resources. They will get reconciled
284
+ # every time the parent resource reconciliation finishes.
285
+ linked_resources: frozenset[ExternalResourceKey] | None
284
286
 
285
287
 
286
288
  class ReconcileAction(StrEnum):
@@ -20,7 +20,9 @@ from reconcile.external_resources.meta import (
20
20
  SECRET_UPDATED_AT,
21
21
  SECRET_UPDATED_AT_TIMEFORMAT,
22
22
  )
23
- from reconcile.external_resources.model import ExternalResourceKey
23
+ from reconcile.external_resources.model import (
24
+ ExternalResourceKey,
25
+ )
24
26
  from reconcile.openshift_base import ApplyOptions, apply_action
25
27
  from reconcile.typed_queries.clusters_minimal import get_clusters_minimal
26
28
  from reconcile.utils.differ import diff_mappings
@@ -207,7 +209,7 @@ class SecretsReconciler:
207
209
  If current is newer; don't apply.
208
210
  If other changes; apply and Recycle Pods
209
211
  Desired can not be newer than current.
210
- External reosurce to Cluster (last reconciliation):
212
+ External resource to Cluster (last reconciliation):
211
213
  If updated_at annotation is the only change; Don't update
212
214
  If other changes; Update Secret and Recycle Pods
213
215
  Current can not be newer then Desired
@@ -233,7 +235,7 @@ class SecretsReconciler:
233
235
 
234
236
  if self.ri.has_error_registered():
235
237
  # Return all specs as error if there are errors.
236
- # There is no a clear way to kwno which specs failed.
238
+ # There is not a clear way to know which specs have failed.
237
239
  return list(specs)
238
240
  else:
239
241
  return []