Coverage for src/meshadmin/server/networks/views/host.py: 64%

84 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-10 16:08 +0200

1import difflib 

2 

3from django.contrib.auth.mixins import LoginRequiredMixin 

4from django.http import HttpResponse 

5from django.shortcuts import get_object_or_404, redirect, render 

6from django.urls import reverse_lazy 

7from django.views.generic import CreateView, DeleteView, DetailView, UpdateView, View 

8 

9from meshadmin.server.networks.forms import HostForm 

10from meshadmin.server.networks.mixins import NetworkPermissionMixin 

11from meshadmin.server.networks.models import Host, HostConfig, Network 

12from meshadmin.server.networks.services import generate_config_yaml 

13 

14 

15class HostDetailView(LoginRequiredMixin, NetworkPermissionMixin, DetailView): 

16 model = Host 

17 template_name = "networks/host/detail.html" 

18 

19 def get_network(self): 

20 return self.get_object().network 

21 

22 def get_context_data(self, **kwargs): 

23 context = super().get_context_data(**kwargs) 

24 fields = [ 

25 { 

26 "name": field.name, 

27 "verbose_name": field.verbose_name, 

28 "value": getattr(self.object, field.name), 

29 } 

30 for field in self.model._meta.fields 

31 ] 

32 config_history = self.object.hostconfig_set.order_by("-created_at") 

33 context.update( 

34 { 

35 "fields": fields, 

36 "network": self.object.network, 

37 "groups": self.object.groups.all(), 

38 "config": config_history.first(), 

39 "config_history": config_history, 

40 } 

41 ) 

42 return context 

43 

44 

45class HostCreateView(LoginRequiredMixin, NetworkPermissionMixin, CreateView): 

46 model = Host 

47 form_class = HostForm 

48 template_name = "networks/shared/form.html" 

49 

50 def get_network(self): 

51 return get_object_or_404(Network, id=self.kwargs.get("network_id")) 

52 

53 def get_success_url(self): 

54 return reverse_lazy("networks:host-detail", kwargs={"pk": self.object.pk}) 

55 

56 def get_form_kwargs(self): 

57 kwargs = super().get_form_kwargs() 

58 network_id = self.kwargs.get("network_id") 

59 if network_id: 

60 network = get_object_or_404(Network, id=network_id) 

61 kwargs["network"] = network 

62 return kwargs 

63 

64 def get_context_data(self, **kwargs): 

65 context = super().get_context_data(**kwargs) 

66 context.update( 

67 { 

68 "action": "Create", 

69 "model_name": self.model._meta.verbose_name, 

70 "network_id": self.kwargs.get("network_id"), 

71 } 

72 ) 

73 return context 

74 

75 

76class HostUpdateView(LoginRequiredMixin, NetworkPermissionMixin, UpdateView): 

77 model = Host 

78 form_class = HostForm 

79 template_name = "networks/shared/form.html" 

80 

81 def get_network(self): 

82 return self.get_object().network 

83 

84 def get_success_url(self): 

85 return reverse_lazy("networks:host-detail", kwargs={"pk": self.object.pk}) 

86 

87 def get_context_data(self, **kwargs): 

88 context = super().get_context_data(**kwargs) 

89 context["action"] = "Update" 

90 return context 

91 

92 

93class HostDeleteView(LoginRequiredMixin, NetworkPermissionMixin, DeleteView): 

94 model = Host 

95 template_name = "networks/shared/delete.html" 

96 

97 def get_network(self): 

98 return self.get_object().network 

99 

100 def get_success_url(self): 

101 return ( 

102 reverse_lazy( 

103 "networks:network-detail", kwargs={"pk": self.object.network.pk} 

104 ) 

105 + "#hosts-section" 

106 ) 

107 

108 def get_context_data(self, **kwargs): 

109 context = super().get_context_data(**kwargs) 

110 context["model_name"] = self.model._meta.verbose_name 

111 return context 

112 

113 

114class HostConfigView(LoginRequiredMixin, View): 

115 def get(self, request, pk): 

116 get_object_or_404(Host, id=pk) 

117 config = generate_config_yaml(pk) 

118 return HttpResponse(config, content_type="text/yaml") 

119 

120 

121class ConfigDiffView(LoginRequiredMixin, View): 

122 def get(self, request, base_id, compare_id): 

123 try: 

124 base_config = get_object_or_404(HostConfig, id=base_id) 

125 compare_config = get_object_or_404(HostConfig, id=compare_id) 

126 diff = list( 

127 difflib.unified_diff( 

128 base_config.config.splitlines(), 

129 compare_config.config.splitlines(), 

130 fromfile=f"Version {base_config.created_at:%Y-%m-%d %H:%M}", 

131 tofile=f"Version {compare_config.created_at:%Y-%m-%d %H:%M}", 

132 lineterm="", 

133 ) 

134 ) 

135 context = { 

136 "diff": diff, 

137 "has_changes": bool(diff), 

138 "base_time": base_config.created_at.strftime("%Y-%m-%d %H:%M"), 

139 "compare_time": compare_config.created_at.strftime("%Y-%m-%d %H:%M"), 

140 } 

141 return render(request, "networks/host/diff.html", context) 

142 except Exception: 

143 context = {"error": "Error generating diff"} 

144 return render(request, "networks/host/diff.html", context) 

145 

146 

147class HostRefreshConfigView(LoginRequiredMixin, View): 

148 def post(self, request, pk, rollout_id): 

149 host = get_object_or_404(Host, id=pk) 

150 generate_config_yaml(host.id, ignore_freeze=True) 

151 return redirect("networks:rollout-detail", pk=rollout_id)