Coverage for src/meshadmin/server/networks/views/rollout.py: 79%
107 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.contrib.auth.mixins import LoginRequiredMixin
2from django.http import HttpResponseRedirect
3from django.shortcuts import get_object_or_404, redirect
4from django.urls import reverse_lazy
5from django.views.generic import CreateView, DeleteView, DetailView, UpdateView, View
7from meshadmin.server.networks.mixins import NetworkPermissionMixin
8from meshadmin.server.networks.models import ConfigRollout, Host, Network
11class RolloutCreateView(LoginRequiredMixin, NetworkPermissionMixin, CreateView):
12 model = ConfigRollout
13 template_name = "networks/rollout/create.html"
14 fields = ["name", "notes"]
16 def get_network(self):
17 network_id = self.kwargs.get("network_id")
18 if network_id:
19 return get_object_or_404(Network, id=network_id)
20 return None
22 def get_context_data(self, **kwargs):
23 context = super().get_context_data(**kwargs)
24 network = self.get_network()
25 context["network"] = network
27 host_ids = self.request.GET.get("hosts", "").split(",")
28 if host_ids and host_ids[0]:
29 context["preselected_hosts"] = Host.objects.filter(
30 id__in=host_ids, network=network
31 )
33 context["hosts"] = Host.objects.filter(network=network)
34 return context
36 def form_valid(self, form):
37 form.instance.network_id = self.kwargs["network_id"]
38 response = super().form_valid(form)
40 selected_hosts = self.request.POST.getlist("hosts")
41 if selected_hosts:
42 self.object.target_hosts.set(selected_hosts)
43 Host.objects.filter(id__in=selected_hosts).update(config_freeze=True)
45 return response
47 def get_success_url(self):
48 return (
49 reverse_lazy(
50 "networks:network-detail", kwargs={"pk": self.kwargs["network_id"]}
51 )
52 + "#rollouts-section"
53 )
56class RolloutDetailView(LoginRequiredMixin, NetworkPermissionMixin, DetailView):
57 model = ConfigRollout
58 template_name = "networks/rollout/detail.html"
60 def get_network(self):
61 return self.get_object().network
63 def get_context_data(self, **kwargs):
64 context = super().get_context_data(**kwargs)
65 context["pending_hosts"] = self.object.target_hosts.exclude(
66 id__in=self.object.completed_hosts.values_list("id", flat=True)
67 )
68 return context
71class UnfreezeHostConfigView(LoginRequiredMixin, NetworkPermissionMixin, View):
72 def get_network(self):
73 rollout = get_object_or_404(ConfigRollout, id=self.kwargs.get("pk"))
74 return rollout.network
76 def post(self, request, pk):
77 rollout = get_object_or_404(ConfigRollout, id=pk)
78 host_id = request.POST.get("host_id")
79 if host_id:
80 host = get_object_or_404(Host, id=host_id)
81 if host not in rollout.completed_hosts.all():
82 try:
83 host.config_freeze = False
84 host.save()
85 rollout.completed_hosts.add(host)
86 except Exception:
87 rollout.status = "FAILED"
88 rollout.save()
89 else:
90 pending_hosts = rollout.target_hosts.exclude(
91 id__in=rollout.completed_hosts.values_list("id", flat=True)
92 )
93 for host in pending_hosts:
94 try:
95 host.config_freeze = False
96 host.save()
97 rollout.completed_hosts.add(host)
98 except Exception:
99 rollout.status = "FAILED"
100 rollout.save()
101 return redirect("networks:rollout-detail", pk=pk)
103 if not rollout.target_hosts.exclude(
104 id__in=rollout.completed_hosts.values_list("id", flat=True)
105 ).exists():
106 rollout.status = "COMPLETED"
107 rollout.save()
109 return redirect("networks:rollout-detail", pk=pk)
112class RolloutUpdateView(LoginRequiredMixin, NetworkPermissionMixin, UpdateView):
113 model = ConfigRollout
114 template_name = "networks/rollout/edit.html"
115 fields = ["name", "notes"]
117 def get_network(self):
118 return self.get_object().network
120 def get_context_data(self, **kwargs):
121 context = super().get_context_data(**kwargs)
122 context["hosts"] = Host.objects.filter(network=self.get_network())
123 return context
125 def form_valid(self, form):
126 response = super().form_valid(form)
127 selected_hosts = self.request.POST.getlist("hosts")
128 if selected_hosts:
129 removed_hosts = self.object.target_hosts.exclude(id__in=selected_hosts)
130 removed_hosts.update(config_freeze=False)
131 self.object.target_hosts.set(selected_hosts)
132 Host.objects.filter(id__in=selected_hosts).update(config_freeze=True)
134 return response
136 def get_success_url(self):
137 return reverse_lazy("networks:rollout-detail", kwargs={"pk": self.object.pk})
140class RolloutDeleteView(LoginRequiredMixin, NetworkPermissionMixin, DeleteView):
141 model = ConfigRollout
142 template_name = "networks/rollout/delete.html"
144 def get_network(self):
145 return self.get_object().network
147 def post(self, request, *args, **kwargs):
148 self.object = self.get_object()
149 self.object.target_hosts.all().update(config_freeze=False)
150 network_id = self.object.network_id
151 self.object.delete()
152 return HttpResponseRedirect(
153 reverse_lazy("networks:network-detail", kwargs={"pk": network_id})
154 + "#rollouts-section"
155 )