add custom management commands
This commit is contained in:
parent
b2c0f10899
commit
9872cf7347
|
@ -0,0 +1,14 @@
|
|||
import sys
|
||||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('role_name')
|
||||
|
||||
def handle(self, role_name, *args, **options):
|
||||
if Group.objects.filter(name=role_name).exists():
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
|
@ -0,0 +1,112 @@
|
|||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
import urllib.parse
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
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 import_roles(self):
|
||||
cmd = agent_settings.AUTHENTIC_MANAGE_COMMAND.split()
|
||||
subprocess.run(
|
||||
cmd
|
||||
+ [
|
||||
'tenant_command',
|
||||
'import_site',
|
||||
'-d',
|
||||
urllib.parse.urlparse(self.authentic.base_url).netloc,
|
||||
os.path.join(self.directory, 'roles', 'roles.json'),
|
||||
],
|
||||
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):
|
||||
if not os.path.exists(os.path.join(self.directory, 'roles/roles.json')):
|
||||
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')))
|
||||
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, 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,
|
||||
exported_file,
|
||||
]
|
||||
subprocess.run(cmd, env=self.env)
|
|
@ -0,0 +1,27 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
from ..qommon.ctl import Command, make_option
|
||||
from wcs.roles import Role
|
||||
|
||||
|
||||
class Cmd(Command):
|
||||
name = 'has_role'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__([make_option('-d', '--domain', action='store', dest='domain')])
|
||||
|
||||
def execute(self, base_options, sub_options, args):
|
||||
from .. import publisher
|
||||
|
||||
publisher.WcsPublisher.configure(self.config)
|
||||
publisher = publisher.WcsPublisher.create_publisher(register_tld_names=False)
|
||||
publisher.app_dir = os.path.join(publisher.app_dir, sub_options.domain)
|
||||
publisher.set_config()
|
||||
for role in Role.select():
|
||||
if role.name == args[0]:
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
Cmd.register()
|
|
@ -0,0 +1,165 @@
|
|||
import os
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from ..qommon.ctl import Command, make_option
|
||||
from wcs.blocks import BlockDef
|
||||
from wcs.carddef import CardDef
|
||||
from wcs.categories import Category
|
||||
from wcs.data_sources import NamedDataSource
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.wscalls import NamedWsCall
|
||||
|
||||
|
||||
class Cmd(Command):
|
||||
name = 'imio_import_directory'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
[
|
||||
make_option('-d', '--domain', action='store', dest='domain'),
|
||||
]
|
||||
)
|
||||
|
||||
def execute(self, base_options, sub_options, args):
|
||||
from .. import publisher
|
||||
|
||||
publisher.WcsPublisher.configure(self.config)
|
||||
publisher = publisher.WcsPublisher.create_publisher(register_tld_names=False)
|
||||
publisher.app_dir = os.path.join(publisher.app_dir, sub_options.domain)
|
||||
publisher.set_config()
|
||||
self.directory = args[0]
|
||||
self.import_categories()
|
||||
self.import_datasources()
|
||||
self.import_wscalls()
|
||||
self.import_workflows()
|
||||
self.import_blocks()
|
||||
self.import_carddefs()
|
||||
self.import_formdefs()
|
||||
|
||||
def import_categories(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'category')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'category')):
|
||||
category = Category.import_from_xml(open(os.path.join(self.directory, 'category', filename)))
|
||||
try:
|
||||
existing_category = Category.get_by_urlname(category.url_name)
|
||||
except KeyError:
|
||||
category.store()
|
||||
else:
|
||||
# replace
|
||||
category.id = existing_category.id
|
||||
category.store()
|
||||
|
||||
def import_datasources(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'datasources')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'datasources')):
|
||||
datasource = NamedDataSource.import_from_xml(
|
||||
open(os.path.join(self.directory, 'datasources', filename))
|
||||
)
|
||||
try:
|
||||
existing_datasource = NamedDataSource.get_by_slug(datasource.slug, ignore_errors=False)
|
||||
except KeyError:
|
||||
datasource.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# replace
|
||||
datasource.id = existing_datasource.id
|
||||
datasource.store(comment='Indus Update')
|
||||
|
||||
def import_workflows(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'workflows')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'workflows')):
|
||||
workflow = Workflow.import_from_xml(
|
||||
open(os.path.join(self.directory, 'workflows', filename)),
|
||||
include_id=False,
|
||||
check_datasources=True,
|
||||
)
|
||||
try:
|
||||
existing_workflow = [
|
||||
x for x in Workflow.select(ignore_errors=True) if x and x.name == workflow.name
|
||||
][0]
|
||||
except IndexError:
|
||||
workflow.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# replace
|
||||
workflow.id = existing_workflow.id
|
||||
workflow.store(comment='Indus Update')
|
||||
|
||||
def import_wscalls(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'wscalls')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'wscalls')):
|
||||
wscall = NamedWsCall.import_from_xml(open(os.path.join(self.directory, 'wscalls', filename)))
|
||||
try:
|
||||
existing_wscall = NamedWsCall.get(filename, ignore_errors=False)
|
||||
except KeyError:
|
||||
wscall.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# replace
|
||||
wscall.id = existing_wscall.id
|
||||
wscall.store(comment='Indus Update')
|
||||
|
||||
def import_blocks(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'blocks')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'blocks')):
|
||||
fd = open(os.path.join(self.directory, 'blocks', filename))
|
||||
tree = ET.parse(fd)
|
||||
# do not use import_from_xml to avoid autofixing url_name.
|
||||
blockdef = BlockDef.import_from_xml_tree(tree, include_id=False)
|
||||
try:
|
||||
existing_blockdef = BlockDef.get_by_urlname(blockdef.url_name)
|
||||
except KeyError:
|
||||
blockdef.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# replace
|
||||
blockdef.id = existing_blockdef.id
|
||||
blockdef.store(comment='Indus Update')
|
||||
|
||||
def import_carddefs(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'carddefs')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'carddefs')):
|
||||
fd = open(os.path.join(self.directory, 'carddefs', filename))
|
||||
tree = ET.parse(fd)
|
||||
# do not use import_from_xml to avoid autofixing url_name.
|
||||
carddef = CardDef.import_from_xml_tree(tree, include_id=False)
|
||||
try:
|
||||
existing_carddef = CardDef.get_by_urlname(carddef.url_name)
|
||||
except KeyError:
|
||||
carddef.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# replace
|
||||
carddef.id = existing_carddef.id
|
||||
carddef.store(comment='Indus Update')
|
||||
|
||||
def import_formdefs(self):
|
||||
if not os.path.exists(os.path.join(self.directory, 'forms')):
|
||||
return
|
||||
for filename in os.listdir(os.path.join(self.directory, 'forms')):
|
||||
fd = open(os.path.join(self.directory, 'forms', filename))
|
||||
tree = ET.parse(fd)
|
||||
# do not use import_from_xml to avoid autofixing url_name.
|
||||
formdef = FormDef.import_from_xml_tree(tree, include_id=False)
|
||||
try:
|
||||
existing_formdef = FormDef.get_by_urlname(formdef.url_name)
|
||||
except KeyError:
|
||||
formdef.store(comment='Indus Initial Import')
|
||||
else:
|
||||
# partial update
|
||||
for attribute in (
|
||||
'fields',
|
||||
'digest_template',
|
||||
'lateral_template',
|
||||
'submission_lateral_template',
|
||||
'user_support',
|
||||
'geolocations',
|
||||
):
|
||||
if hasattr(formdef, attribute):
|
||||
setattr(existing_formdef, attribute, getattr(formdef, attribute))
|
||||
existing_formdef.store(comment='Indus Update')
|
||||
|
||||
|
||||
Cmd.register()
|
Loading…
Reference in New Issue