qontract-reconcile 0.10.2.dev94__py3-none-any.whl → 0.10.2.dev95__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.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev94
3
+ Version: 0.10.2.dev95
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
6
6
  Project-URL: repository, https://github.com/app-sre/qontract-reconcile
@@ -207,11 +207,11 @@ reconcile/external_resources/reconciler.py,sha256=-0trp1K-iUgOQn3mm1ZUSmfaReRrUT
207
207
  reconcile/external_resources/secrets_sync.py,sha256=ZDxzGZ6wC4zxLhA7-L39xDRH6rzUM285gytuzmRQdlw,16208
208
208
  reconcile/external_resources/state.py,sha256=gF3ACdl7YiUlbQ4uEGrD6i_Txxqr6mT9f8IFlTQ-8dY,13176
209
209
  reconcile/fleet_labeler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
210
- reconcile/fleet_labeler/dependencies.py,sha256=ZOpmtwgxEPBWU2yHRc6rhPwlvqhwYSsNMJQ_jVq1dLI,2993
211
- reconcile/fleet_labeler/integration.py,sha256=IeDUDlIIZREQRbsODB9xsCMoNrMk5738OF_fP7lUGFs,13128
210
+ reconcile/fleet_labeler/dependencies.py,sha256=6vD9dC1pXOztWQpQCZa2ZLbXrTf50kzjtpqewRybuJ4,3169
211
+ reconcile/fleet_labeler/integration.py,sha256=ZSzU9BRbZ2OZHyvpKnuA0mywzwd0MLRlXRSmwseU6Tk,14071
212
212
  reconcile/fleet_labeler/merge_request.py,sha256=SfGxXInxeJzVnsTtO0ZC9-PesUJMdpKxKY9eCB6ms-g,1538
213
213
  reconcile/fleet_labeler/meta.py,sha256=lWnpH2U0PHCPXu9Ok_CPmO494qQJQ5pOuqo28s0jzIQ,146
214
- reconcile/fleet_labeler/metrics.py,sha256=wx9BmXLsN67m-aSsf81iB7Ehj5SzUsS2WB75isUReZg,662
214
+ reconcile/fleet_labeler/metrics.py,sha256=zhcp06woGaZywTqWZf3znh6C2S2u7OHBLXalXYKuTzQ,1934
215
215
  reconcile/fleet_labeler/ocm.py,sha256=qcg1_p7nKlZG7-MQeOZos3rz6YSPAPh-HKxE3OVJwe0,4165
216
216
  reconcile/fleet_labeler/validate.py,sha256=gzc2tt7h9F60h7dcyJfEmsnjnfuux5Jtc_WzrIqr-5k,2541
217
217
  reconcile/fleet_labeler/vcs.py,sha256=6UHUQ08AGAHXF7629I6X-T_E1pvx96LxjS66EeOzve4,1108
@@ -786,7 +786,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
786
786
  tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
787
787
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
788
788
  tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
789
- qontract_reconcile-0.10.2.dev94.dist-info/METADATA,sha256=6jF1IpkimS99Wf-hXeOV8tYFGl0GGQgVl_p9Ax-YDG4,24565
790
- qontract_reconcile-0.10.2.dev94.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
791
- qontract_reconcile-0.10.2.dev94.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
792
- qontract_reconcile-0.10.2.dev94.dist-info/RECORD,,
789
+ qontract_reconcile-0.10.2.dev95.dist-info/METADATA,sha256=FExU6hytglivZHRD19B4ZwbM0V_IKNav1MoR2JBG65M,24565
790
+ qontract_reconcile-0.10.2.dev95.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
791
+ qontract_reconcile-0.10.2.dev95.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
792
+ qontract_reconcile-0.10.2.dev95.dist-info/RECORD,,
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import Mapping
4
4
 
5
+ from reconcile.fleet_labeler.metrics import FleetLabelerMetrics
5
6
  from reconcile.fleet_labeler.ocm import OCMClient, OCMClientConfig
6
7
  from reconcile.fleet_labeler.vcs import VCS
7
8
  from reconcile.gql_definitions.fleet_labeler.fleet_labels import FleetLabelsSpecV1
@@ -26,12 +27,14 @@ class Dependencies:
26
27
  self,
27
28
  label_specs_by_name: Mapping[str, FleetLabelsSpecV1],
28
29
  ocm_clients_by_label_spec_name: Mapping[str, OCMClient],
30
+ metrics: FleetLabelerMetrics,
29
31
  vcs: VCS,
30
32
  dry_run: bool,
31
33
  ):
32
34
  self.label_specs_by_name = label_specs_by_name
33
35
  self.ocm_clients_by_label_spec_name = ocm_clients_by_label_spec_name
34
36
  self.vcs = vcs
37
+ self.metrics = metrics
35
38
  self.dry_run = dry_run
36
39
 
37
40
  @classmethod
@@ -45,6 +48,7 @@ class Dependencies:
45
48
  ocm_clients_by_label_spec_name=_ocm_clients(secret_reader=secret_reader),
46
49
  vcs=_vcs(secret_reader=secret_reader, dry_run=dry_run),
47
50
  dry_run=dry_run,
51
+ metrics=FleetLabelerMetrics(),
48
52
  )
49
53
 
50
54
 
@@ -13,7 +13,9 @@ from reconcile.fleet_labeler.meta import (
13
13
  QONTRACT_INTEGRATION,
14
14
  QONTRACT_INTEGRATION_VERSION,
15
15
  )
16
- from reconcile.fleet_labeler.metrics import FleetLabelerDuplicateClusterMatchesGauge
16
+ from reconcile.fleet_labeler.metrics import (
17
+ FleetLabelerMetrics,
18
+ )
17
19
  from reconcile.fleet_labeler.ocm import OCMClient
18
20
  from reconcile.fleet_labeler.validate import validate_label_specs
19
21
  from reconcile.fleet_labeler.vcs import VCS, Gitlab404Error
@@ -23,9 +25,6 @@ from reconcile.gql_definitions.fleet_labeler.fleet_labels import (
23
25
  FleetSubscriptionLabelTemplateV1,
24
26
  )
25
27
  from reconcile.typed_queries.fleet_labels import get_fleet_label_specs
26
- from reconcile.utils import (
27
- metrics,
28
- )
29
28
  from reconcile.utils.differ import diff_mappings
30
29
  from reconcile.utils.jinja2.utils import process_jinja2_template
31
30
  from reconcile.utils.ruamel import create_ruamel_instance
@@ -67,6 +66,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
67
66
  secret_reader=self.secret_reader,
68
67
  dry_run=dry_run,
69
68
  )
69
+ self._metrics = dependencies.metrics
70
70
  self.reconcile(dependencies=dependencies)
71
71
 
72
72
  def reconcile(self, dependencies: Dependencies) -> None:
@@ -89,6 +89,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
89
89
  vcs=dependencies.vcs,
90
90
  all_desired_clusters=all_desired_clusters,
91
91
  clusters_with_duplicate_matches=clusters_with_duplicate_matches,
92
+ metrics=dependencies.metrics,
92
93
  dry_run=dependencies.dry_run,
93
94
  )
94
95
  self._sync_subscription_labels(
@@ -243,6 +244,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
243
244
  vcs: VCS,
244
245
  clusters_with_duplicate_matches: dict[str, list[ClusterData]],
245
246
  all_desired_clusters: dict[str, ClusterData],
247
+ metrics: FleetLabelerMetrics,
246
248
  dry_run: bool,
247
249
  ) -> None:
248
250
  all_current_cluster_ids = {cluster.cluster_id for cluster in spec.clusters}
@@ -253,28 +255,46 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
253
255
  logging.error(
254
256
  f"[{spec.name}] Cluster ID {cluster_id} is matched multiple times by different label matchers:\n{label_matches}"
255
257
  )
256
- metrics.set_gauge(
257
- FleetLabelerDuplicateClusterMatchesGauge(
258
- integration=self.name,
259
- ocm_name=spec.ocm.name,
260
- ),
261
- len(clusters_with_duplicate_matches),
258
+ metrics.set_duplicate_cluster_matches_gauge(
259
+ ocm_name=spec.ocm.name,
260
+ spec_name=spec.name,
261
+ value=len(clusters_with_duplicate_matches),
262
262
  )
263
263
 
264
- clusters_to_add = [
265
- YamlCluster(
266
- cluster_id=cluster_id,
267
- subscription_id=cluster_info.subscription_id,
268
- name=cluster_info.name,
269
- server_url=cluster_info.server_url,
270
- subscription_labels_content=self._render_default_labels(
264
+ clusters_to_add: list[YamlCluster] = []
265
+ label_rendering_errors_cnt = 0
266
+ for cluster_id, cluster_info in all_desired_clusters.items():
267
+ if cluster_id in all_current_cluster_ids:
268
+ continue
269
+ try:
270
+ default_labels = self._render_default_labels(
271
271
  template=cluster_info.desired_label_default.subscription_label_template,
272
272
  labels=ocm.get_cluster_labels(cluster_id=cluster_id),
273
- ),
274
- )
275
- for cluster_id, cluster_info in all_desired_clusters.items()
276
- if cluster_id not in all_current_cluster_ids
277
- ]
273
+ )
274
+ except Exception as e:
275
+ logging.error(
276
+ f"[{spec.name}] Error while rendering default labels for {cluster_id=} {cluster_info.subscription_id=} - skipping cluster: {e}"
277
+ )
278
+ default_labels = None
279
+ label_rendering_errors_cnt += 1
280
+
281
+ if default_labels:
282
+ # Note, we are skipping this cluster if there are no default_labels rendered
283
+ clusters_to_add.append(
284
+ YamlCluster(
285
+ cluster_id=cluster_id,
286
+ subscription_id=cluster_info.subscription_id,
287
+ name=cluster_info.name,
288
+ server_url=cluster_info.server_url,
289
+ subscription_labels_content=default_labels,
290
+ )
291
+ )
292
+ metrics.set_label_rendering_error_gauge(
293
+ ocm_name=spec.ocm.name,
294
+ spec_name=spec.name,
295
+ value=label_rendering_errors_cnt,
296
+ )
297
+
278
298
  cluster_ids_to_delete = all_current_cluster_ids - all_desired_clusters.keys()
279
299
 
280
300
  if not (cluster_ids_to_delete or clusters_to_add):
@@ -282,7 +302,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
282
302
 
283
303
  for yaml_cluster in clusters_to_add:
284
304
  logging.info(
285
- f"[{spec.name}] Adding cluster '{yaml_cluster.name}' with id '{yaml_cluster.cluster_id}' to inventory with default labels {yaml_cluster.subscription_labels_content}."
305
+ f"[{spec.name}] Adding cluster '{yaml_cluster.name}' with id '{yaml_cluster.cluster_id}' and subscription id '{yaml_cluster.subscription_id}' to inventory with default labels {yaml_cluster.subscription_labels_content}."
286
306
  )
287
307
  for cluster_id in cluster_ids_to_delete:
288
308
  logging.info(
@@ -1,13 +1,46 @@
1
1
  from pydantic import BaseModel
2
2
 
3
+ from reconcile.fleet_labeler.meta import QONTRACT_INTEGRATION
4
+ from reconcile.utils import (
5
+ metrics,
6
+ )
3
7
  from reconcile.utils.metrics import (
4
8
  GaugeMetric,
5
9
  )
6
10
 
7
11
 
12
+ class FleetLabelerMetrics:
13
+ """
14
+ Thin OOP wrapper for tests
15
+ """
16
+
17
+ def set_label_rendering_error_gauge(
18
+ self, ocm_name: str, spec_name: str, value: int
19
+ ) -> None:
20
+ metrics.set_gauge(
21
+ FleetLabelerDuplicateClusterMatchesGauge(
22
+ ocm_name=ocm_name,
23
+ spec=spec_name,
24
+ ),
25
+ value,
26
+ )
27
+
28
+ def set_duplicate_cluster_matches_gauge(
29
+ self, ocm_name: str, spec_name: str, value: int
30
+ ) -> None:
31
+ metrics.set_gauge(
32
+ FleetLabelerLabelRenderingErrorGauge(
33
+ ocm_name=ocm_name,
34
+ spec=spec_name,
35
+ ),
36
+ value,
37
+ )
38
+
39
+
8
40
  class FleetLabelerBaseMetric(BaseModel):
9
- integration: str
41
+ integration: str = QONTRACT_INTEGRATION
10
42
  ocm_name: str
43
+ spec: str
11
44
 
12
45
 
13
46
  class FleetLabelerDuplicateClusterMatchesGauge(FleetLabelerBaseMetric, GaugeMetric):
@@ -21,3 +54,15 @@ class FleetLabelerDuplicateClusterMatchesGauge(FleetLabelerBaseMetric, GaugeMetr
21
54
  @classmethod
22
55
  def name(cls) -> str:
23
56
  return "fleet_labeler_duplicate_cluster_matches"
57
+
58
+
59
+ class FleetLabelerLabelRenderingErrorGauge(FleetLabelerBaseMetric, GaugeMetric):
60
+ """
61
+ Gauge for the number of clusters that have label render errors. This
62
+ happens when the fleet labeler is unable to render the subscription labels
63
+ template for a cluster. Check the logs to identify the clusters with label render errors.
64
+ """
65
+
66
+ @classmethod
67
+ def name(cls) -> str:
68
+ return "fleet_labeler_label_rendering_error"