142 lines
5.3 KiB
Python
142 lines
5.3 KiB
Python
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
|
|
from hobo.agent.worker import settings as agent_settings
|
|
|
|
|
|
class Command(InteractiveTenantOption, BaseCommand):
|
|
def add_arguments(self, parser):
|
|
super().add_arguments(parser)
|
|
parser.add_argument('--directory', dest='directory')
|
|
|
|
def handle(self, *args, **options):
|
|
tenant = self.get_tenant_from_options_or_interactive(**options)
|
|
connection.set_tenant(tenant)
|
|
self.directory = options['directory']
|
|
|
|
self.authentic = Authentic.objects.all().first()
|
|
self.combos = list(Combo.objects.filter(secondary=False))
|
|
self.passerelle = Passerelle.objects.filter(secondary=False).first()
|
|
self.wcs = Wcs.objects.filter(secondary=False).first()
|
|
|
|
for service in [self.authentic, self.passerelle, self.wcs] + self.combos:
|
|
service.tenant_name = urllib.parse.urlparse(service.base_url).netloc
|
|
|
|
self.env = {k: v for k, v in os.environ.items() if k.endswith('_SETTINGS_FILE')}
|
|
if not self.wait_for_roles(nowait=True):
|
|
self.import_roles()
|
|
self.wait_for_roles()
|
|
self.import_wcs()
|
|
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
|
|
+ [
|
|
'tenant_command',
|
|
'import_site',
|
|
'-d',
|
|
urllib.parse.urlparse(self.authentic.base_url).netloc,
|
|
self.get_templated_file(roles_filename),
|
|
],
|
|
env=self.env,
|
|
)
|
|
|
|
def wait_for_success(self, cmd, nowait=False):
|
|
while True:
|
|
process = subprocess.run(cmd, env=self.env)
|
|
if process.returncode == 0 or nowait:
|
|
return process.returncode
|
|
time.sleep(0.5)
|
|
|
|
def wait_for_roles(self, nowait=False):
|
|
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(self.get_templated_file(roles_filename)))
|
|
rc = 0
|
|
for role in roles['roles']:
|
|
role_name = role['name']
|
|
rc += self.wait_for_success(
|
|
wcs_cmd + ['has_role', '-d', self.wcs.tenant_name, role_name], nowait=nowait
|
|
)
|
|
for combo in self.combos:
|
|
rc += self.wait_for_success(
|
|
combo_cmd + ['tenant_command', 'has_role', '-d', combo.tenant_name, role_name],
|
|
nowait=nowait,
|
|
)
|
|
if rc and nowait:
|
|
break
|
|
return bool(rc == 0)
|
|
|
|
def import_wcs(self):
|
|
wcs_cmd = agent_settings.WCS_MANAGE_COMMAND.split()
|
|
cmd = wcs_cmd + ['imio_import_directory', '-d', self.wcs.tenant_name, self.directory]
|
|
subprocess.run(cmd, env=self.env)
|
|
|
|
def import_combos(self):
|
|
combo_cmd = agent_settings.COMBO_MANAGE_COMMAND.split()
|
|
for combo in self.combos:
|
|
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,
|
|
self.get_templated_file(exported_file),
|
|
]
|
|
subprocess.run(cmd, env=self.env)
|
|
|
|
def import_passerelle(self):
|
|
if not os.path.exists(os.path.join(self.directory, 'passerelle')):
|
|
return
|
|
passerelle_cmd = agent_settings.PASSERELLE_MANAGE_COMMAND.split()
|
|
for filename in os.listdir(os.path.join(self.directory, 'passerelle')):
|
|
if not filename.endswith('.json'):
|
|
continue
|
|
exported_file = os.path.join(self.directory, 'passerelle', filename)
|
|
cmd = passerelle_cmd + [
|
|
'tenant_command',
|
|
'import_site',
|
|
'-d',
|
|
self.passerelle.tenant_name,
|
|
self.get_templated_file(exported_file),
|
|
]
|
|
subprocess.run(cmd, env=self.env)
|