qontract-reconcile 0.10.2.dev94__py3-none-any.whl → 0.10.2.dev96__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.
- {qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/RECORD +9 -9
- reconcile/fleet_labeler/dependencies.py +4 -0
- reconcile/fleet_labeler/integration.py +45 -24
- reconcile/fleet_labeler/metrics.py +46 -1
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +2 -0
- reconcile/gql_definitions/introspection.json +12 -0
- {qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev96
|
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
|
{qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/RECORD
RENAMED
@@ -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=
|
211
|
-
reconcile/fleet_labeler/integration.py,sha256=
|
210
|
+
reconcile/fleet_labeler/dependencies.py,sha256=6vD9dC1pXOztWQpQCZa2ZLbXrTf50kzjtpqewRybuJ4,3169
|
211
|
+
reconcile/fleet_labeler/integration.py,sha256=vMvDnQW1NXv2qWeG8ab_gguBq45UtmYErSXy6XR83d8,14149
|
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=
|
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
|
@@ -224,7 +224,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=BgMx-NyV9mTuv7Sotb2OioC
|
|
224
224
|
reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
225
225
|
reconcile/glitchtip_project_dsn/integration.py,sha256=2iugub-kHYkHNK33n0v9_TeWonuxCPah_VkoTPvaajE,8077
|
226
226
|
reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
227
|
-
reconcile/gql_definitions/introspection.json,sha256=
|
227
|
+
reconcile/gql_definitions/introspection.json,sha256=xA_cHhSy0wr9PG9y_Nwk75MbnjtHQjOEMd48nLZMK8E,2239784
|
228
228
|
reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
229
229
|
reconcile/gql_definitions/acs/acs_instances.py,sha256=L91WW9LbhJbBSrECqShQpFtjoBOsmNIYLRpMbx1io5o,2181
|
230
230
|
reconcile/gql_definitions/acs/acs_policies.py,sha256=bN5i4mks10Z23KJSj7jqp966Osq2dps4d-sPH9gjxEA,7008
|
@@ -314,7 +314,7 @@ reconcile/gql_definitions/external_resources/external_resources_settings.py,sha2
|
|
314
314
|
reconcile/gql_definitions/external_resources/fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
315
315
|
reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py,sha256=T_qWCRtzU8F9frebBXG9TkeQdrKGt3R9YinSngPoFqM,1262
|
316
316
|
reconcile/gql_definitions/fleet_labeler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
317
|
-
reconcile/gql_definitions/fleet_labeler/fleet_labels.py,sha256=
|
317
|
+
reconcile/gql_definitions/fleet_labeler/fleet_labels.py,sha256=ow9LTm376Y5rCVMWgRtrj2yWKK7_aBC5AM7svLN7pKo,4546
|
318
318
|
reconcile/gql_definitions/fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
319
319
|
reconcile/gql_definitions/fragments/aus_organization.py,sha256=uBKbTuBa3CZmTXR5HOcGhRcu2U9kM93KbYmoWTxcpB0,4767
|
320
320
|
reconcile/gql_definitions/fragments/aws_account_common.py,sha256=3-7ZAP6GSff7Z2Syz2VQCLY4IySqBOSVmceaRiVNQpw,2385
|
@@ -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.
|
790
|
-
qontract_reconcile-0.10.2.
|
791
|
-
qontract_reconcile-0.10.2.
|
792
|
-
qontract_reconcile-0.10.2.
|
789
|
+
qontract_reconcile-0.10.2.dev96.dist-info/METADATA,sha256=HAWau-mbdGSxEIuXiVqfR00bMYmkHZPCrQn2jcTzmmU,24565
|
790
|
+
qontract_reconcile-0.10.2.dev96.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
791
|
+
qontract_reconcile-0.10.2.dev96.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
792
|
+
qontract_reconcile-0.10.2.dev96.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
|
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,13 +89,15 @@ 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
|
)
|
95
|
+
synch_labels = spec.dry_run_label_synchronization or dependencies.dry_run
|
94
96
|
self._sync_subscription_labels(
|
95
97
|
spec=spec,
|
96
98
|
desired_clusters=all_desired_clusters,
|
97
99
|
ocm=ocm,
|
98
|
-
dry_run=
|
100
|
+
dry_run=synch_labels,
|
99
101
|
)
|
100
102
|
|
101
103
|
def _discover_desired_clusters(
|
@@ -243,6 +245,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
243
245
|
vcs: VCS,
|
244
246
|
clusters_with_duplicate_matches: dict[str, list[ClusterData]],
|
245
247
|
all_desired_clusters: dict[str, ClusterData],
|
248
|
+
metrics: FleetLabelerMetrics,
|
246
249
|
dry_run: bool,
|
247
250
|
) -> None:
|
248
251
|
all_current_cluster_ids = {cluster.cluster_id for cluster in spec.clusters}
|
@@ -253,28 +256,46 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
253
256
|
logging.error(
|
254
257
|
f"[{spec.name}] Cluster ID {cluster_id} is matched multiple times by different label matchers:\n{label_matches}"
|
255
258
|
)
|
256
|
-
metrics.
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
),
|
261
|
-
len(clusters_with_duplicate_matches),
|
259
|
+
metrics.set_duplicate_cluster_matches_gauge(
|
260
|
+
ocm_name=spec.ocm.name,
|
261
|
+
spec_name=spec.name,
|
262
|
+
value=len(clusters_with_duplicate_matches),
|
262
263
|
)
|
263
264
|
|
264
|
-
clusters_to_add = [
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
265
|
+
clusters_to_add: list[YamlCluster] = []
|
266
|
+
label_rendering_errors_cnt = 0
|
267
|
+
for cluster_id, cluster_info in all_desired_clusters.items():
|
268
|
+
if cluster_id in all_current_cluster_ids:
|
269
|
+
continue
|
270
|
+
try:
|
271
|
+
default_labels = self._render_default_labels(
|
271
272
|
template=cluster_info.desired_label_default.subscription_label_template,
|
272
273
|
labels=ocm.get_cluster_labels(cluster_id=cluster_id),
|
273
|
-
)
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
274
|
+
)
|
275
|
+
except Exception as e:
|
276
|
+
logging.error(
|
277
|
+
f"[{spec.name}] Error while rendering default labels for {cluster_id=} {cluster_info.subscription_id=} - skipping cluster: {e}"
|
278
|
+
)
|
279
|
+
default_labels = None
|
280
|
+
label_rendering_errors_cnt += 1
|
281
|
+
|
282
|
+
if default_labels:
|
283
|
+
# Note, we are skipping this cluster if there are no default_labels rendered
|
284
|
+
clusters_to_add.append(
|
285
|
+
YamlCluster(
|
286
|
+
cluster_id=cluster_id,
|
287
|
+
subscription_id=cluster_info.subscription_id,
|
288
|
+
name=cluster_info.name,
|
289
|
+
server_url=cluster_info.server_url,
|
290
|
+
subscription_labels_content=default_labels,
|
291
|
+
)
|
292
|
+
)
|
293
|
+
metrics.set_label_rendering_error_gauge(
|
294
|
+
ocm_name=spec.ocm.name,
|
295
|
+
spec_name=spec.name,
|
296
|
+
value=label_rendering_errors_cnt,
|
297
|
+
)
|
298
|
+
|
278
299
|
cluster_ids_to_delete = all_current_cluster_ids - all_desired_clusters.keys()
|
279
300
|
|
280
301
|
if not (cluster_ids_to_delete or clusters_to_add):
|
@@ -282,7 +303,7 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
282
303
|
|
283
304
|
for yaml_cluster in clusters_to_add:
|
284
305
|
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}."
|
306
|
+
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
307
|
)
|
287
308
|
for cluster_id in cluster_ids_to_delete:
|
288
309
|
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"
|
@@ -33,6 +33,7 @@ query FleetLabelSpecs {
|
|
33
33
|
name
|
34
34
|
path
|
35
35
|
managedSubscriptionLabelPrefix
|
36
|
+
dryRunLabelSynchronization
|
36
37
|
ocm {
|
37
38
|
name
|
38
39
|
environment {
|
@@ -113,6 +114,7 @@ class FleetLabelsSpecV1(ConfiguredBaseModel):
|
|
113
114
|
name: str = Field(..., alias="name")
|
114
115
|
path: str = Field(..., alias="path")
|
115
116
|
managed_subscription_label_prefix: str = Field(..., alias="managedSubscriptionLabelPrefix")
|
117
|
+
dry_run_label_synchronization: Optional[bool] = Field(..., alias="dryRunLabelSynchronization")
|
116
118
|
ocm: OpenShiftClusterManagerV1 = Field(..., alias="ocm")
|
117
119
|
label_defaults: list[FleetLabelDefaultV1] = Field(..., alias="labelDefaults")
|
118
120
|
clusters: list[FleetClusterV1] = Field(..., alias="clusters")
|
@@ -34397,6 +34397,18 @@
|
|
34397
34397
|
"isDeprecated": false,
|
34398
34398
|
"deprecationReason": null
|
34399
34399
|
},
|
34400
|
+
{
|
34401
|
+
"name": "dryRunLabelSynchronization",
|
34402
|
+
"description": null,
|
34403
|
+
"args": [],
|
34404
|
+
"type": {
|
34405
|
+
"kind": "SCALAR",
|
34406
|
+
"name": "Boolean",
|
34407
|
+
"ofType": null
|
34408
|
+
},
|
34409
|
+
"isDeprecated": false,
|
34410
|
+
"deprecationReason": null
|
34411
|
+
},
|
34400
34412
|
{
|
34401
34413
|
"name": "managedSubscriptionLabelPrefix",
|
34402
34414
|
"description": null,
|
{qontract_reconcile-0.10.2.dev94.dist-info → qontract_reconcile-0.10.2.dev96.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|