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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev15
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
@@ -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=Xh1pIvObueNK9BAlbS_EXH8RghkskrTB0huffbaSepo,107436
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=pngPnfrfXysPMX8Yy0utKjVxHgnej2DU4yM1ePtYYb4,4397
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=znfnlm8bZesfcNbQnaR2aaVM-DTBiw1I7FNmZcfyfoQ,12702
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/namespaces.py,sha256=FqJ0H7NdsIm5BgVnuJV9wLcj7i667VhCN559tWJ-WsA,3054
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.dev15.dist-info/METADATA,sha256=x22Iz3W6W70vThbR7kn69_3pciPTq24S6jfRG8hS5J0,24665
770
- qontract_reconcile-0.10.2.dev15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
771
- qontract_reconcile-0.10.2.dev15.dist-info/entry_points.txt,sha256=JniHZPadNOILPyfSl0LF2YSp3Db7K2_W2CN7i9f3Gos,540
772
- qontract_reconcile-0.10.2.dev15.dist-info/RECORD,,
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
- namespace_name=namespace_name,
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.namespaces import (
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.namespaces import (
23
- query as namespaces_query,
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, 0, 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
- namespace_name: str | None = None
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
- namespaces: Iterable[NamespaceV1]
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 get_namespaces(
128
+ def get_apps(
117
129
  self,
118
130
  query_func: Callable,
119
- cluster_names: Iterable[str] | None = None,
120
- namespace_name: str | None = None,
121
- ) -> list[NamespaceV1]:
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
- ns
125
- for ns in namespaces_query(query_func).namespaces or []
126
- if integration_is_enabled(self.name, ns.cluster)
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 get_endpoint_changes(
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
- endpoints_to_change = []
191
- endpoints_to_delete = []
192
-
193
- for add in diff.add.values():
194
- logging.info(f"{app}: Adding endpoint for route {add.name}")
195
- endpoints_to_add.append(
196
- Endpoint(
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
- endpoints_to_change.append(
211
- Endpoint(
212
- name=pair.current.name,
213
- data=render_template(
214
- endpoint_template,
215
- endpoint_name=compile_endpoint_name(
216
- endpoint_prefix, pair.desired
217
- ),
218
- route=pair.desired,
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
- for delete in diff.delete.values():
223
- logging.info(f"{app}: Deleting endpoint for route {delete.name}")
224
- endpoints_to_delete.append(Endpoint(name=delete.name))
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 get_apps(
228
- self, oc_map: OCMap, endpoint_template: str, namespaces: Iterable[NamespaceV1]
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
- apps: dict[str, App] = {}
232
- for namespace in namespaces:
233
- logging.debug(
234
- f"Processing namespace {namespace.cluster.name}/{namespace.name}"
235
- )
236
- routes = self.get_routes(oc_map, namespace)
237
- endpoints_to_add, endpoints_to_change, endpoints_to_delete = (
238
- self.get_endpoint_changes(
239
- app=namespace.app.name,
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
- # update the app with the endpoints per namespace
247
- app = apps.setdefault(
248
- namespace.app.path,
249
- App(name=namespace.app.name, path=namespace.app.path),
250
- )
251
- app.endpoints_to_add += endpoints_to_add
252
- app.endpoints_to_change += endpoints_to_change
253
- app.endpoints_to_delete += endpoints_to_delete
254
-
255
- # return only apps endpoint changes
256
- return [
257
- app
258
- for app in apps.values()
259
- if app.endpoints_to_add
260
- or app.endpoints_to_change
261
- or app.endpoints_to_delete
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
- namespaces: Iterable[NamespaceV1],
290
+ apps: Iterable[AppV1],
270
291
  ) -> ExtendedEarlyExitRunnerResult:
271
292
  """Reconcile the endpoints for all namespaces."""
272
- apps = self.get_apps(oc_map, endpoint_template, namespaces)
273
- merge_request_manager.create_merge_request(apps=apps)
274
- return ExtendedEarlyExitRunnerResult(payload={}, applied_count=len(apps))
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
- namespaces = self.get_namespaces(
281
- gql_api.query,
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=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
- "namespaces": namespaces,
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 EndPointsDiscoveryNamespaces {
62
- namespaces: namespaces_v1 {
61
+ query EndPointsDiscoveryApps {
62
+ apps: apps_v1 {
63
+ path
63
64
  name
64
- delete
65
- clusterAdmin
66
- cluster {
67
- ... OcConnectionCluster
65
+ endPoints {
66
+ name
67
+ url
68
68
  }
69
- app {
70
- path
69
+ namespaces {
71
70
  name
72
- endPoints {
73
- name
74
- url
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 EndPointsDiscoveryNamespacesQueryData(ConfiguredBaseModel):
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
- def query(query_func: Callable, **kwargs: Any) -> EndPointsDiscoveryNamespacesQueryData:
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
- EndPointsDiscoveryNamespacesQueryData: queried data parsed into generated classes
124
+ EndPointsDiscoveryAppsQueryData: queried data parsed into generated classes
125
125
  """
126
126
  raw_data: dict[Any, Any] = query_func(DEFINITION, **kwargs)
127
- return EndPointsDiscoveryNamespacesQueryData(**raw_data)
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(