qontract-reconcile 0.10.1rc1025__py3-none-any.whl → 0.10.1rc1027__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.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/RECORD +7 -7
- reconcile/dynatrace_token_provider/integration.py +60 -10
- reconcile/utils/mr/promote_qontract.py +1 -1
- {qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc1027
|
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
|
{qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/RECORD
RENAMED
@@ -181,7 +181,7 @@ reconcile/cna/assets/asset_factory.py,sha256=7T7X_J6xIsoGETqBRI45_EyIKEdQcnRPt_G
|
|
181
181
|
reconcile/cna/assets/null.py,sha256=85mVh97atCoC0aLuX47poTZiyOthmziJeBsUw0c924w,1658
|
182
182
|
reconcile/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
183
183
|
reconcile/dynatrace_token_provider/dependencies.py,sha256=41q05A4C_eS3E8-MR4veeMxtQNsPoGdxmEa3d-OKxq4,2814
|
184
|
-
reconcile/dynatrace_token_provider/integration.py,sha256=
|
184
|
+
reconcile/dynatrace_token_provider/integration.py,sha256=jOpj2qtkI95b_Ih0IH3cYV5G63RBuxhG6kX4RADBWeg,23003
|
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
|
@@ -781,7 +781,7 @@ reconcile/utils/mr/labels.py,sha256=9QRTRjZAtq45zELd9SwavaraczMjwjn5no3RK1YxFTg,
|
|
781
781
|
reconcile/utils/mr/notificator.py,sha256=cp80wFzu_ZzrJPye7L1pI0H6JRGb7hOGuNxJYUq4Yr8,2967
|
782
782
|
reconcile/utils/mr/ocm_update_recommended_version.py,sha256=p_aVP0TGrlKk9WBwgQnYWqUDsED_Hg6G5Bqj0UvtRwA,1536
|
783
783
|
reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py,sha256=ojnIjw-8vRnmCCxOGBOEgPZLH4nC1hcuef74LWw2Rpk,3004
|
784
|
-
reconcile/utils/mr/promote_qontract.py,sha256=
|
784
|
+
reconcile/utils/mr/promote_qontract.py,sha256=3o_Lpn3gQc8HP3kSJRB1d7TvaDoIAKWLap5bhagQRaM,5945
|
785
785
|
reconcile/utils/mr/user_maintenance.py,sha256=cHPBn8zrReWLHalyk-EFdkFJe9zjVjRoZhT4t2zZfGE,3956
|
786
786
|
reconcile/utils/ocm/__init__.py,sha256=xv7CJp7K9LCQfa4gL_W0MMCOD1P4qOy8t5aZj1xXNUE,808
|
787
787
|
reconcile/utils/ocm/addons.py,sha256=_LDdJ-gapM3s5exKlIUt-MlXZTAUoHezbYBU0QmvfWQ,7335
|
@@ -865,8 +865,8 @@ tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jr
|
|
865
865
|
tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
|
866
866
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
867
867
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
868
|
-
qontract_reconcile-0.10.
|
869
|
-
qontract_reconcile-0.10.
|
870
|
-
qontract_reconcile-0.10.
|
871
|
-
qontract_reconcile-0.10.
|
872
|
-
qontract_reconcile-0.10.
|
868
|
+
qontract_reconcile-0.10.1rc1027.dist-info/METADATA,sha256=NZ2RmjjS7vqLah46hp_j6Gny8RHEeRBbHu9EMHd49dc,2213
|
869
|
+
qontract_reconcile-0.10.1rc1027.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
870
|
+
qontract_reconcile-0.10.1rc1027.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
|
871
|
+
qontract_reconcile-0.10.1rc1027.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
872
|
+
qontract_reconcile-0.10.1rc1027.dist-info/RECORD,,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import base64
|
2
|
+
import hashlib
|
2
3
|
import logging
|
3
|
-
from collections.abc import Iterable, Mapping
|
4
|
+
from collections.abc import Iterable, Mapping, MutableMapping
|
4
5
|
from datetime import timedelta
|
5
6
|
from typing import Any
|
6
7
|
|
@@ -140,7 +141,7 @@ class DynatraceTokenProviderIntegration(
|
|
140
141
|
if tenant_id not in existing_dtp_tokens:
|
141
142
|
existing_dtp_tokens[tenant_id] = (
|
142
143
|
dt_client.get_token_ids_map_for_name_prefix(
|
143
|
-
prefix="dtp
|
144
|
+
prefix="dtp"
|
144
145
|
)
|
145
146
|
)
|
146
147
|
|
@@ -172,7 +173,7 @@ class DynatraceTokenProviderIntegration(
|
|
172
173
|
cluster: Cluster,
|
173
174
|
dt_client: DynatraceClient,
|
174
175
|
ocm_client: OCMClient,
|
175
|
-
existing_dtp_tokens:
|
176
|
+
existing_dtp_tokens: MutableMapping[str, str],
|
176
177
|
tenant_id: str,
|
177
178
|
token_spec: DynatraceTokenProviderTokenSpecV1,
|
178
179
|
) -> None:
|
@@ -276,12 +277,52 @@ class DynatraceTokenProviderIntegration(
|
|
276
277
|
f"Patched {token_spec.name=} for {SYNCSET_AND_MANIFEST_ID} in {cluster.external_id=}."
|
277
278
|
)
|
278
279
|
|
280
|
+
def scopes_hash(self, scopes: Iterable[str], length: int) -> str:
|
281
|
+
m = hashlib.sha256()
|
282
|
+
msg = ",".join(sorted(scopes))
|
283
|
+
m.update(msg.encode("utf-8"))
|
284
|
+
return m.hexdigest()[:length]
|
285
|
+
|
286
|
+
def dynatrace_token_name(self, spec: DynatraceAPITokenV1, cluster_uuid: str) -> str:
|
287
|
+
scopes_hash = self.scopes_hash(scopes=spec.scopes, length=12)
|
288
|
+
# We have a limit of 100 chars
|
289
|
+
# cluster_uuid = 36 chars
|
290
|
+
# scopes_hash = 12 chars
|
291
|
+
# prefix + separators = 6 chars
|
292
|
+
return f"dtp_{spec.name[:46]}_{cluster_uuid}_{scopes_hash}"
|
293
|
+
|
294
|
+
def sync_token_in_dynatrace(
|
295
|
+
self,
|
296
|
+
token_id: str,
|
297
|
+
spec: DynatraceAPITokenV1,
|
298
|
+
cluster_uuid: str,
|
299
|
+
dt_client: DynatraceClient,
|
300
|
+
token_name_in_dt_api: str,
|
301
|
+
dry_run: bool,
|
302
|
+
) -> None:
|
303
|
+
"""
|
304
|
+
We ensure that the given token is properly configured in Dynatrace
|
305
|
+
according to the given spec.
|
306
|
+
|
307
|
+
A list query on the tokens does not return each tokens configuration.
|
308
|
+
We encode the token configuration in the token name to save API calls.
|
309
|
+
"""
|
310
|
+
expected_name = self.dynatrace_token_name(spec=spec, cluster_uuid=cluster_uuid)
|
311
|
+
if token_name_in_dt_api != expected_name:
|
312
|
+
logging.info(
|
313
|
+
f"{token_name_in_dt_api=} != {expected_name=}. Sync dynatrace token {token_id=} with {spec=} for {cluster_uuid=}."
|
314
|
+
)
|
315
|
+
if not dry_run:
|
316
|
+
dt_client.update_token(
|
317
|
+
token_id=token_id, name=expected_name, scopes=spec.scopes
|
318
|
+
)
|
319
|
+
|
279
320
|
def generate_desired(
|
280
321
|
self,
|
281
322
|
dry_run: bool,
|
282
323
|
current_k8s_secrets: Iterable[K8sSecret],
|
283
324
|
desired_spec: DynatraceTokenProviderTokenSpecV1,
|
284
|
-
existing_dtp_tokens:
|
325
|
+
existing_dtp_tokens: MutableMapping[str, str],
|
285
326
|
dt_client: DynatraceClient,
|
286
327
|
cluster_uuid: str,
|
287
328
|
) -> tuple[bool, Iterable[K8sSecret]]:
|
@@ -301,15 +342,24 @@ class DynatraceTokenProviderIntegration(
|
|
301
342
|
else {}
|
302
343
|
)
|
303
344
|
for desired_token in secret.tokens:
|
304
|
-
|
305
|
-
if not
|
345
|
+
cur_token = current_tokens_by_name.get(desired_token.name)
|
346
|
+
if not cur_token or cur_token.id not in existing_dtp_tokens:
|
306
347
|
has_diff = True
|
307
348
|
if not dry_run:
|
308
|
-
|
349
|
+
cur_token = self.create_dynatrace_token(
|
309
350
|
dt_client, cluster_uuid, desired_token
|
310
351
|
)
|
311
|
-
|
312
|
-
|
352
|
+
existing_dtp_tokens[cur_token.id] = cur_token.name
|
353
|
+
if cur_token:
|
354
|
+
self.sync_token_in_dynatrace(
|
355
|
+
token_id=cur_token.id,
|
356
|
+
spec=desired_token,
|
357
|
+
cluster_uuid=cluster_uuid,
|
358
|
+
dt_client=dt_client,
|
359
|
+
dry_run=dry_run,
|
360
|
+
token_name_in_dt_api=existing_dtp_tokens[cur_token.id],
|
361
|
+
)
|
362
|
+
desired_tokens.append(cur_token)
|
313
363
|
desired.append(
|
314
364
|
K8sSecret(
|
315
365
|
secret_name=secret.name,
|
@@ -323,7 +373,7 @@ class DynatraceTokenProviderIntegration(
|
|
323
373
|
def create_dynatrace_token(
|
324
374
|
self, dt_client: DynatraceClient, cluster_uuid: str, token: DynatraceAPITokenV1
|
325
375
|
) -> DynatraceAPIToken:
|
326
|
-
token_name =
|
376
|
+
token_name = self.dynatrace_token_name(spec=token, cluster_uuid=cluster_uuid)
|
327
377
|
new_token = dt_client.create_api_token(
|
328
378
|
name=token_name,
|
329
379
|
scopes=token.scopes,
|
@@ -169,5 +169,5 @@ class PromoteQontractReconcileCommercial(MergeRequestBase):
|
|
169
169
|
gitlab_cli=gitlab_cli,
|
170
170
|
path="data/pipelines/tekton-provider-global-defaults.yaml",
|
171
171
|
search_text="$.taskTemplates[?(@.name == 'openshift-saas-deploy')].variables.qontract_reconcile_image_tag",
|
172
|
-
replace_text=self.
|
172
|
+
replace_text=self.version,
|
173
173
|
)
|
{qontract_reconcile-0.10.1rc1025.dist-info → qontract_reconcile-0.10.1rc1027.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|