qontract-reconcile 0.10.2.dev15__py3-none-any.whl → 0.10.2.dev17__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.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/RECORD +8 -8
- reconcile/cli.py +3 -3
- reconcile/endpoints_discovery/integration.py +137 -98
- reconcile/gql_definitions/endpoints_discovery/{namespaces.py → apps.py} +22 -22
- reconcile/service_dependencies.py +1 -1
- {qontract_reconcile-0.10.2.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev15.dist-info → qontract_reconcile-0.10.2.dev17.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.dev17
|
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.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/RECORD
RENAMED
@@ -10,7 +10,7 @@ reconcile/aws_iam_password_reset.py,sha256=q96mwr2KeEQ5bpNniGlgIMZTxiuLSodcYfX-t
|
|
10
10
|
reconcile/aws_support_cases_sos.py,sha256=hl_9L53yQYRQxKs3IWrd69Cc60XK067g_bJRM9B0udo,2975
|
11
11
|
reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
|
12
12
|
reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
|
13
|
-
reconcile/cli.py,sha256=
|
13
|
+
reconcile/cli.py,sha256=Xyk9VZnf3nQULRE6j3VvNqQXXq8wa0c-HyIfSRgkrlw,107476
|
14
14
|
reconcile/closedbox_endpoint_monitoring_base.py,sha256=MvGKBqH9PdHWdMjhLuptze-dk0Tifhp3-0SZdI-7Fmo,4862
|
15
15
|
reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
|
16
16
|
reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
|
@@ -102,7 +102,7 @@ reconcile/resource_template_tester.py,sha256=DsKvBuNLPxm4Fa-e1YHHySnhThm5i_j-nF3
|
|
102
102
|
reconcile/run_integration.py,sha256=8kc-lMKF9n2bvyrItJ-3nOgQMqK7lh1UAubXQrxQDPY,9711
|
103
103
|
reconcile/saas_file_validator.py,sha256=tyvFYU6lnkfDYIkAIr5pWqSvO5Yc6TagZ-quJYD2dtI,2547
|
104
104
|
reconcile/sendgrid_teammates.py,sha256=oO8QbLb4s1o8A6CGiCagN9CmS05BSS_WLztuY0Ym9D8,4773
|
105
|
-
reconcile/service_dependencies.py,sha256=
|
105
|
+
reconcile/service_dependencies.py,sha256=SOSJvSo6GchQpLsTbkGFnf1yHtlSFu2VnirAfi6-XGA,4418
|
106
106
|
reconcile/signalfx_endpoint_monitoring.py,sha256=Nqgsg1cflSd2nNnm89y_e8c--7xLUqTrKOHkDs-qADE,2868
|
107
107
|
reconcile/slack_base.py,sha256=8FqwMJ5SkoRyDJ9iPfZogWkC9QRoTouMCnGUevV_GME,3447
|
108
108
|
reconcile/slack_usergroups.py,sha256=vMifpbnrQDLeckGtUmpIg7sVvlhpaJz8HZH_loA7fpY,30221
|
@@ -191,7 +191,7 @@ reconcile/dynatrace_token_provider/model.py,sha256=gkpqo5rRRueBXnIMjp4EEHqBUBuU6
|
|
191
191
|
reconcile/dynatrace_token_provider/ocm.py,sha256=MwYCZIxW4f-1jzFTxxN__sity6S8O7bbKUdyTFEVO7U,4325
|
192
192
|
reconcile/dynatrace_token_provider/validate.py,sha256=40_9QmHoB3-KBc0k_0D4QO00PpNNPS-gU9Z6cIcWga8,1920
|
193
193
|
reconcile/endpoints_discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
194
|
-
reconcile/endpoints_discovery/integration.py,sha256=
|
194
|
+
reconcile/endpoints_discovery/integration.py,sha256=63jAVDOcO1iF8zmH2nCmPxHiUGxs83bFTfKfD9vUlEY,14273
|
195
195
|
reconcile/endpoints_discovery/merge_request.py,sha256=_yLb4tnvoZMCko8rta2C_CvOInJa9pa3HzSmHNtjgGU,2978
|
196
196
|
reconcile/endpoints_discovery/merge_request_manager.py,sha256=wUMsumxv8RnWaRattax4HfoRlhtVzmgro3GiJJ1C4Vc,6392
|
197
197
|
reconcile/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -293,7 +293,7 @@ reconcile/gql_definitions/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HB
|
|
293
293
|
reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py,sha256=5gTuAnR2rnx2k6Rn7FMEAzw6GCZ6F5HZbqkmJ9-3NI4,2244
|
294
294
|
reconcile/gql_definitions/dynatrace_token_provider/token_specs.py,sha256=XGsMuB8gowRpqJjkD_KRomx-1OswzyWbF4qjVdhionk,2555
|
295
295
|
reconcile/gql_definitions/endpoints_discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
296
|
-
reconcile/gql_definitions/endpoints_discovery/
|
296
|
+
reconcile/gql_definitions/endpoints_discovery/apps.py,sha256=erQqC1twpa7gwV6HJh8C5mYQehlfbEzsSzFbIj8gtyQ,3036
|
297
297
|
reconcile/gql_definitions/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
298
298
|
reconcile/gql_definitions/external_resources/aws_accounts.py,sha256=XR69j9dpTQ0gv8y-AZN7AJ0dPvO-wbHscyCDgrax6Bk,2046
|
299
299
|
reconcile/gql_definitions/external_resources/external_resources_modules.py,sha256=cbbvGq1Te9DP8XiFg3bp4Y0q6LxpGYov8ugcROPyPLI,2647
|
@@ -766,7 +766,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
766
766
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
767
767
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
768
768
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
769
|
-
qontract_reconcile-0.10.2.
|
770
|
-
qontract_reconcile-0.10.2.
|
771
|
-
qontract_reconcile-0.10.2.
|
772
|
-
qontract_reconcile-0.10.2.
|
769
|
+
qontract_reconcile-0.10.2.dev17.dist-info/METADATA,sha256=9UMiSwjSAOu05rjw0IPPzRAKiWJJyJEPavuXkc1x5E8,24665
|
770
|
+
qontract_reconcile-0.10.2.dev17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
771
|
+
qontract_reconcile-0.10.2.dev17.dist-info/entry_points.txt,sha256=JniHZPadNOILPyfSl0LF2YSp3Db7K2_W2CN7i9f3Gos,540
|
772
|
+
qontract_reconcile-0.10.2.dev17.dist-info/RECORD,,
|
reconcile/cli.py
CHANGED
@@ -1801,10 +1801,10 @@ def openshift_prometheus_rules(
|
|
1801
1801
|
@internal()
|
1802
1802
|
@use_jump_host()
|
1803
1803
|
@cluster_name
|
1804
|
-
@namespace_name
|
1805
1804
|
@enable_extended_early_exit
|
1806
1805
|
@extended_early_exit_cache_ttl_seconds
|
1807
1806
|
@log_cached_log_output
|
1807
|
+
@click.option("--app-name", default=None, help="Consider this app only.")
|
1808
1808
|
@click.option(
|
1809
1809
|
"--endpoint-tmpl-resource",
|
1810
1810
|
help="Resource name of the endpoint template in the app-interface.",
|
@@ -1817,10 +1817,10 @@ def endpoints_discovery(
|
|
1817
1817
|
internal,
|
1818
1818
|
use_jump_host,
|
1819
1819
|
cluster_name,
|
1820
|
-
namespace_name,
|
1821
1820
|
enable_extended_early_exit,
|
1822
1821
|
extended_early_exit_cache_ttl_seconds,
|
1823
1822
|
log_cached_log_output,
|
1823
|
+
app_name,
|
1824
1824
|
endpoint_tmpl_resource,
|
1825
1825
|
):
|
1826
1826
|
from reconcile.endpoints_discovery.integration import (
|
@@ -1833,7 +1833,7 @@ def endpoints_discovery(
|
|
1833
1833
|
internal=internal,
|
1834
1834
|
use_jump_host=use_jump_host,
|
1835
1835
|
cluster_name=cluster_name,
|
1836
|
-
|
1836
|
+
app_name=app_name,
|
1837
1837
|
enable_extended_early_exit=enable_extended_early_exit,
|
1838
1838
|
extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
|
1839
1839
|
log_cached_log_output=log_cached_log_output,
|
@@ -15,12 +15,13 @@ from reconcile.endpoints_discovery.merge_request_manager import (
|
|
15
15
|
EndpointsToDelete,
|
16
16
|
MergeRequestManager,
|
17
17
|
)
|
18
|
-
from reconcile.gql_definitions.endpoints_discovery.
|
18
|
+
from reconcile.gql_definitions.endpoints_discovery.apps import (
|
19
19
|
AppEndPointsV1,
|
20
|
+
AppV1,
|
20
21
|
NamespaceV1,
|
21
22
|
)
|
22
|
-
from reconcile.gql_definitions.endpoints_discovery.
|
23
|
-
query as
|
23
|
+
from reconcile.gql_definitions.endpoints_discovery.apps import (
|
24
|
+
query as apps_query,
|
24
25
|
)
|
25
26
|
from reconcile.typed_queries.app_interface_repo_url import get_app_interface_repo_url
|
26
27
|
from reconcile.typed_queries.github_orgs import get_github_orgs
|
@@ -44,7 +45,7 @@ from reconcile.utils.unleash import get_feature_toggle_state
|
|
44
45
|
from reconcile.utils.vcs import VCS
|
45
46
|
|
46
47
|
QONTRACT_INTEGRATION = "endpoints-discovery"
|
47
|
-
QONTRACT_INTEGRATION_VERSION = make_semver(1,
|
48
|
+
QONTRACT_INTEGRATION_VERSION = make_semver(1, 1, 0)
|
48
49
|
|
49
50
|
|
50
51
|
class EndpointsDiscoveryIntegrationParams(PydanticRunParams):
|
@@ -52,7 +53,7 @@ class EndpointsDiscoveryIntegrationParams(PydanticRunParams):
|
|
52
53
|
internal: bool | None = None
|
53
54
|
use_jump_host: bool = True
|
54
55
|
cluster_name: set[str] | None = None
|
55
|
-
|
56
|
+
app_name: str | None = None
|
56
57
|
endpoint_tmpl_resource: str = "/endpoints-discovery/endpoint-template.yml"
|
57
58
|
# extended early exit parameters
|
58
59
|
enable_extended_early_exit: bool = False
|
@@ -71,14 +72,25 @@ class Route(BaseModel):
|
|
71
72
|
|
72
73
|
|
73
74
|
def endpoint_prefix(namespace: NamespaceV1) -> str:
|
75
|
+
"""Return the prefix for the endpoint name."""
|
74
76
|
return f"{QONTRACT_INTEGRATION}/{namespace.cluster.name}/{namespace.name}/"
|
75
77
|
|
76
78
|
|
79
|
+
def parse_endpoint_name(endpoint_name: str) -> tuple[str, str, list[str]]:
|
80
|
+
"""Parse the endpoint name into its components."""
|
81
|
+
integration_name, cluster, namespace, route_names = endpoint_name.split("/")
|
82
|
+
if integration_name != QONTRACT_INTEGRATION:
|
83
|
+
raise ValueError("Invalid integration name")
|
84
|
+
return cluster, namespace, route_names.split("|")
|
85
|
+
|
86
|
+
|
77
87
|
def compile_endpoint_name(endpoint_prefix: str, route: Route) -> str:
|
88
|
+
"""Compile the endpoint name from the prefix and route."""
|
78
89
|
return f"{endpoint_prefix}{route.name}"
|
79
90
|
|
80
91
|
|
81
92
|
def render_template(template: str, endpoint_name: str, route: Route) -> dict:
|
93
|
+
"""Render the endpoint yaml template used in the merge request."""
|
82
94
|
yml = create_ruamel_instance()
|
83
95
|
return yml.load(
|
84
96
|
jinja2.Template(
|
@@ -95,7 +107,7 @@ class RunnerParams(TypedDict):
|
|
95
107
|
oc_map: OCMap
|
96
108
|
merge_request_manager: MergeRequestManager
|
97
109
|
endpoint_template: str
|
98
|
-
|
110
|
+
apps: Iterable[AppV1]
|
99
111
|
|
100
112
|
|
101
113
|
class EndpointsDiscoveryIntegration(
|
@@ -113,20 +125,16 @@ class EndpointsDiscoveryIntegration(
|
|
113
125
|
An application can have endpoints in multiple clusters and this may cause merge conflicts."""
|
114
126
|
return None
|
115
127
|
|
116
|
-
def
|
128
|
+
def get_apps(
|
117
129
|
self,
|
118
130
|
query_func: Callable,
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
"""Return namespaces to consider for the integration."""
|
131
|
+
app_name: str | None = None,
|
132
|
+
) -> list[AppV1]:
|
133
|
+
"""Return all applications to consider for the integration."""
|
123
134
|
return [
|
124
|
-
|
125
|
-
for
|
126
|
-
if
|
127
|
-
and (not cluster_names or ns.cluster.name in cluster_names)
|
128
|
-
and (not namespace_name or ns.name == namespace_name)
|
129
|
-
and not ns.delete
|
135
|
+
app
|
136
|
+
for app in apps_query(query_func).apps or []
|
137
|
+
if (not app_name or app.name == app_name)
|
130
138
|
]
|
131
139
|
|
132
140
|
def get_routes(self, oc_map: OCMap, namespace: NamespaceV1) -> list[Route]:
|
@@ -155,9 +163,8 @@ class EndpointsDiscoveryIntegration(
|
|
155
163
|
for (host, tls), names in routes.items()
|
156
164
|
]
|
157
165
|
|
158
|
-
def
|
166
|
+
def get_namespace_endpoint_changes(
|
159
167
|
self,
|
160
|
-
app: str,
|
161
168
|
endpoint_prefix: str,
|
162
169
|
endpoint_template: str,
|
163
170
|
endpoints: Iterable[AppEndPointsV1],
|
@@ -186,108 +193,140 @@ class EndpointsDiscoveryIntegration(
|
|
186
193
|
equal=lambda endpoint, route: endpoint.url == route.url,
|
187
194
|
)
|
188
195
|
|
189
|
-
endpoints_to_add = [
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
name=compile_endpoint_name(endpoint_prefix, add),
|
198
|
-
data=render_template(
|
199
|
-
endpoint_template,
|
200
|
-
endpoint_name=compile_endpoint_name(endpoint_prefix, add),
|
201
|
-
route=add,
|
202
|
-
),
|
203
|
-
)
|
204
|
-
)
|
205
|
-
|
206
|
-
for pair in diff.change.values():
|
207
|
-
logging.info(
|
208
|
-
f"{app}: Changing endpoint {pair.current.name} for route {pair.desired.name}"
|
196
|
+
endpoints_to_add = [
|
197
|
+
Endpoint(
|
198
|
+
name=compile_endpoint_name(endpoint_prefix, add),
|
199
|
+
data=render_template(
|
200
|
+
endpoint_template,
|
201
|
+
endpoint_name=compile_endpoint_name(endpoint_prefix, add),
|
202
|
+
route=add,
|
203
|
+
),
|
209
204
|
)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
)
|
205
|
+
for add in diff.add.values()
|
206
|
+
]
|
207
|
+
endpoints_to_change = [
|
208
|
+
Endpoint(
|
209
|
+
name=pair.current.name,
|
210
|
+
data=render_template(
|
211
|
+
endpoint_template,
|
212
|
+
endpoint_name=compile_endpoint_name(endpoint_prefix, pair.desired),
|
213
|
+
route=pair.desired,
|
214
|
+
),
|
221
215
|
)
|
222
|
-
|
223
|
-
|
224
|
-
|
216
|
+
for pair in diff.change.values()
|
217
|
+
]
|
218
|
+
endpoints_to_delete = [
|
219
|
+
Endpoint(name=delete.name) for delete in diff.delete.values()
|
220
|
+
]
|
225
221
|
return endpoints_to_add, endpoints_to_change, endpoints_to_delete
|
226
222
|
|
227
|
-
def
|
228
|
-
self,
|
223
|
+
def process(
|
224
|
+
self,
|
225
|
+
oc_map: OCMap,
|
226
|
+
endpoint_template: str,
|
227
|
+
apps: Iterable[AppV1],
|
228
|
+
cluster_names: Iterable[str] | None = None,
|
229
229
|
) -> list[App]:
|
230
230
|
"""Compile a list of apps with their endpoints to add, change and delete."""
|
231
|
-
|
232
|
-
for
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
endpoint_prefix=endpoint_prefix(namespace),
|
241
|
-
endpoint_template=endpoint_template,
|
242
|
-
endpoints=namespace.app.end_points or [],
|
243
|
-
routes=routes,
|
231
|
+
apps_with_changes: list[App] = []
|
232
|
+
for app in apps:
|
233
|
+
app_endpoints = App(name=app.name, path=app.path)
|
234
|
+
for namespace in app.namespaces or []:
|
235
|
+
if not self.is_enabled(namespace, cluster_names=cluster_names):
|
236
|
+
continue
|
237
|
+
|
238
|
+
logging.debug(
|
239
|
+
f"Processing namespace {namespace.cluster.name}/{namespace.name}"
|
244
240
|
)
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
241
|
+
routes = self.get_routes(oc_map, namespace)
|
242
|
+
endpoints_to_add, endpoints_to_change, endpoints_to_delete = (
|
243
|
+
self.get_namespace_endpoint_changes(
|
244
|
+
endpoint_prefix=endpoint_prefix(namespace),
|
245
|
+
endpoint_template=endpoint_template,
|
246
|
+
endpoints=app.end_points or [],
|
247
|
+
routes=routes,
|
248
|
+
)
|
249
|
+
)
|
250
|
+
# update the app with the endpoints per namespace
|
251
|
+
app_endpoints.endpoints_to_add += endpoints_to_add
|
252
|
+
app_endpoints.endpoints_to_change += endpoints_to_change
|
253
|
+
app_endpoints.endpoints_to_delete += endpoints_to_delete
|
254
|
+
|
255
|
+
# remove endpoints from deleted namespaces
|
256
|
+
namspace_names = {(ns.cluster.name, ns.name) for ns in app.namespaces or []}
|
257
|
+
for ep in app.end_points or []:
|
258
|
+
try:
|
259
|
+
ep_cluster, ep_namespace, _ = parse_endpoint_name(ep.name)
|
260
|
+
except ValueError:
|
261
|
+
continue
|
262
|
+
if (ep_cluster, ep_namespace) not in namspace_names:
|
263
|
+
app_endpoints.endpoints_to_delete.append(Endpoint(name=ep.name))
|
264
|
+
|
265
|
+
# log the changes
|
266
|
+
for add in app_endpoints.endpoints_to_add:
|
267
|
+
logging.info(f"{app.name}: Adding endpoint for route {add.name}")
|
268
|
+
|
269
|
+
for change in app_endpoints.endpoints_to_change:
|
270
|
+
logging.info(f"{app.name}: Changing endpoint for route {change.name}")
|
271
|
+
|
272
|
+
for delete in app_endpoints.endpoints_to_delete:
|
273
|
+
logging.info(f"{app.name}: Deleting endpoint for route {delete.name}")
|
274
|
+
|
275
|
+
if (
|
276
|
+
app_endpoints.endpoints_to_add
|
277
|
+
or app_endpoints.endpoints_to_change
|
278
|
+
or app_endpoints.endpoints_to_delete
|
279
|
+
):
|
280
|
+
# ignore apps without changes
|
281
|
+
apps_with_changes.append(app_endpoints)
|
282
|
+
|
283
|
+
return apps_with_changes
|
263
284
|
|
264
285
|
def runner(
|
265
286
|
self,
|
266
287
|
oc_map: OCMap,
|
267
288
|
merge_request_manager: MergeRequestManager,
|
268
289
|
endpoint_template: str,
|
269
|
-
|
290
|
+
apps: Iterable[AppV1],
|
270
291
|
) -> ExtendedEarlyExitRunnerResult:
|
271
292
|
"""Reconcile the endpoints for all namespaces."""
|
272
|
-
|
273
|
-
|
274
|
-
|
293
|
+
apps_with_changes = self.process(
|
294
|
+
oc_map,
|
295
|
+
endpoint_template,
|
296
|
+
apps,
|
297
|
+
cluster_names=self.params.cluster_name,
|
298
|
+
)
|
299
|
+
merge_request_manager.create_merge_request(apps=apps_with_changes)
|
300
|
+
return ExtendedEarlyExitRunnerResult(
|
301
|
+
payload={}, applied_count=len(apps_with_changes)
|
302
|
+
)
|
303
|
+
|
304
|
+
def is_enabled(
|
305
|
+
self, namespace: NamespaceV1, cluster_names: Iterable[str] | None = None
|
306
|
+
) -> bool:
|
307
|
+
"""Check if the integration is enabled for the given namespace."""
|
308
|
+
return (
|
309
|
+
integration_is_enabled(self.name, namespace.cluster)
|
310
|
+
and (not cluster_names or namespace.cluster.name in cluster_names)
|
311
|
+
and not namespace.delete
|
312
|
+
)
|
275
313
|
|
276
314
|
@defer
|
277
315
|
def run(self, dry_run: bool, defer: Callable | None = None) -> None:
|
278
316
|
"""Run the integration."""
|
279
317
|
gql_api = gql.get_api()
|
280
|
-
|
281
|
-
|
282
|
-
cluster_names=self.params.cluster_name,
|
283
|
-
namespace_name=self.params.namespace_name,
|
284
|
-
)
|
285
|
-
if not namespaces:
|
318
|
+
apps = self.get_apps(gql_api.query, app_name=self.params.app_name)
|
319
|
+
if not apps:
|
286
320
|
# nothing to do
|
287
321
|
return
|
288
322
|
|
289
323
|
oc_map = init_oc_map_from_namespaces(
|
290
|
-
namespaces=
|
324
|
+
namespaces=[
|
325
|
+
ns
|
326
|
+
for app in apps
|
327
|
+
for ns in app.namespaces or []
|
328
|
+
if self.is_enabled(ns, self.params.cluster_name)
|
329
|
+
],
|
291
330
|
secret_reader=self.secret_reader,
|
292
331
|
integration=QONTRACT_INTEGRATION,
|
293
332
|
use_jump_host=self.params.use_jump_host,
|
@@ -326,7 +365,7 @@ class EndpointsDiscoveryIntegration(
|
|
326
365
|
"oc_map": oc_map,
|
327
366
|
"merge_request_manager": merge_request_manager,
|
328
367
|
"endpoint_template": endpoint_template,
|
329
|
-
"
|
368
|
+
"apps": apps,
|
330
369
|
}
|
331
370
|
|
332
371
|
if self.params.enable_extended_early_exit and get_feature_toggle_state(
|
@@ -58,20 +58,20 @@ fragment VaultSecret on VaultSecret_v1 {
|
|
58
58
|
format
|
59
59
|
}
|
60
60
|
|
61
|
-
query
|
62
|
-
|
61
|
+
query EndPointsDiscoveryApps {
|
62
|
+
apps: apps_v1 {
|
63
|
+
path
|
63
64
|
name
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
... OcConnectionCluster
|
65
|
+
endPoints {
|
66
|
+
name
|
67
|
+
url
|
68
68
|
}
|
69
|
-
|
70
|
-
path
|
69
|
+
namespaces {
|
71
70
|
name
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
delete
|
72
|
+
clusterAdmin
|
73
|
+
cluster {
|
74
|
+
...OcConnectionCluster
|
75
75
|
}
|
76
76
|
}
|
77
77
|
}
|
@@ -90,25 +90,25 @@ class AppEndPointsV1(ConfiguredBaseModel):
|
|
90
90
|
url: str = Field(..., alias="url")
|
91
91
|
|
92
92
|
|
93
|
-
class AppV1(ConfiguredBaseModel):
|
94
|
-
path: str = Field(..., alias="path")
|
95
|
-
name: str = Field(..., alias="name")
|
96
|
-
end_points: Optional[list[AppEndPointsV1]] = Field(..., alias="endPoints")
|
97
|
-
|
98
|
-
|
99
93
|
class NamespaceV1(ConfiguredBaseModel):
|
100
94
|
name: str = Field(..., alias="name")
|
101
95
|
delete: Optional[bool] = Field(..., alias="delete")
|
102
96
|
cluster_admin: Optional[bool] = Field(..., alias="clusterAdmin")
|
103
97
|
cluster: OcConnectionCluster = Field(..., alias="cluster")
|
104
|
-
app: AppV1 = Field(..., alias="app")
|
105
98
|
|
106
99
|
|
107
|
-
class
|
100
|
+
class AppV1(ConfiguredBaseModel):
|
101
|
+
path: str = Field(..., alias="path")
|
102
|
+
name: str = Field(..., alias="name")
|
103
|
+
end_points: Optional[list[AppEndPointsV1]] = Field(..., alias="endPoints")
|
108
104
|
namespaces: Optional[list[NamespaceV1]] = Field(..., alias="namespaces")
|
109
105
|
|
110
106
|
|
111
|
-
|
107
|
+
class EndPointsDiscoveryAppsQueryData(ConfiguredBaseModel):
|
108
|
+
apps: Optional[list[AppV1]] = Field(..., alias="apps")
|
109
|
+
|
110
|
+
|
111
|
+
def query(query_func: Callable, **kwargs: Any) -> EndPointsDiscoveryAppsQueryData:
|
112
112
|
"""
|
113
113
|
This is a convenience function which queries and parses the data into
|
114
114
|
concrete types. It should be compatible with most GQL clients.
|
@@ -121,7 +121,7 @@ def query(query_func: Callable, **kwargs: Any) -> EndPointsDiscoveryNamespacesQu
|
|
121
121
|
kwargs: optional arguments that will be passed to the query function
|
122
122
|
|
123
123
|
Returns:
|
124
|
-
|
124
|
+
EndPointsDiscoveryAppsQueryData: queried data parsed into generated classes
|
125
125
|
"""
|
126
126
|
raw_data: dict[Any, Any] = query_func(DEFINITION, **kwargs)
|
127
|
-
return
|
127
|
+
return EndPointsDiscoveryAppsQueryData(**raw_data)
|
@@ -22,7 +22,7 @@ QONTRACT_INTEGRATION = "service-dependencies"
|
|
22
22
|
|
23
23
|
def get_dependency_names(dependency_map: Mapping[Any, Any], dep_type: str) -> list[str]:
|
24
24
|
dependency_maps = (dm for dm in dependency_map if dm["type"] == dep_type)
|
25
|
-
return [service["name"] for service in dependency_maps]
|
25
|
+
return [service["name"] for service in dependency_maps if "name" in service]
|
26
26
|
|
27
27
|
|
28
28
|
def get_desired_dependency_names(
|
{qontract_reconcile-0.10.2.dev15.dist-info → qontract_reconcile-0.10.2.dev17.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|