Projet

Général

Profil

0003-environment-add-migrate_service-command-60897.patch

Emmanuel Cazenave, 31 mars 2022 15:23

Télécharger (7,28 ko)

Voir les différences:

Subject: [PATCH 3/3] environment: add migrate_service command (#60897)

 .../management/commands/migrate_service.py    | 70 ++++++++++++++++
 tests_schemas/test_migrate_service.py         | 81 +++++++++++++++++++
 2 files changed, 151 insertions(+)
 create mode 100644 hobo/environment/management/commands/migrate_service.py
 create mode 100644 tests_schemas/test_migrate_service.py
hobo/environment/management/commands/migrate_service.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 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.core.management.base import BaseCommand, CommandError
18

  
19
from hobo.deploy.signals import notify_agents
20
from hobo.environment.utils import get_installed_services, wait_operationals
21

  
22

  
23
def normalize_url(url):
24
    if not url.endswith('/'):
25
        url += '/'
26
    return url
27

  
28

  
29
class Command(BaseCommand):
30
    verbosity = 1
31

  
32
    def add_arguments(self, parser):
33
        parser.add_argument('src_url', type=str)
34
        parser.add_argument('target_url', type=str)
35
        parser.add_argument(
36
            '--timeout',
37
            type=int,
38
            action='store',
39
            default=120,
40
            help='set the timeout for the wait_operationals method',
41
        )
42

  
43
    def handle(self, src_url, target_url, *args, **kwargs):
44
        self.timeout = kwargs.get('timeout')
45
        self.verbosity = kwargs.get('verbosity')
46
        self.terminal_width = 0
47

  
48
        src_url, target_url = normalize_url(src_url), normalize_url(target_url)
49
        target_service = None
50

  
51
        for service in get_installed_services():
52
            if service.get_base_url_path() == src_url:
53
                if service.secondary:
54
                    raise CommandError(
55
                        'Cannot migrate a secondary service, you must run the command against the hobo tenant that is primary holding it'
56
                    )
57
                target_service = service
58
                break
59
        if target_service is None:
60
            raise CommandError('No service matches %s' % src_url)
61

  
62
        target_service.change_base_url(target_url)
63
        target_service.last_operational_check_timestamp = None
64
        target_service.last_operational_success_timestamp = None
65
        target_service.save()
66
        notify_agents(None)
67
        wait_operationals([target_service], self.timeout, self.verbosity, self.terminal_width, notify_agents)
68

  
69
        if self.verbosity:
70
            print('Service migrated successfully, check it out : %s' % target_url)
tests_schemas/test_migrate_service.py
1
import pytest
2
from django.core.management import call_command
3
from django.core.management.base import CommandError
4
from mock import Mock
5
from tenant_schemas.utils import tenant_context
6

  
7
from hobo.environment.models import Passerelle, ServiceBase
8
from hobo.environment.utils import get_installed_services
9
from hobo.multitenant.middleware import TenantMiddleware
10

  
11

  
12
@pytest.fixture()
13
def hobo_tenant(db, fake_notify, monkeypatch, fake_themes):
14
    monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
15
    monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
16
    yield call_command('cook', 'tests_schemas/example_recipe.json')
17
    call_command('delete_tenant', 'hobo-instance-name.dev.signalpublik.com')
18

  
19

  
20
def test_unknown_service(hobo_tenant):
21
    tenant = TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com')
22
    with tenant_context(tenant):
23
        assert get_installed_services()
24
        with pytest.raises(CommandError) as e_info:
25
            call_command(
26
                'migrate_service',
27
                'https://unkown.dev.signalpublik.com/',
28
                'https://new-passerelle-instance-name.dev.signalpublik.com',
29
            )
30
        assert 'No service matches https://unkown.dev.signalpublik.com/' in str(e_info.value)
31

  
32

  
33
def test_secondary_service(hobo_tenant):
34
    tenant = TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com')
35
    with tenant_context(tenant):
36
        assert get_installed_services()
37
        Passerelle.objects.create(
38
            title='other passerelle',
39
            slug='other-passerelle',
40
            base_url='https://other-passerelle-instance-name.dev.signalpublik.com',
41
            secondary=True,
42
        )
43
        with pytest.raises(CommandError) as e_info:
44
            call_command(
45
                'migrate_service',
46
                'https://other-passerelle-instance-name.dev.signalpublik.com',
47
                'https://new-other-passerelle-instance-name.dev.signalpublik.com',
48
            )
49
        assert (
50
            'Cannot migrate a secondary service, you must run the command against the hobo tenant that is primary holding it'
51
            in str(e_info.value)
52
        )
53

  
54

  
55
def test_migrate_service_succes(hobo_tenant, monkeypatch):
56
    tenant = TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com')
57
    with tenant_context(tenant):
58
        assert Passerelle.objects.count() == 1
59
        passerelle_service = Passerelle.objects.first()
60
        assert (
61
            passerelle_service.get_base_url_path() == 'https://passerelle-instance-name.dev.signalpublik.com/'
62
        )
63
        assert get_installed_services()
64
        monkeypatch.setattr('hobo.environment.management.commands.migrate_service.notify_agents', Mock())
65
        monkeypatch.setattr('hobo.environment.management.commands.migrate_service.wait_operationals', Mock())
66
        call_command(
67
            'migrate_service',
68
            'https://passerelle-instance-name.dev.signalpublik.com/',
69
            'https://new-passerelle-instance-name.dev.signalpublik.com/',
70
        )
71
        assert Passerelle.objects.count() == 1
72
        passerelle_service = Passerelle.objects.first()
73
        assert (
74
            passerelle_service.get_base_url_path()
75
            == 'https://new-passerelle-instance-name.dev.signalpublik.com/'
76
        )
77
        assert len(passerelle_service.legacy_urls) == 1
78
        assert (
79
            passerelle_service.legacy_urls[0]['base_url']
80
            == 'https://passerelle-instance-name.dev.signalpublik.com/'
81
        )
0
-