qontract-reconcile 0.10.1rc1153__py3-none-any.whl → 0.10.1rc1155__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.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/RECORD +9 -9
- reconcile/external_resources/model.py +19 -21
- reconcile/quay_mirror.py +31 -13
- reconcile/test/test_quay_mirror.py +7 -14
- reconcile/utils/helpers.py +11 -0
- {qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.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.1rc1155
|
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.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/RECORD
RENAMED
@@ -90,7 +90,7 @@ reconcile/openshift_users.py,sha256=63mar-swgidz8f10TCPJcofbMN9FETq-HuVFpi8dUL4,
|
|
90
90
|
reconcile/openshift_vault_secrets.py,sha256=9rTqV6wzCQx2Oh712E_Xj8wMG7u8Oh-pY8DWjlv4mZw,1660
|
91
91
|
reconcile/quay_base.py,sha256=h5xNjb7EZm8L2JgpO42r6w0UA4im5dabZXJSIW69zKU,1987
|
92
92
|
reconcile/quay_membership.py,sha256=YDLY7ayDsatEpYCe_iMdf3pkvrbmN8mAwrDKUJUa4Lg,6260
|
93
|
-
reconcile/quay_mirror.py,sha256=
|
93
|
+
reconcile/quay_mirror.py,sha256=mFp4Z5Nwl-DcFbbsJBOB8f9ldohFT-V67o868d5ux1s,15369
|
94
94
|
reconcile/quay_mirror_org.py,sha256=utrJpJaKCs7U6WX6DODdfCeB0EmX-lUC8Y5fkmpgFSs,10764
|
95
95
|
reconcile/quay_permissions.py,sha256=9KOutS1w4RFQqkvMSy54VtsKNx56-phzP6yI_rEW-B8,4244
|
96
96
|
reconcile/quay_repos.py,sha256=cuEYG0HUe0ut5yvLdEwOF5-CmccpXQHRb_wDazvDrvQ,6895
|
@@ -199,7 +199,7 @@ reconcile/external_resources/integration_secrets_sync.py,sha256=dX09O3r6KURziUYY
|
|
199
199
|
reconcile/external_resources/manager.py,sha256=wcqTawNS4qoBHFVfyCfHtWXh4L3AlgcNYx_Ov_vEjNg,17914
|
200
200
|
reconcile/external_resources/meta.py,sha256=noaytFzmShpzLA_ebGh7wuP45mOfHIOnnoUxivjDa1I,672
|
201
201
|
reconcile/external_resources/metrics.py,sha256=nMbyonGZEJDD1lYzpQY2eR9TNwvxYC4ZCcpi6wrExcM,1037
|
202
|
-
reconcile/external_resources/model.py,sha256=
|
202
|
+
reconcile/external_resources/model.py,sha256=Ta8eOJ97RxCgBtWqsF4MWzQhgsOC2PoFfBKM5y3rM6U,8378
|
203
203
|
reconcile/external_resources/reconciler.py,sha256=3KFmkHsN7YAwJUSBpN1Xd_D2zM9Ea5_c2uMGWsfruZo,9707
|
204
204
|
reconcile/external_resources/secrets_sync.py,sha256=6n0oDPLjd9Ql0lf6zsr1AZw8A6EEe3yCzl20XodtgkE,16229
|
205
205
|
reconcile/external_resources/state.py,sha256=UupSa6tl4-73_J6Fhisn-qHal3v3uAUS5s5sk85LGDs,9343
|
@@ -549,7 +549,7 @@ reconcile/test/test_openshift_tekton_resources.py,sha256=O6-qPQwSiPHQKm1a1iqRU2V
|
|
549
549
|
reconcile/test/test_openshift_upgrade_watcher.py,sha256=0GDQ_YFHIX8DbkbDYSuLv9uZeeg4NwP1vlOqvSaZvN4,7183
|
550
550
|
reconcile/test/test_prometheus_rules_tester.py,sha256=cgVkPM3KcAw69bOkJ6iR2Lfog_WgblyoqVRtXv4ly7o,5685
|
551
551
|
reconcile/test/test_quay_membership.py,sha256=e29Giz5S9ckFgjpTO8PBo8qVPocIQmy4WqsRhgTFd9A,2643
|
552
|
-
reconcile/test/test_quay_mirror.py,sha256=
|
552
|
+
reconcile/test/test_quay_mirror.py,sha256=9TIu1-YQl0CG705m-FeEOs4OwKG3UVJzVhISw525Lco,6324
|
553
553
|
reconcile/test/test_quay_mirror_org.py,sha256=67XwB0WkqO6l9SeR9cSfjODyt-P587Kvqvam7hR8rLQ,3008
|
554
554
|
reconcile/test/test_quay_repos.py,sha256=TdkcRF_a8PLp01Kti9eZZN-vGup2yPBT4Iba3k08qe0,1810
|
555
555
|
reconcile/test/test_queries.py,sha256=SpH3RmNpBjEr_ne3VjAMCgKK8RE1z1zo7bypkT5uoO4,1946
|
@@ -683,7 +683,7 @@ reconcile/utils/gpg.py,sha256=EKG7_fdMv8BMlV5yUdPiqoTx-KrzmVSEAl2sLkaKwWI,1123
|
|
683
683
|
reconcile/utils/gql.py,sha256=C0thIm_k9MBldfqwHzyqtYZk9sIvMdm9IbbnXLGwjD8,14158
|
684
684
|
reconcile/utils/grouping.py,sha256=vr9SFHZ7bqmHYrvYcEZt-Er3-yQYfAAdq5sHLZVmXPY,456
|
685
685
|
reconcile/utils/helm.py,sha256=hr4J_9mBZwbc1FDNfFh4QKAj0h3eLxyTN2Y3UxIRp8U,3893
|
686
|
-
reconcile/utils/helpers.py,sha256=
|
686
|
+
reconcile/utils/helpers.py,sha256=womAD2bKPUAFOjHvNPAe_2Hsb-oVTxuQiYPGeR-Thp0,1772
|
687
687
|
reconcile/utils/imap_client.py,sha256=h8YDiCSCvroErhpH_-KGYI7Y2WU2Q2oSpuxDFbOkSbY,1989
|
688
688
|
reconcile/utils/instrumented_wrappers.py,sha256=eVwMoa6FCrYxLv3RML3WpZF9qKVfCTjMxphgVXG03OM,1073
|
689
689
|
reconcile/utils/jenkins_api.py,sha256=RaKuZmO7_lbI-hE6c_Pq2a6CQdmBVj7BcP2jR68cIbI,7081
|
@@ -880,8 +880,8 @@ tools/test/test_qontract_cli.py,sha256=iuzKbQ6ahinvjoQmQLBrG4shey0z-1rB6qCgS8T6d
|
|
880
880
|
tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
|
881
881
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
882
882
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
883
|
-
qontract_reconcile-0.10.
|
884
|
-
qontract_reconcile-0.10.
|
885
|
-
qontract_reconcile-0.10.
|
886
|
-
qontract_reconcile-0.10.
|
887
|
-
qontract_reconcile-0.10.
|
883
|
+
qontract_reconcile-0.10.1rc1155.dist-info/METADATA,sha256=R8XN1xU4JfYBpQJVZ8l8iWuRWuQ8DpVGaYE-pIpLRwk,2213
|
884
|
+
qontract_reconcile-0.10.1rc1155.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
885
|
+
qontract_reconcile-0.10.1rc1155.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
|
886
|
+
qontract_reconcile-0.10.1rc1155.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
887
|
+
qontract_reconcile-0.10.1rc1155.dist-info/RECORD,,
|
@@ -76,7 +76,25 @@ SUPPORTED_RESOURCE_TYPES = (
|
|
76
76
|
|
77
77
|
|
78
78
|
class ExternalResourcesInventory(MutableMapping):
|
79
|
-
|
79
|
+
def __init__(self, namespaces: Iterable[NamespaceV1]) -> None:
|
80
|
+
self._inventory: dict[ExternalResourceKey, ExternalResourceSpec] = {}
|
81
|
+
|
82
|
+
desired_providers = [
|
83
|
+
(p, ns)
|
84
|
+
for ns in namespaces
|
85
|
+
for p in ns.external_resources or []
|
86
|
+
if isinstance(p, SUPPORTED_RESOURCE_PROVIDERS) and p.resources
|
87
|
+
]
|
88
|
+
|
89
|
+
desired_specs = [
|
90
|
+
self._build_external_resource_spec(ns, p, r)
|
91
|
+
for (p, ns) in desired_providers
|
92
|
+
for r in p.resources
|
93
|
+
if isinstance(r, SUPPORTED_RESOURCE_TYPES) and r.managed_by_erv2
|
94
|
+
]
|
95
|
+
|
96
|
+
for spec in desired_specs:
|
97
|
+
self._inventory[ExternalResourceKey.from_spec(spec)] = spec
|
80
98
|
|
81
99
|
def _build_external_resource_spec(
|
82
100
|
self,
|
@@ -100,24 +118,6 @@ class ExternalResourcesInventory(MutableMapping):
|
|
100
118
|
spec.metadata[MODULE_OVERRIDES] = resource.module_overrides
|
101
119
|
return spec
|
102
120
|
|
103
|
-
def __init__(self, namespaces: Iterable[NamespaceV1]) -> None:
|
104
|
-
desired_providers = [
|
105
|
-
(p, ns)
|
106
|
-
for ns in namespaces
|
107
|
-
for p in ns.external_resources or []
|
108
|
-
if isinstance(p, SUPPORTED_RESOURCE_PROVIDERS) and p.resources
|
109
|
-
]
|
110
|
-
|
111
|
-
desired_specs = [
|
112
|
-
self._build_external_resource_spec(ns, p, r)
|
113
|
-
for (p, ns) in desired_providers
|
114
|
-
for r in p.resources
|
115
|
-
if isinstance(r, SUPPORTED_RESOURCE_TYPES) and r.managed_by_erv2
|
116
|
-
]
|
117
|
-
|
118
|
-
for spec in desired_specs:
|
119
|
-
self._inventory[ExternalResourceKey.from_spec(spec)] = spec
|
120
|
-
|
121
121
|
def __getitem__(self, key: ExternalResourceKey) -> ExternalResourceSpec | None:
|
122
122
|
return self._inventory[key]
|
123
123
|
|
@@ -161,8 +161,6 @@ class ExternalResourceModuleKey(BaseModel, frozen=True):
|
|
161
161
|
|
162
162
|
|
163
163
|
class ModuleInventory:
|
164
|
-
inventory: dict[ExternalResourceModuleKey, ExternalResourcesModuleV1]
|
165
|
-
|
166
164
|
def __init__(
|
167
165
|
self, inventory: dict[ExternalResourceModuleKey, ExternalResourcesModuleV1]
|
168
166
|
):
|
reconcile/quay_mirror.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
-
import re
|
4
3
|
import sys
|
5
4
|
import tempfile
|
6
5
|
import time
|
@@ -29,6 +28,7 @@ from reconcile.utils import (
|
|
29
28
|
metrics,
|
30
29
|
sharding,
|
31
30
|
)
|
31
|
+
from reconcile.utils.helpers import match_patterns
|
32
32
|
from reconcile.utils.instrumented_wrappers import InstrumentedImage as Image
|
33
33
|
from reconcile.utils.instrumented_wrappers import InstrumentedSkopeo as Skopeo
|
34
34
|
from reconcile.utils.secret_reader import SecretReader
|
@@ -205,20 +205,38 @@ class QuayMirror:
|
|
205
205
|
return summary
|
206
206
|
|
207
207
|
@staticmethod
|
208
|
-
def sync_tag(
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
208
|
+
def sync_tag(
|
209
|
+
tags: Iterable[str] | None,
|
210
|
+
tags_exclude: Iterable[str] | None,
|
211
|
+
candidate: str,
|
212
|
+
) -> bool:
|
213
|
+
"""
|
214
|
+
Determine if the candidate tag should sync, tags_exclude check take precedence.
|
215
|
+
:param tags: regex patterns to filter, match means to sync, None means no filter
|
216
|
+
:param tags_exclude: regex patterns to filter, match means not to sync, None means no filter
|
217
|
+
:param candidate: tag to check
|
218
|
+
:return: bool, True means to sync, False means not to sync
|
219
|
+
"""
|
220
|
+
if not tags and not tags_exclude:
|
217
221
|
return True
|
218
222
|
|
219
|
-
|
220
|
-
|
221
|
-
|
223
|
+
if not tags:
|
224
|
+
# only tags_exclude provided
|
225
|
+
assert tags_exclude # mypy can't infer not None
|
226
|
+
return not match_patterns(tags_exclude, candidate)
|
227
|
+
|
228
|
+
if not tags_exclude:
|
229
|
+
# only tags provided
|
230
|
+
return match_patterns(tags, candidate)
|
231
|
+
|
232
|
+
# both tags and tags_exclude provided
|
233
|
+
return not match_patterns(
|
234
|
+
tags_exclude,
|
235
|
+
candidate,
|
236
|
+
) and match_patterns(
|
237
|
+
tags,
|
238
|
+
candidate,
|
239
|
+
)
|
222
240
|
|
223
241
|
def process_sync_tasks(self):
|
224
242
|
if self.is_compare_tags:
|
@@ -96,22 +96,15 @@ class TestIsCompareTags:
|
|
96
96
|
(["^sha256-.+sig$", "^main-.+"], None, "main-755781cc", True),
|
97
97
|
(["^sha256-.+sig$", "^main-.+"], None, "sha256-8b5.sig", True),
|
98
98
|
(["^sha256-.+sig$", "^main-.+"], None, "1.2.3", False),
|
99
|
-
# Tags exclude tests.
|
99
|
+
# # Tags exclude tests.
|
100
100
|
(None, ["^sha256-.+sig$", "^main-.+"], "main-755781cc", False),
|
101
101
|
(None, ["^sha256-.+sig$", "^main-.+"], "sha256-8b5.sig", False),
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
),
|
109
|
-
(
|
110
|
-
["^sha256-.+sig$", "^main-.+"],
|
111
|
-
["^sha256-.+sig$", "^main-.+"],
|
112
|
-
"sha256-8b5.sig",
|
113
|
-
True,
|
114
|
-
),
|
102
|
+
(None, ["^sha256-.+sig$", "^main-.+"], "1.2.3", True),
|
103
|
+
# When both includes and excludes are explicitly given, exclude take precedence.
|
104
|
+
(["^sha256-.+sig$", "^main-.+"], ["main-755781cc"], "main-755781cc", False),
|
105
|
+
(["^sha256-.+sig$", "^main-.+"], ["main-755781cc"], "sha256-8b5.sig", True),
|
106
|
+
# both include and exclude are not set
|
107
|
+
(None, None, "main-755781cc", True),
|
115
108
|
],
|
116
109
|
)
|
117
110
|
def test_sync_tag(tags, tags_exclude, candidate, result):
|
reconcile/utils/helpers.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import random
|
3
|
+
import re
|
3
4
|
import string
|
4
5
|
from collections import Counter
|
5
6
|
from collections.abc import (
|
@@ -52,3 +53,13 @@ def generate_random_password(string_length: int = 20) -> str:
|
|
52
53
|
"""Generate a random string of letters and digits"""
|
53
54
|
letters_and_digits = string.ascii_letters + string.digits
|
54
55
|
return "".join(random.choices(letters_and_digits, k=string_length))
|
56
|
+
|
57
|
+
|
58
|
+
def match_patterns(patterns: Iterable[str], s: str) -> bool:
|
59
|
+
"""
|
60
|
+
Check if any pattern matches the string.
|
61
|
+
:param patterns: patterns to match
|
62
|
+
:param s: string to check
|
63
|
+
:return: True if any pattern matches, False otherwise
|
64
|
+
"""
|
65
|
+
return any(re.match(p, s) for p in patterns)
|
{qontract_reconcile-0.10.1rc1153.dist-info → qontract_reconcile-0.10.1rc1155.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|