0001-manage-availability-check-through-the-UI-29965.patch
passerelle/base/migrations/0011_auto_20190205_1126.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Generated by Django 1.11.17 on 2019-02-05 10:26 |
|
3 |
from __future__ import unicode_literals |
|
4 | ||
5 |
from django.db import migrations, models |
|
6 |
import django.db.models.deletion |
|
7 | ||
8 | ||
9 |
class Migration(migrations.Migration): |
|
10 | ||
11 |
dependencies = [ |
|
12 |
('contenttypes', '0002_remove_content_type_name'), |
|
13 |
('base', '0010_loggingparameters_trace_emails'), |
|
14 |
] |
|
15 | ||
16 |
operations = [ |
|
17 |
migrations.CreateModel( |
|
18 |
name='AvailibityParameters', |
|
19 |
fields=[ |
|
20 |
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
21 |
('resource_pk', models.PositiveIntegerField()), |
|
22 |
('disable_check', models.BooleanField(default=False, verbose_name='Disable availiblity check')), |
|
23 |
('resource_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), |
|
24 |
], |
|
25 |
), |
|
26 |
migrations.AlterUniqueTogether( |
|
27 |
name='availibityparameters', |
|
28 |
unique_together=set([('resource_type', 'resource_pk')]), |
|
29 |
), |
|
30 |
] |
passerelle/base/models.py | ||
---|---|---|
176 | 176 |
parameters.log_level = value |
177 | 177 |
parameters.save() |
178 | 178 | |
179 |
@property |
|
180 |
def availability_parameters(self): |
|
181 |
resource_type = ContentType.objects.get_for_model(self) |
|
182 |
try: |
|
183 |
return AvailibityParameters.objects.get( |
|
184 |
resource_type=resource_type, |
|
185 |
resource_pk=self.id) |
|
186 |
except AvailibityParameters.DoesNotExist: |
|
187 |
return AvailibityParameters( |
|
188 |
resource_type=resource_type, |
|
189 |
resource_pk=self.id) |
|
190 | ||
179 | 191 |
def soap_client(self, **kwargs): |
180 | 192 |
return passerelle.utils.SOAPClient(resource=self, **kwargs) |
181 | 193 | |
... | ... | |
390 | 402 | |
391 | 403 |
def availability(self): |
392 | 404 |
# "availability" cron job to update service statuses |
405 | ||
406 |
# eventually skip it |
|
407 |
if self.availability_parameters.disable_check: |
|
408 |
return |
|
409 | ||
393 | 410 |
currently_down = self.down() |
394 | 411 |
try: |
395 | 412 |
self.check_status() |
... | ... | |
477 | 494 |
unique_together = (('resource_type', 'resource_pk')) |
478 | 495 | |
479 | 496 | |
497 |
class AvailibityParameters(models.Model): |
|
498 |
resource_type = models.ForeignKey(ContentType) |
|
499 |
resource_pk = models.PositiveIntegerField() |
|
500 |
resource = fields.GenericForeignKey('resource_type', 'resource_pk') |
|
501 |
disable_check = models.BooleanField(default=False, verbose_name=_('Disable availiblity check')) |
|
502 | ||
503 |
class Meta: |
|
504 |
unique_together = (('resource_type', 'resource_pk')) |
|
505 | ||
506 | ||
480 | 507 | |
481 | 508 |
class ResourceLog(models.Model): |
482 | 509 |
timestamp = models.DateTimeField(auto_now_add=True) |
passerelle/base/urls.py | ||
---|---|---|
2 | 2 | |
3 | 3 |
from .views import ApiUserCreateView, ApiUserUpdateView, ApiUserDeleteView, \ |
4 | 4 |
ApiUserListView, AccessRightDeleteView, AccessRightCreateView, \ |
5 |
LoggingParametersUpdateView |
|
5 |
LoggingParametersUpdateView, ManageAvailabilityView
|
|
6 | 6 | |
7 | 7 |
access_urlpatterns = [ |
8 | 8 |
url(r'^$', ApiUserListView.as_view(), name='apiuser-list'), |
... | ... | |
15 | 15 |
url(r'^accessright/add/(?P<resource_type>[\w,-]+)/(?P<resource_pk>[\w,-]+)/(?P<codename>[\w,-]+)/', |
16 | 16 |
AccessRightCreateView.as_view(), name='access-right-add'), |
17 | 17 |
url(r'logging/parameters/(?P<resource_type>[\w,-]+)/(?P<resource_pk>[\w,-]+)/$', |
18 |
LoggingParametersUpdateView.as_view(), name='logging-parameters') |
|
18 |
LoggingParametersUpdateView.as_view(), name='logging-parameters'), |
|
19 |
url(r'manage/availability/(?P<resource_type>[\w,-]+)/(?P<resource_pk>[\w,-]+)/$', |
|
20 |
ManageAvailabilityView.as_view(), name='manage-availability') |
|
21 | ||
19 | 22 |
] |
passerelle/base/views.py | ||
---|---|---|
5 | 5 |
from django.views.generic import * |
6 | 6 |
from django.http import Http404 |
7 | 7 | |
8 |
from .models import ApiUser, AccessRight, LoggingParameters |
|
8 |
from .models import ApiUser, AccessRight, LoggingParameters, AvailibityParameters, ResourceStatus
|
|
9 | 9 |
from .forms import ApiUserForm, AccessRightForm |
10 | 10 |
from ..utils import get_trusted_services |
11 | 11 | |
... | ... | |
136 | 136 |
parameters.trace_emails = form.cleaned_data['trace_emails'] |
137 | 137 |
parameters.save() |
138 | 138 |
return super(LoggingParametersUpdateView, self).form_valid(form) |
139 | ||
140 | ||
141 |
class ManageAvailabilityView(FormView): |
|
142 |
template_name = 'passerelle/manage/manage_availability_form.html' |
|
143 | ||
144 |
def get_context_data(self, **kwargs): |
|
145 |
context = super(ManageAvailabilityView, self).get_context_data(**kwargs) |
|
146 |
connector = self.get_resource() |
|
147 |
context['connector'] = connector |
|
148 |
context['availability_status'] = connector.get_availability_status() |
|
149 |
return context |
|
150 | ||
151 |
def get_form_class(self): |
|
152 |
form_class = model_forms.modelform_factory( |
|
153 |
AvailibityParameters, |
|
154 |
fields=['disable_check']) |
|
155 |
return form_class |
|
156 | ||
157 |
def get_initial(self): |
|
158 |
d = self.initial.copy() |
|
159 |
d['resource_type'] = self.kwargs['resource_type'] |
|
160 |
d['resource_pk'] = self.kwargs['resource_pk'] |
|
161 |
d['disable_check'] = self.get_resource().availability_parameters.disable_check |
|
162 |
return d |
|
163 | ||
164 |
def get_resource(self): |
|
165 |
content_type = ContentType.objects.get_for_id(self.kwargs['resource_type']) |
|
166 |
return content_type.model_class().objects.get(pk=self.kwargs['resource_pk']) |
|
167 | ||
168 |
def get_success_url(self): |
|
169 |
return self.get_resource().get_absolute_url() |
|
170 | ||
171 |
def form_valid(self, form): |
|
172 |
resource = self.get_resource() |
|
173 |
parameters = resource.availability_parameters |
|
174 |
disable_check = form.cleaned_data['disable_check'] |
|
175 | ||
176 |
if resource.down() and disable_check: |
|
177 |
resource_type = ContentType.objects.get_for_model(resource) |
|
178 |
ResourceStatus( |
|
179 |
resource_type=resource_type, |
|
180 |
resource_pk=self.kwargs['resource_pk'], |
|
181 |
status='up', |
|
182 |
message='').save() |
|
183 |
resource.logger.info( |
|
184 |
u'connector "%s" (%s) put back up by user', resource, resource.__class__.__name__) |
|
185 | ||
186 |
parameters.disable_check = disable_check |
|
187 |
parameters.save() |
|
188 |
return super(ManageAvailabilityView, self).form_valid(form) |
passerelle/templates/passerelle/manage/manage_availability_form.html | ||
---|---|---|
1 |
{% extends "passerelle/manage.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{% trans 'Connector Status' %} : {{availability_status.status}}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block content %} |
|
9 |
<form method="post"> |
|
10 |
{% csrf_token %} |
|
11 |
{{ form.as_p }} |
|
12 |
<div class="buttons"> |
|
13 |
<button class="submit-button">{% trans 'Save' %}</button> |
|
14 |
<a href="{{ connector.get_absolute_url }}" class="cancel">{% trans 'Cancel' %}</a> |
|
15 |
</div> |
|
16 |
</form> |
|
17 |
{% endblock %} |
passerelle/templates/passerelle/manage/service_view.html | ||
---|---|---|
15 | 15 |
{% endwith %} |
16 | 16 |
</h2> |
17 | 17 |
<span class="actions"> |
18 |
{% if object|can_edit:request.user and object.get_availability_status %} |
|
19 |
<a rel="popup" href="{% url 'manage-availability' resource_type=object|resource_type resource_pk=object.id %}">{% trans 'manage availability' %}</a> |
|
20 |
{% endif %} |
|
18 | 21 |
{% if object|can_edit:request.user %} |
19 | 22 |
<a rel="popup" href="{% url 'logging-parameters' resource_type=object|resource_type resource_pk=object.id %}">{% trans 'logging parameters' %}</a> |
20 | 23 |
{% endif %} |
tests/test_availability.py | ||
---|---|---|
73 | 73 |
connector.availability() |
74 | 74 |
assert connector.get_availability_status().down() |
75 | 75 |
assert '500' in connector.get_availability_status().message |
76 | ||
77 | ||
78 |
def test_availability_disabled(app, connector): |
|
79 |
with HTTMock(up_mock): |
|
80 |
connector.availability() |
|
81 |
assert connector.get_availability_status().up() |
|
82 | ||
83 |
av = connector.availability_parameters |
|
84 |
av.disable_check = True |
|
85 |
av.save() |
|
86 | ||
87 |
with HTTMock(down_mock): |
|
88 |
connector.availability() |
|
89 |
assert connector.get_availability_status().up() |
|
90 | ||
91 |
av.disable_check = False |
|
92 |
av.save() |
|
93 |
with HTTMock(down_mock): |
|
94 |
connector.availability() |
|
95 |
assert connector.get_availability_status().down() |
tests/test_manager.py | ||
---|---|---|
7 | 7 |
from django.core.files import File |
8 | 8 |
import pytest |
9 | 9 | |
10 |
from passerelle.base.models import ApiUser, AccessRight, ResourceLog |
|
10 |
from passerelle.base.models import ApiUser, AccessRight, ResourceLog, ResourceStatus
|
|
11 | 11 |
from passerelle.apps.csvdatasource.models import CsvDataSource, Query |
12 | 12 | |
13 | 13 |
pytestmark = pytest.mark.django_db |
... | ... | |
197 | 197 |
resp = app.get(csv.get_absolute_url()) |
198 | 198 |
resp = resp.click('logging parameters') |
199 | 199 |
assert resp.form['trace_emails'].value == 'fred@localhost' |
200 | ||
201 | ||
202 |
def test_availability_parameters(app, admin_user): |
|
203 |
data = StringIO('1;Foo\n2;Bar\n3;Baz') |
|
204 |
csv = CsvDataSource.objects.create( |
|
205 |
csv_file=File(data, 't.csv'), |
|
206 |
columns_keynames='id, text', slug='test', title='a title', description='a description') |
|
207 |
app = login(app) |
|
208 |
resp = app.get(csv.get_absolute_url()) |
|
209 | ||
210 |
assert not csv.availability_parameters.disable_check |
|
211 |
# No availability check so this should not show up |
|
212 |
assert 'manage availability' not in resp.text |
|
213 | ||
214 |
resource_type = ContentType.objects.get_for_model(csv) |
|
215 |
status = ResourceStatus( |
|
216 |
resource_type=resource_type, resource_pk=csv.pk, |
|
217 |
status='up', message='') |
|
218 |
status.save() |
|
219 |
resp = app.get(csv.get_absolute_url()) |
|
220 |
assert 'manage availability' in resp.text |
|
221 | ||
222 |
resp = resp.click('manage availability') |
|
223 |
assert 'up' in resp.text |
|
224 |
resp.form['disable_check'] = True |
|
225 |
resp = resp.form.submit() |
|
226 |
# Connector status not changed, availibility parameters changed |
|
227 |
assert status == csv.get_availability_status() |
|
228 |
assert csv.availability_parameters.disable_check |
|
229 | ||
230 |
resp = app.get(csv.get_absolute_url()) |
|
231 |
resp = resp.click('manage availability') |
|
232 |
resp.form['disable_check'] = False |
|
233 |
resp = resp.form.submit() |
|
234 | ||
235 |
# Connector down |
|
236 |
status = ResourceStatus( |
|
237 |
resource_type=resource_type, resource_pk=csv.pk, |
|
238 |
status='down', message='') |
|
239 |
status.save() |
|
240 |
assert csv.down() |
|
241 |
resp = app.get(csv.get_absolute_url()) |
|
242 |
resp = resp.click('manage availability') |
|
243 |
resp.form['disable_check'] = True |
|
244 |
resp = resp.form.submit() |
|
245 |
# Connector is put backup |
|
246 |
assert csv.availability_parameters.disable_check |
|
247 |
assert not csv.down() |
|
248 |
status = csv.get_availability_status() |
|
249 |
assert status.status == 'up' |
|
200 |
- |