qontract-reconcile 0.10.2.dev84__py3-none-any.whl → 0.10.2.dev86__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.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/RECORD +9 -9
- reconcile/fleet_labeler/dependencies.py +3 -0
- reconcile/fleet_labeler/integration.py +27 -4
- reconcile/fleet_labeler/vcs.py +16 -3
- tools/cli_commands/container_images_report.py +10 -4
- tools/qontract_cli.py +2 -0
- {qontract_reconcile-0.10.2.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev84.dist-info → qontract_reconcile-0.10.2.dev86.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.dev86
|
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.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/RECORD
RENAMED
@@ -207,14 +207,14 @@ 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=ZOpmtwgxEPBWU2yHRc6rhPwlvqhwYSsNMJQ_jVq1dLI,2993
|
211
|
+
reconcile/fleet_labeler/integration.py,sha256=jm2wvkxsxqGLsX_vE874crgce_YsDWyggL3Q3olMNJM,8753
|
212
212
|
reconcile/fleet_labeler/merge_request.py,sha256=VA_XSIob4LWYb02dRUr9coXjIa8_0prObI1v5Gqi_mY,1513
|
213
213
|
reconcile/fleet_labeler/meta.py,sha256=DF7O4T9wvQ7-xTWXvuNw1OG_F0SBmRrjFBtVy9wWh9U,146
|
214
214
|
reconcile/fleet_labeler/metrics.py,sha256=wx9BmXLsN67m-aSsf81iB7Ehj5SzUsS2WB75isUReZg,662
|
215
215
|
reconcile/fleet_labeler/ocm.py,sha256=GGsz-bq1g8BJVVMCfI2kSwZCyngbQoZ3i3k8fO608KA,2506
|
216
216
|
reconcile/fleet_labeler/validate.py,sha256=gzc2tt7h9F60h7dcyJfEmsnjnfuux5Jtc_WzrIqr-5k,2541
|
217
|
-
reconcile/fleet_labeler/vcs.py,sha256=
|
217
|
+
reconcile/fleet_labeler/vcs.py,sha256=6UHUQ08AGAHXF7629I6X-T_E1pvx96LxjS66EeOzve4,1108
|
218
218
|
reconcile/glitchtip/README.md,sha256=rfXT6jNP9khJW65jL7I2PgoxvxgcGGuJF8NpbzufEQ4,4335
|
219
219
|
reconcile/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
220
220
|
reconcile/glitchtip/integration.py,sha256=vCyg8W4ZUGxjU8tB1Gkre_auSpzo83n05mmO8_-7al0,8263
|
@@ -759,11 +759,11 @@ tools/app_sre_tekton_access_reporter.py,sha256=o9prLUgQpwO3msRWc2as1xT1y9OB3znkp
|
|
759
759
|
tools/app_sre_tekton_access_revalidation.py,sha256=66nHEaY-bIqxIhpcmwN8AvQZu6ZXenfkg4Fut0pVZRM,2726
|
760
760
|
tools/glitchtip_access_reporter.py,sha256=o01A6b88t3Wie6tj_tJWWVo2J01LxQ_a9giGm4UzEaU,2901
|
761
761
|
tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
|
762
|
-
tools/qontract_cli.py,sha256=
|
762
|
+
tools/qontract_cli.py,sha256=_KHwJIC0Keyy2cmhUVruOYtmp1CrTZDzEZkEe8lf81I,152941
|
763
763
|
tools/sd_app_sre_alert_report.py,sha256=jQpJdXVID68bSNtJNOGDh0-ei1CfEUS4Itr4MAaBNFA,5062
|
764
764
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
765
765
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
766
|
-
tools/cli_commands/container_images_report.py,sha256=
|
766
|
+
tools/cli_commands/container_images_report.py,sha256=SXh6sZ1dXXzd-2R5eeBufCtW3J4-Y55--0MZLdo4lr8,5409
|
767
767
|
tools/cli_commands/erv2.py,sha256=VxUlNXllo947UwmtvS-42IeI9x_t_X3MHrrSI3K_GRo,23274
|
768
768
|
tools/cli_commands/gpg_encrypt.py,sha256=JWwds_Qg7KhSJMIGUh8TfI5-Jf17iUtmaEi4kWJxfVE,4907
|
769
769
|
tools/cli_commands/systems_and_tools.py,sha256=EMHOF1AtUDaoSk0bbjl6oUKYAz4rTZjIBaF-6E6GspM,16816
|
@@ -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.dev86.dist-info/METADATA,sha256=cajktJ7yRKHgFkrRRzNfruYA4M_gcRFOEF9RO_MH01w,24565
|
790
|
+
qontract_reconcile-0.10.2.dev86.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
791
|
+
qontract_reconcile-0.10.2.dev86.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
792
|
+
qontract_reconcile-0.10.2.dev86.dist-info/RECORD,,
|
@@ -27,10 +27,12 @@ class Dependencies:
|
|
27
27
|
label_specs_by_name: Mapping[str, FleetLabelsSpecV1],
|
28
28
|
ocm_clients_by_label_spec_name: Mapping[str, OCMClient],
|
29
29
|
vcs: VCS,
|
30
|
+
dry_run: bool,
|
30
31
|
):
|
31
32
|
self.label_specs_by_name = label_specs_by_name
|
32
33
|
self.ocm_clients_by_label_spec_name = ocm_clients_by_label_spec_name
|
33
34
|
self.vcs = vcs
|
35
|
+
self.dry_run = dry_run
|
34
36
|
|
35
37
|
@classmethod
|
36
38
|
def create(
|
@@ -42,6 +44,7 @@ class Dependencies:
|
|
42
44
|
label_specs_by_name=_label_specs(),
|
43
45
|
ocm_clients_by_label_spec_name=_ocm_clients(secret_reader=secret_reader),
|
44
46
|
vcs=_vcs(secret_reader=secret_reader, dry_run=dry_run),
|
47
|
+
dry_run=dry_run,
|
45
48
|
)
|
46
49
|
|
47
50
|
|
@@ -16,7 +16,7 @@ from reconcile.fleet_labeler.meta import (
|
|
16
16
|
from reconcile.fleet_labeler.metrics import FleetLabelerDuplicateClusterMatchesGauge
|
17
17
|
from reconcile.fleet_labeler.ocm import OCMClient
|
18
18
|
from reconcile.fleet_labeler.validate import validate_label_specs
|
19
|
-
from reconcile.fleet_labeler.vcs import VCS
|
19
|
+
from reconcile.fleet_labeler.vcs import VCS, Gitlab404Error
|
20
20
|
from reconcile.gql_definitions.fleet_labeler.fleet_labels import (
|
21
21
|
FleetLabelDefaultV1,
|
22
22
|
FleetLabelsSpecV1,
|
@@ -60,7 +60,10 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
60
60
|
validate_label_specs(specs=dependencies.label_specs_by_name)
|
61
61
|
for spec_name, ocm in dependencies.ocm_clients_by_label_spec_name.items():
|
62
62
|
self._sync_cluster_inventory(
|
63
|
-
ocm,
|
63
|
+
ocm=ocm,
|
64
|
+
spec=dependencies.label_specs_by_name[spec_name],
|
65
|
+
vcs=dependencies.vcs,
|
66
|
+
dry_run=dependencies.dry_run,
|
64
67
|
)
|
65
68
|
|
66
69
|
def _render_default_labels(
|
@@ -112,7 +115,11 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
112
115
|
return stream.getvalue()
|
113
116
|
|
114
117
|
def _sync_cluster_inventory(
|
115
|
-
self,
|
118
|
+
self,
|
119
|
+
ocm: OCMClient,
|
120
|
+
spec: FleetLabelsSpecV1,
|
121
|
+
vcs: VCS,
|
122
|
+
dry_run: bool,
|
116
123
|
) -> None:
|
117
124
|
class ClusterData(BaseModel):
|
118
125
|
"""
|
@@ -189,7 +196,23 @@ class FleetLabelerIntegration(QontractReconcileIntegration[NoParams]):
|
|
189
196
|
f"[{spec.name}] Deleting cluster {cluster_id=} from inventory."
|
190
197
|
)
|
191
198
|
|
192
|
-
|
199
|
+
# When adding a new label spec file, then we dont have any existing content in main yet.
|
200
|
+
# This is a chicken-egg problem, but if we are in dry-run we can skip these steps on 404s.
|
201
|
+
# Note, that the diff is already printed above, so we can make a good decision if desired
|
202
|
+
# content fits.
|
203
|
+
# If the content exists in main, then it doesnt harm to also run the rendering procedure.
|
204
|
+
try:
|
205
|
+
current_content = vcs.get_file_content_from_main(path=spec.path)
|
206
|
+
except Gitlab404Error:
|
207
|
+
if dry_run:
|
208
|
+
logging.info(
|
209
|
+
f"The file data{spec.path} does not exist in main branch yet. This is likely because it is being created with this MR. We are skipping rendering steps."
|
210
|
+
)
|
211
|
+
return
|
212
|
+
# 404 must never happen on non-dry-run, as the file must have already passed
|
213
|
+
# MR check and must have been merged to main
|
214
|
+
raise
|
215
|
+
|
193
216
|
# Lets make sure we are deterministic when adding new clusters
|
194
217
|
# The overhead is neglectable and it makes testing easier
|
195
218
|
sorted_clusters_to_add = sorted(clusters_to_add, key=lambda c: c.name)
|
reconcile/fleet_labeler/vcs.py
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
from gitlab.exceptions import GitlabGetError
|
2
|
+
|
1
3
|
from reconcile.fleet_labeler.merge_request import FleetLabelerUpdates
|
2
4
|
from reconcile.utils.vcs import VCS as VCSBase
|
3
5
|
|
4
6
|
|
7
|
+
class Gitlab404Error(Exception):
|
8
|
+
pass
|
9
|
+
|
10
|
+
|
5
11
|
class VCS:
|
6
12
|
"""
|
7
13
|
Thin abstractions of reconcile.utils.vcs module to reduce coupling and simplify tests.
|
@@ -11,9 +17,16 @@ class VCS:
|
|
11
17
|
self._vcs = vcs
|
12
18
|
|
13
19
|
def get_file_content_from_main(self, path: str) -> str:
|
14
|
-
|
15
|
-
|
16
|
-
|
20
|
+
try:
|
21
|
+
return self._vcs.get_file_content_from_app_interface_ref(
|
22
|
+
file_path=path, ref="main"
|
23
|
+
)
|
24
|
+
except GitlabGetError as e:
|
25
|
+
if e.response_code != 404:
|
26
|
+
raise
|
27
|
+
raise Gitlab404Error(
|
28
|
+
f"File at ${path} does not exist yet in main branch. Maybe it is just being created with this MR?"
|
29
|
+
) from e
|
17
30
|
|
18
31
|
def open_merge_request(self, path: str, content: str) -> None:
|
19
32
|
mr = FleetLabelerUpdates(path=path, content=content)
|
@@ -6,11 +6,11 @@ from typing import Any
|
|
6
6
|
from pydantic import BaseModel
|
7
7
|
from sretoolbox.utils import threaded
|
8
8
|
|
9
|
-
from reconcile.gql_definitions.common.
|
9
|
+
from reconcile.gql_definitions.common.namespaces import NamespaceV1
|
10
10
|
from reconcile.typed_queries.app_interface_vault_settings import (
|
11
11
|
get_app_interface_vault_settings,
|
12
12
|
)
|
13
|
-
from reconcile.typed_queries.
|
13
|
+
from reconcile.typed_queries.namespaces import get_namespaces
|
14
14
|
from reconcile.utils.oc_filters import filter_namespaces_by_cluster_and_namespace
|
15
15
|
from reconcile.utils.oc_map import OCMap, init_oc_map_from_namespaces
|
16
16
|
from reconcile.utils.secret_reader import create_secret_reader
|
@@ -22,6 +22,7 @@ IMAGE_NAME_REGEX = re.compile(
|
|
22
22
|
|
23
23
|
class NamespaceImages(BaseModel):
|
24
24
|
namespace_name: str
|
25
|
+
app_name: str
|
25
26
|
image_names: list[str] | None = None
|
26
27
|
error_message: str | None = None
|
27
28
|
|
@@ -40,7 +41,7 @@ def get_all_pods_images(
|
|
40
41
|
* namespaces: a comma separated list of namespaces where the instance is used
|
41
42
|
* count: number of uses of the image
|
42
43
|
"""
|
43
|
-
all_namespaces =
|
44
|
+
all_namespaces = get_namespaces()
|
44
45
|
namespaces = filter_namespaces_by_cluster_and_namespace(
|
45
46
|
namespaces=all_namespaces,
|
46
47
|
cluster_names=cluster_name,
|
@@ -89,6 +90,7 @@ def fetch_pods_images_from_namespaces(
|
|
89
90
|
|
90
91
|
for name in ni.image_names or []:
|
91
92
|
result[name]["namespaces"].add(ni.namespace_name)
|
93
|
+
result[name]["apps"].add(ni.app_name)
|
92
94
|
result[name]["count"] += 1
|
93
95
|
|
94
96
|
exclude_pattern_compiled: re.Pattern | None = None
|
@@ -109,6 +111,7 @@ def fetch_pods_images_from_namespaces(
|
|
109
111
|
result_filtered_flattened.append({
|
110
112
|
"name": name,
|
111
113
|
"namespaces": ",".join(sorted(value["namespaces"])),
|
114
|
+
"apps": ",".join(sorted(value["apps"])),
|
112
115
|
"count": value["count"],
|
113
116
|
})
|
114
117
|
|
@@ -119,6 +122,7 @@ def fetch_pods_images_from_namespaces(
|
|
119
122
|
result_filtered_flattened.append({
|
120
123
|
"name": "error",
|
121
124
|
"namespaces": message,
|
125
|
+
"apps": "",
|
122
126
|
"count": count,
|
123
127
|
})
|
124
128
|
|
@@ -126,7 +130,7 @@ def fetch_pods_images_from_namespaces(
|
|
126
130
|
|
127
131
|
|
128
132
|
def _get_all_images_default() -> dict[str, Any]:
|
129
|
-
return {"namespaces": set(), "count": 0}
|
133
|
+
return {"namespaces": set(), "apps": set(), "count": 0}
|
130
134
|
|
131
135
|
|
132
136
|
def _get_namespace_images(ns: NamespaceV1, oc_map: OCMap) -> NamespaceImages:
|
@@ -145,10 +149,12 @@ def _get_namespace_images(ns: NamespaceV1, oc_map: OCMap) -> NamespaceImages:
|
|
145
149
|
except Exception as exc:
|
146
150
|
return NamespaceImages(
|
147
151
|
namespace_name=ns.name,
|
152
|
+
app_name=ns.app.name,
|
148
153
|
error_message=str(exc),
|
149
154
|
)
|
150
155
|
|
151
156
|
return NamespaceImages(
|
152
157
|
namespace_name=ns.name,
|
158
|
+
app_name=ns.app.name,
|
153
159
|
image_names=image_names,
|
154
160
|
)
|
tools/qontract_cli.py
CHANGED
@@ -4528,6 +4528,7 @@ def container_images(
|
|
4528
4528
|
"fields": [
|
4529
4529
|
{"key": "name", "sortable": True},
|
4530
4530
|
{"key": "namespaces", "sortable": True},
|
4531
|
+
{"key": "apps", "sortable": True},
|
4531
4532
|
{"key": "count", "sortable": True},
|
4532
4533
|
],
|
4533
4534
|
"items": results,
|
@@ -4548,6 +4549,7 @@ You can view the source of this Markdown to extract the JSON data.
|
|
4548
4549
|
columns = [
|
4549
4550
|
"name",
|
4550
4551
|
"namespaces",
|
4552
|
+
"apps",
|
4551
4553
|
"count",
|
4552
4554
|
]
|
4553
4555
|
ctx.obj["options"]["sort"] = False
|
{qontract_reconcile-0.10.2.dev84.dist-info → qontract_reconcile-0.10.2.dev86.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|