make it possible to use input json files as templates (#51574)

This commit is contained in:
Frédéric Péters 2021-03-05 08:51:35 +01:00
parent b847f6cc28
commit e31161283d
2 changed files with 47 additions and 5 deletions

13
README
View File

@ -43,6 +43,19 @@ Expected directory layout
}
The combo, passerelle and roles JSON files will be treated as templates if they
start with a Django template comment ({# ... #}), with environment variables
available in the rendering context.
This allows for such an import file:
{# template #}{
"resources": [
{
"server_url": "https://{{ environ.SERVER_HOSTNAME }}",
...
Order of operations
-------------------

View File

@ -1,11 +1,14 @@
import json
import os
import random
import subprocess
import tempfile
import time
import urllib.parse
from django.core.management.base import BaseCommand
from django.db import connection
from django.template import Context, Template
from hobo.multitenant.management.commands import InteractiveTenantOption
from hobo.environment.models import Authentic, Combo, Passerelle, Wcs
@ -38,7 +41,26 @@ class Command(InteractiveTenantOption, BaseCommand):
self.import_combos()
self.import_passerelle()
def get_templated_file(self, template_name):
with open(template_name) as fd:
first_line = fd.readline()
if '{#' in first_line:
# template marker
fd.seek(0)
template = Template(fd.read())
context = Context({'environ': os.environ})
new_file_name = os.path.join(
tempfile.gettempdir(), '%s-%s' % (tempfile.gettempprefix(), random.randint(0, 10 ** 10))
)
with open(new_file_name, 'w') as fd2:
fd2.write(template.render(context))
return new_file_name
return template_name
def import_roles(self):
roles_filename = os.path.join(self.directory, 'roles/roles.json')
if not os.path.exists(roles_filename):
return
cmd = agent_settings.AUTHENTIC_MANAGE_COMMAND.split()
subprocess.run(
cmd
@ -47,7 +69,7 @@ class Command(InteractiveTenantOption, BaseCommand):
'import_site',
'-d',
urllib.parse.urlparse(self.authentic.base_url).netloc,
os.path.join(self.directory, 'roles', 'roles.json'),
self.get_templated_file(roles_filename),
],
env=self.env,
)
@ -60,11 +82,12 @@ class Command(InteractiveTenantOption, BaseCommand):
time.sleep(0.5)
def wait_for_roles(self, nowait=False):
if not os.path.exists(os.path.join(self.directory, 'roles/roles.json')):
roles_filename = os.path.join(self.directory, 'roles/roles.json')
if not os.path.exists(roles_filename):
return
wcs_cmd = agent_settings.WCS_MANAGE_COMMAND.split()
combo_cmd = agent_settings.COMBO_MANAGE_COMMAND.split()
roles = json.load(open(os.path.join(self.directory, 'roles', 'roles.json')))
roles = json.load(open(self.get_templated_file(roles_filename)))
rc = 0
for role in roles['roles']:
role_name = role['name']
@ -91,7 +114,13 @@ class Command(InteractiveTenantOption, BaseCommand):
exported_file = os.path.join(self.directory, 'combo/%s.json' % combo.template_name)
if not os.path.exists(exported_file):
continue
cmd = combo_cmd + ['tenant_command', 'import_site', '-d', combo.tenant_name, exported_file]
cmd = combo_cmd + [
'tenant_command',
'import_site',
'-d',
combo.tenant_name,
self.get_templated_file(exported_file),
]
subprocess.run(cmd, env=self.env)
def import_passerelle(self):
@ -107,6 +136,6 @@ class Command(InteractiveTenantOption, BaseCommand):
'import_site',
'-d',
self.passerelle.tenant_name,
exported_file,
self.get_templated_file(exported_file),
]
subprocess.run(cmd, env=self.env)