From e31161283d9d6e3bb78b3366a54328532657a905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 5 Mar 2021 08:51:35 +0100 Subject: [PATCH] make it possible to use input json files as templates (#51574) --- README | 13 +++++++++++++ hobo/imio_indus_deploy.py | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/README b/README index 81249ef..bcbf1fb 100644 --- a/README +++ b/README @@ -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 ------------------- diff --git a/hobo/imio_indus_deploy.py b/hobo/imio_indus_deploy.py index b746207..af57e98 100644 --- a/hobo/imio_indus_deploy.py +++ b/hobo/imio_indus_deploy.py @@ -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)