Coverage for src/meshadmin/server/project/middleware.py: 39%
142 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-10 16:08 +0200
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-10 16:08 +0200
1from django.urls import resolve, reverse
3from meshadmin.server.networks.models import (
4 CA,
5 ConfigRollout,
6 Group,
7 Host,
8 Network,
9 Rule,
10 Template,
11)
14class BreadcrumbMiddleware:
15 def __init__(self, get_response):
16 self.get_response = get_response
18 def __call__(self, request):
19 response = self.get_response(request)
20 return response
22 def process_template_response(self, request, response):
23 if request.htmx:
24 return response
26 if not hasattr(response, "context_data"):
27 return response
29 # Start with the base networks link
30 breadcrumbs = [{"label": "Networks", "url": reverse("networks:network-list")}]
32 # Get resolved URL info
33 resolved = resolve(request.path_info)
34 url_name = resolved.url_name
35 kwargs = resolved.kwargs
36 context = response.context_data
38 # Handle network-specific paths
39 if "pk" in kwargs and url_name in [
40 "network-detail",
41 "network-edit",
42 "network-delete",
43 ]:
44 network_id = kwargs["pk"]
45 network = self._get_network_by_id(network_id, context)
46 if network:
47 breadcrumbs.append(
48 {
49 "label": network.name,
50 "url": reverse(
51 "networks:network-detail", kwargs={"pk": network.pk}
52 ),
53 }
54 )
55 if url_name == "network-edit":
56 breadcrumbs.append({"label": "Edit", "url": "#"})
57 elif url_name == "network-delete":
58 breadcrumbs.append({"label": "Delete", "url": "#"})
60 # Handle network creation
61 elif url_name == "network-create":
62 breadcrumbs.append({"label": "Create Network", "url": "#"})
64 # Handle network-related entities (host, template, group, ca, rollout, membership)
65 elif "network_id" in kwargs:
66 network_id = kwargs["network_id"]
67 network = self._get_network_by_id(network_id, context)
69 if network:
70 # Add network link with appropriate section anchor
71 section_anchor = ""
72 if "host" in url_name:
73 section_anchor = "#hosts-section"
74 elif "template" in url_name:
75 section_anchor = "#templates-section"
76 elif "group" in url_name or "security-group" in url_name:
77 section_anchor = "#groups-section"
78 elif "ca" in url_name:
79 section_anchor = "#cas-section"
80 elif "rollout" in url_name:
81 section_anchor = "#rollouts-section"
82 elif "member" in url_name or "member" in url_name:
83 section_anchor = "#members-section"
85 breadcrumbs.append(
86 {
87 "label": network.name,
88 "url": reverse(
89 "networks:network-detail", kwargs={"pk": network.pk}
90 )
91 + section_anchor,
92 }
93 )
95 # Add entity-specific breadcrumbs based on URL pattern
96 if "host" in url_name:
97 breadcrumbs.append({"label": "Create Host", "url": "#"})
98 elif "template" in url_name:
99 breadcrumbs.append({"label": "Create Template", "url": "#"})
100 elif "group" in url_name:
101 breadcrumbs.append({"label": "Create Group", "url": "#"})
102 elif "ca" in url_name:
103 breadcrumbs.append({"label": "Create CA", "url": "#"})
104 elif "rollout" in url_name:
105 breadcrumbs.append({"label": "Create Rollout", "url": "#"})
106 elif "add" in url_name:
107 breadcrumbs.append({"label": "Add Member", "url": "#"})
109 # Handle entity-specific paths (without network_id in URL)
110 elif "pk" in kwargs:
111 entity_id = kwargs["pk"]
113 # Handle Host
114 if url_name in [
115 "host-detail",
116 "host-edit",
117 "host-delete",
118 ]:
119 host = self._get_object_by_id(Host, entity_id, context)
120 if host:
121 network = host.network
122 breadcrumbs.append(
123 {
124 "label": network.name,
125 "url": reverse(
126 "networks:network-detail", kwargs={"pk": network.pk}
127 )
128 + "#hosts-section",
129 }
130 )
131 breadcrumbs.append(
132 {
133 "label": host.name,
134 "url": reverse(
135 "networks:host-detail", kwargs={"pk": host.pk}
136 ),
137 }
138 )
140 # Add action breadcrumb
141 if "edit" in url_name:
142 breadcrumbs.append({"label": "Edit", "url": "#"})
143 elif "delete" in url_name:
144 breadcrumbs.append({"label": "Delete", "url": "#"})
146 # Handle Template
147 elif url_name in ["template-detail", "template-edit", "template-delete"]:
148 template = self._get_object_by_id(Template, entity_id, context)
149 if template:
150 network = template.network
151 breadcrumbs.append(
152 {
153 "label": network.name,
154 "url": reverse(
155 "networks:network-detail", kwargs={"pk": network.pk}
156 )
157 + "#templates-section",
158 }
159 )
160 breadcrumbs.append(
161 {
162 "label": template.name,
163 "url": reverse(
164 "networks:template-detail", kwargs={"pk": template.pk}
165 ),
166 }
167 )
169 # Add action breadcrumb
170 if "edit" in url_name:
171 breadcrumbs.append({"label": "Edit", "url": "#"})
172 elif "delete" in url_name:
173 breadcrumbs.append({"label": "Delete", "url": "#"})
175 # Handle Group
176 elif url_name in ["group-detail", "group-edit", "group-delete"]:
177 group = self._get_object_by_id(Group, entity_id, context)
178 if group:
179 network = group.network
180 breadcrumbs.append(
181 {
182 "label": network.name,
183 "url": reverse(
184 "networks:network-detail", kwargs={"pk": network.pk}
185 )
186 + "#groups-section",
187 }
188 )
189 breadcrumbs.append(
190 {
191 "label": group.name,
192 "url": reverse(
193 "networks:group-detail", kwargs={"pk": group.pk}
194 ),
195 }
196 )
198 # Add action breadcrumb
199 if "edit" in url_name:
200 breadcrumbs.append({"label": "Edit", "url": "#"})
201 elif "delete" in url_name:
202 breadcrumbs.append({"label": "Delete", "url": "#"})
204 # Handle CA
205 elif url_name in ["ca-detail", "ca-edit", "ca-delete"]:
206 ca = self._get_object_by_id(CA, entity_id, context)
207 if ca:
208 network = ca.network
209 breadcrumbs.append(
210 {
211 "label": network.name,
212 "url": reverse(
213 "networks:network-detail", kwargs={"pk": network.pk}
214 )
215 + "#cas-section",
216 }
217 )
218 breadcrumbs.append(
219 {
220 "label": ca.name,
221 "url": reverse("networks:ca-detail", kwargs={"pk": ca.pk}),
222 }
223 )
225 # Add action breadcrumb
226 if "edit" in url_name:
227 breadcrumbs.append({"label": "Edit", "url": "#"})
228 elif "delete" in url_name:
229 breadcrumbs.append({"label": "Delete", "url": "#"})
231 # Handle Rule
232 elif url_name in ["rule-detail", "rule-edit", "rule-delete"]:
233 rule = self._get_object_by_id(Rule, entity_id, context)
234 if rule:
235 security_group = rule.security_group
236 network = security_group.network
237 breadcrumbs.append(
238 {
239 "label": network.name,
240 "url": reverse(
241 "networks:network-detail", kwargs={"pk": network.pk}
242 )
243 + "#groups-section",
244 }
245 )
246 if security_group:
247 breadcrumbs.append(
248 {
249 "label": security_group.name,
250 "url": reverse(
251 "networks:group-detail",
252 kwargs={"pk": security_group.pk},
253 ),
254 }
255 )
256 breadcrumbs.append(
257 {
258 "label": f"Rule {rule.pk}",
259 "url": reverse(
260 "networks:rule-detail", kwargs={"pk": rule.pk}
261 ),
262 }
263 )
265 # Add action breadcrumb
266 if "edit" in url_name:
267 breadcrumbs.append({"label": "Edit", "url": "#"})
268 elif "delete" in url_name:
269 breadcrumbs.append({"label": "Delete", "url": "#"})
271 # Handle Rollout
272 elif url_name in [
273 "rollout-detail",
274 "rollout-edit",
275 "rollout-delete",
276 ]:
277 rollout = self._get_object_by_id(ConfigRollout, entity_id, context)
278 if rollout:
279 network = rollout.network
280 breadcrumbs.append(
281 {
282 "label": network.name,
283 "url": reverse(
284 "networks:network-detail", kwargs={"pk": network.pk}
285 )
286 + "#rollouts-section",
287 }
288 )
289 breadcrumbs.append(
290 {
291 "label": f"Rollout {rollout.pk}",
292 "url": reverse(
293 "networks:rollout-detail", kwargs={"pk": rollout.pk}
294 ),
295 }
296 )
298 # Add action breadcrumb
299 if "edit" in url_name:
300 breadcrumbs.append({"label": "Edit", "url": "#"})
301 elif "delete" in url_name:
302 breadcrumbs.append({"label": "Delete", "url": "#"})
304 # Add breadcrumbs to context
305 response.context_data["breadcrumbs"] = breadcrumbs
306 return response
308 def _get_network_by_id(self, network_id, context):
309 """
310 Helper to get a network by ID from context or database
311 """
312 if (
313 "network" in context
314 and hasattr(context["network"], "pk")
315 and context["network"].pk == network_id
316 ):
317 return context["network"]
319 if (
320 "object" in context
321 and isinstance(context["object"], Network)
322 and context["object"].pk == network_id
323 ):
324 return context["object"]
326 try:
327 return Network.objects.get(id=network_id)
328 except Network.DoesNotExist:
329 return None
331 def _get_object_by_id(self, model_class, object_id, context):
332 """
333 Helper to get an object by ID from context or database
334 """
335 if (
336 "object" in context
337 and isinstance(context["object"], model_class)
338 and context["object"].pk == object_id
339 ):
340 return context["object"]
342 try:
343 return model_class.objects.get(id=object_id)
344 except model_class.DoesNotExist:
345 return None