Projet

Général

Profil

0001-start-the-maintenance-application-64868.patch

Emmanuel Cazenave, 11 mai 2022 18:30

Télécharger (11,6 ko)

Voir les différences:

Subject: [PATCH] start the maintenance application (#64868)

 hobo/maintenance/forms.py                     | 26 +++++++
 .../templates/hobo/maintenance/home.html      | 31 +++++++++
 hobo/maintenance/urls.py                      | 23 +++++++
 hobo/maintenance/views.py                     | 69 +++++++++++++++++++
 hobo/settings.py                              |  1 +
 hobo/templates/hobo/home.html                 |  1 +
 hobo/urls.py                                  |  2 +
 tests/test_maintenance.py                     | 34 +++++++++
 8 files changed, 187 insertions(+)
 create mode 100644 hobo/maintenance/forms.py
 create mode 100644 hobo/maintenance/templates/hobo/maintenance/home.html
 create mode 100644 hobo/maintenance/urls.py
 create mode 100644 hobo/maintenance/views.py
hobo/maintenance/forms.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 2015-2022  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django import forms
18
from django.utils.translation import ugettext_lazy as _
19

  
20

  
21
class MaintenanceForm(forms.Form):
22
    maintenance_page = forms.BooleanField(required=False, label=_('Enable maintenance page'))
23
    maintenance_pass_trough_header = forms.CharField(
24
        required=False, label=_('Maintenance HTTP header pass through')
25
    )
26
    disable_cron = forms.BooleanField(required=False, label=_('Disable cron jobs'))
hobo/maintenance/templates/hobo/maintenance/home.html
1
{% extends "hobo/base.html" %}
2
{% load i18n %}
3

  
4
{% block breadcrumb %}
5
{{ block.super }}
6
<a href="{% url 'maintenance-home' %}">{% trans "Maintenance" %}</a>
7
{% endblock %}
8

  
9
{% block appbar %}
10
<h2>{% trans 'Maintenance' %}</h2>
11
{% endblock %}
12

  
13
{% block content %}
14
{% if pass_through_ips %}
15
<div class="infonotice">
16
  {% blocktrans %}IP addresses configured to pass through the maintenance page:{% endblocktrans %} {{ pass_through_ips }}
17
</div>
18
{% else %}
19
<div class="warningnotice">
20
  {% trans "No IP addresses configured to pass through the maintenance page." %}
21
</div>
22
{% endif %}
23

  
24
<form action="." method="post">
25
  {% csrf_token %}
26
  {{ form.as_p }}
27
  <div class="buttons">
28
    <button>{% trans "Submit" %}</button>
29
  </div>
30
</form>
31
{% endblock %}
hobo/maintenance/urls.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 2015-2022 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django.conf.urls import url
18

  
19
from . import views
20

  
21
urlpatterns = [
22
    url(r'^$', views.home, name='maintenance-home'),
23
]
hobo/maintenance/views.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 2015-2022 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django.conf import settings
18
from django.urls import reverse_lazy
19
from django.utils.functional import cached_property
20
from django.views.generic import FormView
21

  
22
from hobo.environment.utils import get_setting_variable
23

  
24
from .forms import MaintenanceForm
25

  
26

  
27
class HomeView(FormView):
28
    template_name = 'hobo/maintenance/home.html'
29
    form_class = MaintenanceForm
30
    success_url = reverse_lazy('maintenance-home')
31

  
32
    @cached_property
33
    def maintenance_page_variable(self):
34
        return get_setting_variable('MAINTENANCE_PAGE')
35

  
36
    @cached_property
37
    def maintenance_pass_trough_header_variable(self):
38
        return get_setting_variable('MAINTENANCE_PASS_THROUGH_HEADER')
39

  
40
    @cached_property
41
    def tenant_disable_cron_jobs_variable(self):
42
        return get_setting_variable('TENANT_DISABLE_CRON_JOBS')
43

  
44
    def get_initial(self):
45
        initial = super().get_initial()
46
        initial['maintenance_page'] = bool(self.maintenance_page_variable.json)
47
        initial['maintenance_pass_trough_header'] = self.maintenance_pass_trough_header_variable.value
48
        initial['disable_cron'] = bool(self.tenant_disable_cron_jobs_variable.json)
49
        return initial
50

  
51
    def form_valid(self, form):
52
        self.maintenance_page_variable.json = form.cleaned_data['maintenance_page']
53
        self.maintenance_page_variable.save()
54
        self.maintenance_pass_trough_header_variable.value = form.cleaned_data[
55
            'maintenance_pass_trough_header'
56
        ]
57
        self.maintenance_pass_trough_header_variable.save()
58
        self.tenant_disable_cron_jobs_variable.json = form.cleaned_data['disable_cron']
59
        self.tenant_disable_cron_jobs_variable.save()
60
        return super().form_valid(form)
61

  
62
    def get_context_data(self, **kwargs):
63
        ctx = super().get_context_data(**kwargs)
64
        pass_through_ips_setting = getattr(settings, 'MAINTENANCE_PASS_THROUGH_IPS', [])
65
        ctx['pass_through_ips'] = ', '.join(pass_through_ips_setting)
66
        return ctx
67

  
68

  
69
home = HomeView.as_view()
hobo/settings.py
46 46
    'hobo.debug',
47 47
    'hobo.environment',
48 48
    'hobo.franceconnect',
49
    'hobo.maintenance',
49 50
    'hobo.matomo',
50 51
    'hobo.profile',
51 52
    'hobo.seo',
hobo/templates/hobo/home.html
117 117
 <a class="button button-paragraph" href="{% url 'environment-home' %}">{% trans 'Services' %}</a>
118 118
 <a class="button button-paragraph" href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a>
119 119
 <a class="button button-paragraph" href="{% url 'debug-home' %}">{% trans 'Debugging' %}</a>
120
 <a class="button button-paragraph" href="{% url 'maintenance-home' %}">{% trans 'Maintenance' %}</a>
120 121

  
121 122
</aside>
122 123
{% endblock %}
hobo/urls.py
23 23
from .emails.urls import urlpatterns as emails_urls
24 24
from .environment.urls import urlpatterns as environment_urls
25 25
from .franceconnect.urls import urlpatterns as franceconnect_urls
26
from .maintenance.urls import urlpatterns as maintenance_urls
26 27
from .matomo.urls import urlpatterns as matomo_urls
27 28
from .profile.urls import urlpatterns as profile_urls
28 29
from .seo.urls import urlpatterns as seo_urls
......
45 46
    url(r'^sms/', decorated_includes(admin_required, include(sms_urls))),
46 47
    url(r'^debug/', decorated_includes(admin_required, include(debug_urls))),
47 48
    url(r'^applications/', decorated_includes(admin_required, include(applications_urls))),
49
    url(r'^maintenance/', decorated_includes(admin_required, include(maintenance_urls))),
48 50
    url(r'^api/health/$', health_json, name='health-json'),
49 51
    url(r'^menu.json$', menu_json, name='menu_json'),
50 52
    url(r'^hobos.json$', hobo),
tests/test_maintenance.py
1 1
import mock
2 2
from test_manager import login
3 3

  
4
from hobo.environment.models import Variable
5

  
4 6

  
5 7
def test_maintenance_middleware(app, admin_user, db, monkeypatch, settings):
6 8
    app = login(app)
......
21 23
    settings.MAINTENANCE_PASS_THROUGH_HEADER = 'X-Entrouvert'
22 24
    resp = app.get('/', headers={'X-Entrouvert': 'yes'})
23 25
    assert resp.status_code == 200
26

  
27

  
28
def test_manage(app, admin_user, settings):
29
    assert Variable.objects.filter(name='SETTING_MAINTENANCE_PAGE').count() == 0
30
    assert Variable.objects.filter(name='SETTING_MAINTENANCE_PASS_THROUGH_HEADER').count() == 0
31
    assert Variable.objects.filter(name='TENANT_DISABLE_CRON_JOBS').count() == 0
32
    assert not getattr(settings, 'MAINTENANCE_PASS_THROUGH_IPS', [])
33

  
34
    login(app)
35
    resp = app.get('/maintenance/')
36
    assert 'No IP addresses configured' in resp.text
37
    resp.form.set('maintenance_page', True)
38
    resp.form.set('maintenance_pass_trough_header', 'X-Entrouvert')
39
    resp.form.set('disable_cron', True)
40
    resp = resp.form.submit().follow()
41
    assert Variable.objects.filter(name='SETTING_MAINTENANCE_PAGE').get().value == 'true'
42
    assert (
43
        Variable.objects.filter(name='SETTING_MAINTENANCE_PASS_THROUGH_HEADER').get().value == 'X-Entrouvert'
44
    )
45
    assert Variable.objects.filter(name='SETTING_TENANT_DISABLE_CRON_JOBS').get().value == 'true'
46

  
47
    resp.form.set('maintenance_page', False)
48
    resp.form.set('maintenance_pass_trough_header', '')
49
    resp.form.set('disable_cron', False)
50
    resp = resp.form.submit().follow()
51
    assert Variable.objects.filter(name='SETTING_MAINTENANCE_PAGE').get().value == 'false'
52
    assert Variable.objects.filter(name='SETTING_MAINTENANCE_PASS_THROUGH_HEADER').get().value == ''
53
    assert Variable.objects.filter(name='SETTING_TENANT_DISABLE_CRON_JOBS').get().value == 'false'
54

  
55
    settings.MAINTENANCE_PASS_THROUGH_IPS = ['127.0.0.1', '127.0.0.2']
56
    resp = app.get('/maintenance/')
57
    assert 'IP addresses configured to pass through the maintenance page: 127.0.0.1, 127.0.0.2' in resp.text
24
-