commands/cook: add prechecks on recipe (#16599)
This commit is contained in:
parent
2e02dd0d35
commit
73848f82f3
|
@ -35,7 +35,7 @@ from hobo.agent.common.management.commands.hobo_deploy import (
|
|||
from hobo.multitenant.middleware import TenantMiddleware
|
||||
from hobo.environment.models import (AVAILABLE_SERVICES, Authentic, Wcs, Hobo,
|
||||
Passerelle, Combo, Fargo, Welco, MandayeJS, Chrono, Corbo, BiJoe,
|
||||
Variable)
|
||||
Variable, ServiceBase)
|
||||
from hobo.deploy.signals import notify_agents
|
||||
from hobo.theme.utils import set_theme
|
||||
from hobo.profile.models import AttributeDefinition
|
||||
|
@ -53,10 +53,12 @@ class Command(BaseCommand):
|
|||
parser.add_argument(
|
||||
'--timeout', type=int, action='store', default=120,
|
||||
help='set the timeout for the wait_operationals method')
|
||||
parser.add_argument('--permissive', action='store_true', help='ignore integrity checks')
|
||||
|
||||
def handle(self, recipe, *args, **kwargs):
|
||||
self.verbosity = kwargs.get('verbosity')
|
||||
self.timeout = kwargs.get('timeout')
|
||||
self.permissive = kwargs.get('permissive')
|
||||
self.run_cook(recipe)
|
||||
if self.verbosity:
|
||||
print 'All steps executed successfully. Your environment should now be ready.'
|
||||
|
@ -64,6 +66,7 @@ class Command(BaseCommand):
|
|||
def run_cook(self, filename):
|
||||
recipe = json.load(open(filename))
|
||||
variables = {}
|
||||
steps = []
|
||||
if 'load-variables-from' in recipe:
|
||||
variables.update(json.load(open(
|
||||
os.path.join(os.path.dirname(filename), recipe['load-variables-from']))))
|
||||
|
@ -75,6 +78,11 @@ class Command(BaseCommand):
|
|||
continue
|
||||
action_args[arg] = string.Template(
|
||||
action_args[arg]).substitute(variables)
|
||||
if not self.permissive:
|
||||
self.check_action(action, action_args)
|
||||
steps.append((action, action_args))
|
||||
|
||||
for action, action_args in steps:
|
||||
getattr(self, action.replace('-', '_'))(**action_args)
|
||||
if self.must_notify:
|
||||
notify_agents(None)
|
||||
|
@ -281,3 +289,14 @@ class Command(BaseCommand):
|
|||
current_tenant = connection.get_tenant()
|
||||
self.run_cook(filename)
|
||||
connection.set_tenant(current_tenant)
|
||||
|
||||
def check_action(self, action, action_args):
|
||||
if not hasattr(self, action.replace('-', '_')):
|
||||
raise CommandError('Error: Unknown action %s' % action)
|
||||
if 'url' in action_args.keys():
|
||||
url = action_args['url']
|
||||
service = ServiceBase(title='dummy', base_url=url)
|
||||
if not service.is_resolvable():
|
||||
raise CommandError('Error: %s is not resolvable' % url)
|
||||
if not service.has_valid_certificate():
|
||||
raise CommandError('Error: %s has no valid certificate' % url)
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import pytest
|
||||
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from hobo.environment.models import ServiceBase
|
||||
from hobo.environment.management.commands.cook import Command
|
||||
|
||||
|
||||
def test_check_action(monkeypatch):
|
||||
"""no exception raised if url are available"""
|
||||
command = Command()
|
||||
command.server_action = 'mock a server_action handler (ex: hobo-create)'
|
||||
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
||||
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
||||
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
||||
command.check_action(action, action_args)
|
||||
assert True
|
||||
|
||||
def test_check_action_unknown_action(monkeypatch):
|
||||
"""raise CommandError"""
|
||||
command = Command()
|
||||
command.server_action = 'mock a server_action handler (ex: hobo-create)'
|
||||
action, action_args = 'not-a-server-action', {u'url': u'https://test.org/'}
|
||||
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
||||
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
||||
with pytest.raises(CommandError) as e_info:
|
||||
command.check_action(action, action_args)
|
||||
assert 'Unknown action not-a-server-action' in str(e_info.value)
|
||||
|
||||
def test_check_action_unresolvable(monkeypatch):
|
||||
"""raise CommandError"""
|
||||
command = Command()
|
||||
command.server_action = 'mock a server_action handler (ex: hobo-create)'
|
||||
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
||||
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: False)
|
||||
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
||||
with pytest.raises(CommandError) as e_info:
|
||||
command.check_action(action, action_args)
|
||||
assert 'is not resolvable' in str(e_info.value)
|
||||
|
||||
def test_check_action_invalid_certificat(monkeypatch):
|
||||
"""raise CommandError"""
|
||||
command = Command()
|
||||
command.server_action = 'mock a server_action handler (ex: hobo-create)'
|
||||
action, action_args = 'server-action', {u'url': u'https://test.org/'}
|
||||
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
||||
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: False)
|
||||
with pytest.raises(CommandError) as e_info:
|
||||
command.check_action(action, action_args)
|
||||
assert 'has no valid certificate' in str(e_info.value)
|
|
@ -0,0 +1,49 @@
|
|||
import pytest
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.db import connection
|
||||
|
||||
from tenant_schemas.test.client import TenantClient
|
||||
from tenant_schemas.utils import tenant_context
|
||||
|
||||
from hobo.environment.management.commands.cook import Command
|
||||
from hobo.multitenant.middleware import TenantMiddleware
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def client(request, tenant_schema):
|
||||
name = 'hobo.foobar'
|
||||
tenant = TenantMiddleware.get_tenant_by_hostname(name)
|
||||
with tenant_context(tenant):
|
||||
return TenantClient(tenant)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def tenant_schema(django_db_setup, django_db_blocker):
|
||||
name = 'hobo.foobar'
|
||||
with django_db_blocker.unblock():
|
||||
call_command('create_hobo_tenant', name)
|
||||
tenant = TenantMiddleware.get_tenant_by_hostname(name)
|
||||
connection.set_tenant(tenant)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_notify(monkeypatch):
|
||||
services = {}
|
||||
|
||||
def notify_agents_mock(*args, **kwargs):
|
||||
from hobo.deploy.utils import get_hobo_json
|
||||
|
||||
environment = get_hobo_json()
|
||||
for service in environment.get('services', []):
|
||||
if service.keys() and service['slug'] not in services.keys():
|
||||
services[service['slug']] = service
|
||||
|
||||
def fake_wait(*args, **kwargs):
|
||||
pass
|
||||
|
||||
monkeypatch.setattr('hobo.environment.management.commands.cook.notify_agents', notify_agents_mock)
|
||||
monkeypatch.setattr('hobo.deploy.signals.notify_agents', notify_agents_mock)
|
||||
monkeypatch.setattr(Command, 'wait_operationals', fake_wait)
|
||||
|
||||
return services
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variables": {
|
||||
"domain": "dev.entrouvert.org"
|
||||
},
|
||||
"steps": [
|
||||
{"create-hobo": {
|
||||
"url": "https://${domain}/"
|
||||
}},
|
||||
{"create-authentic": {
|
||||
"url": "https://${domain}/",
|
||||
"title": "Connexion"
|
||||
}},
|
||||
{"create-combo": {
|
||||
"url": "https://${domain}/",
|
||||
"title": "Portail",
|
||||
"template_name": "portal-user"
|
||||
}}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import tempfile
|
||||
TENANT_BASE = tempfile.mkdtemp('hobo-tenant-base')
|
||||
TENANT_MODEL = 'multitenant.Tenant'
|
||||
MIDDLEWARE_CLASSES = ('hobo.multitenant.middleware.TenantMiddleware',) + MIDDLEWARE_CLASSES
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'tenant_schemas.postgresql_backend',
|
||||
'NAME': 'test_hobo',
|
||||
}
|
||||
}
|
||||
DATABASE_ROUTERS = ('tenant_schemas.routers.TenantSyncRouter',)
|
||||
INSTALLED_APPS = ('hobo.multitenant', 'hobo') + INSTALLED_APPS
|
||||
SHARED_APPS = ()
|
||||
TENANT_APPS = INSTALLED_APPS
|
|
@ -0,0 +1,20 @@
|
|||
import pytest
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from hobo.environment.models import ServiceBase
|
||||
|
||||
|
||||
def test_cook(db, fake_notify, monkeypatch):
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: True)
|
||||
monkeypatch.setattr(ServiceBase, 'has_valid_certificate', lambda x: True)
|
||||
call_command('cook', 'tests_schemas/recipe.json')
|
||||
assert(len(fake_notify) == 3)
|
||||
|
||||
|
||||
def test_cook_unresolvable(db, fake_notify, monkeypatch):
|
||||
monkeypatch.setattr(ServiceBase, 'is_resolvable', lambda x: False)
|
||||
with pytest.raises(CommandError) as e_info:
|
||||
call_command('cook', 'tests_schemas/recipe.json')
|
||||
assert 'is not resolvable' in str(e_info.value)
|
3
tox.ini
3
tox.ini
|
@ -15,6 +15,8 @@ setenv =
|
|||
BRANCH_NAME={env:BRANCH_NAME:}
|
||||
hobo: DJANGO_SETTINGS_MODULE=hobo.settings
|
||||
hobo: HOBO_SETTINGS_FILE=tests/settings.py
|
||||
schemas: DJANGO_SETTINGS_MODULE=hobo.settings
|
||||
schemas: HOBO_SETTINGS_FILE=tests_schemas/settings.py
|
||||
multitenant: PYTHONPATH=tests_multitenant
|
||||
multitenant: DJANGO_SETTINGS_MODULE=settings
|
||||
multipublik: PYTHONPATH=tests_multipublik
|
||||
|
@ -56,6 +58,7 @@ deps:
|
|||
commands =
|
||||
./getlasso.sh
|
||||
hobo: py.test {env:COVERAGE:} {env:NOMIGRATIONS:} {posargs:tests/}
|
||||
schemas: py.test {env:COVERAGE:} {env:NOMIGRATIONS:} {posargs:tests_schemas/}
|
||||
multitenant: py.test {env:COVERAGE:} {env:NOMIGRATIONS:} {posargs:tests_multitenant/}
|
||||
multipublik: py.test {env:COVERAGE:} {env:NOMIGRATIONS:} {posargs:tests_multipublik/}
|
||||
authentic: py.test {env:FAST:} {env:COVERAGE:} {env:NOMIGRATIONS:} {posargs:tests_authentic/}
|
||||
|
|
Loading…
Reference in New Issue