0002-django32-do-not-instanciate-ServiceBase-abstract-mod.patch
hobo/environment/models.py | ||
---|---|---|
97 | 97 |
self._parse_value_as_json() |
98 | 98 | |
99 | 99 | |
100 |
def is_resolvable(url): |
|
101 |
try: |
|
102 |
netloc = urllib.parse.urlparse(url).netloc |
|
103 |
if netloc and socket.gethostbyname(netloc): |
|
104 |
return True |
|
105 |
except socket.gaierror: |
|
106 |
return False |
|
107 | ||
108 | ||
109 |
def has_valid_certificate(url): |
|
110 |
try: |
|
111 |
requests.get(url, timeout=5, verify=True, allow_redirects=False) |
|
112 |
return True |
|
113 |
except requests.exceptions.SSLError: |
|
114 |
return False |
|
115 |
except requests.exceptions.ConnectionError: |
|
116 |
return False |
|
117 | ||
118 | ||
100 | 119 |
class ServiceBase(models.Model): |
101 | 120 |
class Meta: |
102 | 121 |
abstract = True |
... | ... | |
228 | 247 |
return self.get_base_url_path() + '__provision__/' |
229 | 248 | |
230 | 249 |
def is_resolvable(self): |
231 |
try: |
|
232 |
netloc = urllib.parse.urlparse(self.base_url).netloc |
|
233 |
if netloc and socket.gethostbyname(netloc): |
|
234 |
return True |
|
235 |
except socket.gaierror: |
|
236 |
return False |
|
250 |
return is_resolvable(self.base_url) |
|
237 | 251 | |
238 | 252 |
def has_valid_certificate(self): |
239 |
if not self.is_resolvable(): |
|
240 |
return False |
|
241 |
try: |
|
242 |
requests.get(self.base_url, timeout=5, verify=True, allow_redirects=False) |
|
243 |
return True |
|
244 |
except requests.exceptions.SSLError: |
|
245 |
return False |
|
246 |
except requests.exceptions.ConnectionError: |
|
247 |
return False |
|
253 |
return has_valid_certificate(self.base_url) |
|
248 | 254 | |
249 | 255 |
def is_running(self): |
250 | 256 |
if not self.is_resolvable(): |
hobo/environment/validators.py | ||
---|---|---|
3 | 3 |
from django.core.exceptions import ValidationError |
4 | 4 |
from django.utils.translation import gettext_lazy as _ |
5 | 5 | |
6 |
from hobo.environment.models import ServiceBase
|
|
6 |
from hobo.environment import models
|
|
7 | 7 | |
8 | 8 | |
9 | 9 |
def validate_service_url(url): |
10 |
service = ServiceBase(title='dummy', base_url=url) |
|
11 |
if not service.is_resolvable(): |
|
10 |
if not models.is_resolvable(url): |
|
12 | 11 |
raise ValidationError( |
13 | 12 |
_('Error: %(netloc)s is not resolvable in URL %(url)s'), |
14 | 13 |
code='not-resolvable', |
15 | 14 |
params={'netloc': urllib.parse.urlsplit(url).netloc, 'url': url}, |
16 | 15 |
) |
17 |
if not service.has_valid_certificate():
|
|
16 |
if not models.has_valid_certificate(url):
|
|
18 | 17 |
raise ValidationError( |
19 | 18 |
_('Error: no valid certificate for %(url)s'), code='invalid-certificate', params={'url': url} |
20 | 19 |
) |
tests/test_cook.py | ||
---|---|---|
9 | 9 |
from django.core.management import call_command |
10 | 10 |
from django.core.management.base import CommandError |
11 | 11 | |
12 |
from hobo.environment import models as environment_models |
|
12 | 13 |
from hobo.environment.management.commands.cook import Command |
13 | 14 |
from hobo.environment.models import ( |
14 | 15 |
Authentic, |
... | ... | |
57 | 58 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
58 | 59 |
action, action_args = 'server-action', {'url': 'https://test.org/'} |
59 | 60 | |
60 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
61 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
61 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
62 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
62 | 63 |
command.check_action(action, action_args) |
63 | 64 |
assert True |
64 | 65 | |
... | ... | |
68 | 69 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
69 | 70 |
action, action_args = 'not-a-server-action', {'url': 'https://test.org/'} |
70 | 71 | |
71 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
72 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
72 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
73 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
73 | 74 |
with pytest.raises(CommandError) as e_info: |
74 | 75 |
command.check_action(action, action_args) |
75 | 76 |
assert 'Unknown action not-a-server-action' in str(e_info.value) |
... | ... | |
80 | 81 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
81 | 82 |
action, action_args = 'server-action', {'url': 'https://test.org/'} |
82 | 83 | |
83 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: False)
|
|
84 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
84 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: False)
|
|
85 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
85 | 86 |
with pytest.raises(CommandError) as e_info: |
86 | 87 |
command.check_action(action, action_args) |
87 | 88 |
assert 'test.org is not resolvable in URL https://test.org/' in str(e_info.value) |
... | ... | |
92 | 93 |
command.server_action = 'mock a server_action handler (ex: hobo-create)' |
93 | 94 |
action, action_args = 'server-action', {'url': 'https://test.org/'} |
94 | 95 | |
95 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
96 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: False)
|
|
96 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
97 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: False)
|
|
97 | 98 |
with pytest.raises(CommandError) as e_info: |
98 | 99 |
command.check_action(action, action_args) |
99 | 100 |
assert 'no valid certificate for https://test.org/' in str(e_info.value) |
tests/test_environment.py | ||
---|---|---|
8 | 8 |
from test_manager import login |
9 | 9 |
from webtest import Upload |
10 | 10 | |
11 |
from hobo.environment import models as environment_models |
|
11 | 12 |
from hobo.environment.models import AVAILABLE_SERVICES, Combo, Passerelle, ServiceBase, Variable |
12 | 13 |
from hobo.environment.utils import get_installed_services_dict |
13 | 14 |
from hobo.profile.models import AttributeDefinition |
... | ... | |
143 | 144 |
response = form.submit() |
144 | 145 |
assert 'not resolvable' in response |
145 | 146 | |
146 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
147 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
147 | 148 |
form = response.form |
148 | 149 |
response = form.submit() |
149 | 150 |
assert 'no valid certificate' in response |
150 | 151 | |
151 | 152 |
assert not Combo.objects.exists() |
152 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
153 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
153 | 154 |
form = response.form |
154 | 155 |
response = form.submit() |
155 | 156 |
assert Combo.objects.exists() |
tests_schemas/test_cook.py | ||
---|---|---|
5 | 5 |
from django.core.management.base import CommandError |
6 | 6 | |
7 | 7 |
from hobo.deploy.utils import get_hobo_json |
8 |
from hobo.environment.models import ServiceBase
|
|
8 |
from hobo.environment import models as environment_models
|
|
9 | 9 | |
10 | 10 | |
11 | 11 |
def test_cook(db, fake_notify, monkeypatch): |
12 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
13 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
12 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
13 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
14 | 14 |
call_command('cook', 'tests_schemas/recipe.json') |
15 | 15 |
assert len(fake_notify) == 3 |
16 | 16 | |
17 | 17 | |
18 | 18 |
def test_cook_unresolvable(db, fake_notify, monkeypatch): |
19 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: False)
|
|
19 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: False)
|
|
20 | 20 |
with pytest.raises(CommandError) as e_info: |
21 | 21 |
call_command('cook', 'tests_schemas/recipe.json') |
22 | 22 |
assert 'is not resolvable' in str(e_info.value) |
... | ... | |
26 | 26 |
"""hobo/cook (before rabbitmq) scenario having templates. |
27 | 27 |
the resulting JSON may be helpfull to manually invoque hobo-deploy (after rabbitmq) |
28 | 28 |
""" |
29 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
30 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
29 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
30 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
31 | 31 |
call_command('cook', 'tests_schemas/example_recipe.json') |
32 | 32 | |
33 | 33 |
# notify_agents was call |
tests_schemas/test_rename_hobo_service.py | ||
---|---|---|
5 | 5 |
from django.core.management.base import CommandError |
6 | 6 |
from tenant_schemas.utils import tenant_context |
7 | 7 | |
8 |
from hobo.environment.models import Passerelle, ServiceBase
|
|
8 |
from hobo.environment import models as environment_models
|
|
9 | 9 |
from hobo.environment.utils import get_installed_services, get_or_create_local_hobo |
10 | 10 |
from hobo.multitenant.middleware import TenantMiddleware, TenantNotFound |
11 | 11 | |
12 | 12 | |
13 | 13 |
@pytest.fixture() |
14 | 14 |
def hobo_tenant(db, fake_notify, monkeypatch, fake_themes): |
15 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
16 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
15 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
16 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
17 | 17 |
yield call_command('cook', 'tests_schemas/example_recipe.json') |
18 | 18 |
call_command('delete_tenant', 'hobo-instance-name.dev.signalpublik.com') |
19 | 19 | |
... | ... | |
34 | 34 | |
35 | 35 | |
36 | 36 |
def test_rename_hobo_service_succes(db, fake_notify, monkeypatch, fake_themes): |
37 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
38 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
37 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
38 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
39 | 39 |
call_command('cook', 'tests_schemas/example_recipe.json') |
40 | 40 |
assert TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com') |
41 | 41 |
call_command( |
tests_schemas/test_rename_service.py | ||
---|---|---|
5 | 5 |
from django.core.management.base import CommandError |
6 | 6 |
from tenant_schemas.utils import tenant_context |
7 | 7 | |
8 |
from hobo.environment.models import Passerelle, ServiceBase
|
|
8 |
from hobo.environment import models as environment_models
|
|
9 | 9 |
from hobo.environment.utils import get_installed_services |
10 | 10 |
from hobo.multitenant.middleware import TenantMiddleware |
11 | 11 | |
12 | 12 | |
13 | 13 |
@pytest.fixture() |
14 | 14 |
def hobo_tenant(db, fake_notify, monkeypatch, fake_themes): |
15 |
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
|
16 |
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
|
15 |
monkeypatch.setattr(environment_models, 'is_resolvable', lambda x: True)
|
|
16 |
monkeypatch.setattr(environment_models, 'has_valid_certificate', lambda x: True)
|
|
17 | 17 |
yield call_command('cook', 'tests_schemas/example_recipe.json') |
18 | 18 |
call_command('delete_tenant', 'hobo-instance-name.dev.signalpublik.com') |
19 | 19 | |
... | ... | |
35 | 35 |
tenant = TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com') |
36 | 36 |
with tenant_context(tenant): |
37 | 37 |
assert get_installed_services() |
38 |
Passerelle.objects.create( |
|
38 |
environment_models.Passerelle.objects.create(
|
|
39 | 39 |
title='other passerelle', |
40 | 40 |
slug='other-passerelle', |
41 | 41 |
base_url='https://other-passerelle-instance-name.dev.signalpublik.com', |
... | ... | |
56 | 56 |
def test_rename_service_succes(hobo_tenant, monkeypatch): |
57 | 57 |
tenant = TenantMiddleware.get_tenant_by_hostname('hobo-instance-name.dev.signalpublik.com') |
58 | 58 |
with tenant_context(tenant): |
59 |
assert Passerelle.objects.count() == 1 |
|
60 |
passerelle_service = Passerelle.objects.first() |
|
59 |
assert environment_models.Passerelle.objects.count() == 1
|
|
60 |
passerelle_service = environment_models.Passerelle.objects.first()
|
|
61 | 61 |
assert ( |
62 | 62 |
passerelle_service.get_base_url_path() == 'https://passerelle-instance-name.dev.signalpublik.com/' |
63 | 63 |
) |
... | ... | |
69 | 69 |
'https://passerelle-instance-name.dev.signalpublik.com/', |
70 | 70 |
'https://new-passerelle-instance-name.dev.signalpublik.com/', |
71 | 71 |
) |
72 |
assert Passerelle.objects.count() == 1 |
|
73 |
passerelle_service = Passerelle.objects.first() |
|
72 |
assert environment_models.Passerelle.objects.count() == 1
|
|
73 |
passerelle_service = environment_models.Passerelle.objects.first()
|
|
74 | 74 |
assert ( |
75 | 75 |
passerelle_service.get_base_url_path() |
76 | 76 |
== 'https://new-passerelle-instance-name.dev.signalpublik.com/' |
77 |
- |