diff --git a/grandlyon/recipes/bron.json b/grandlyon/recipes/bron.json new file mode 100644 index 0000000..854a828 --- /dev/null +++ b/grandlyon/recipes/bron.json @@ -0,0 +1,40 @@ +{ + "variables": { + "commune": "bron" + }, + "steps": [ + {"create-hobo": { + "url": "https://hobo-${commune}.guichet-recette.grandlyon.com/" + }}, + {"set-idp": { + }}, + {"create-combo": { + "url": "https://portail-citoyen-${commune}.guichet-recette.grandlyon.com/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://portail-agent-${commune}.guichet-recette.grandlyon.com/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-chrono": { + "url": "https://agendas-${commune}.guichet-recette.grandlyon.com/", + "title": "Agendas" + }}, + {"create-wcs": { + "url": "https://demarches-${commune}.guichet-recette.grandlyon.com/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"create-bijoe": { + "url": "https://statistiques-${commune}.guichet-recette.grandlyon.com/", + "title": "Statistiques" + }}, + {"set-theme": { + "theme": "${commune}" + }} + ] +} diff --git a/grandlyon/recipes/dardilly.json b/grandlyon/recipes/dardilly.json new file mode 100644 index 0000000..3b999f1 --- /dev/null +++ b/grandlyon/recipes/dardilly.json @@ -0,0 +1,36 @@ +{ + "variables": { + "commune": "dardilly" + }, + "steps": [ + {"create-hobo": { + "url": "https://hobo-${commune}.guichet-recette.grandlyon.com/" + }}, + {"set-idp": { + }}, + {"create-combo": { + "url": "https://portail-citoyen-${commune}.guichet-recette.grandlyon.com/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://portail-agent-${commune}.guichet-recette.grandlyon.com/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-wcs": { + "url": "https://demarches-${commune}.guichet-recette.grandlyon.com/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"create-chrono": { + "url": "https://agendas-${commune}.guichet-recette.grandlyon.com/", + "title": "Agendas" + }}, + {"set-theme": { + "theme": "${commune}" + }} + ] +} diff --git a/grandlyon/recipes/grandlyon.json b/grandlyon/recipes/grandlyon.json new file mode 100644 index 0000000..2cb0c88 --- /dev/null +++ b/grandlyon/recipes/grandlyon.json @@ -0,0 +1,49 @@ +{ + "variables": { + "hobo": "hobo.guichet-recette.grandlyon.com", + "authentic": "connexion.guichet-recette.grandlyon.com", + "combo": "portail-citoyen.guichet-recette.grandlyon.com", + "combo_agent": "portail-agent.guichet-recette.grandlyon.com", + "passerelle": "passerelle.guichet-recette.grandlyon.com", + "wcs": "demarches.guichet-recette.grandlyon.com" + }, + "steps": [ + {"create-hobo": { + "url": "https://${hobo}/" + }}, + {"create-superuser": { + "email": "admin@entrouvert.com", + "password": "queeJ9aene4xeelaijai" + }}, + {"create-authentic": { + "url": "https://${authentic}/", + "title": "Connexion" + }}, + {"set-idp": { + }}, + {"create-passerelle": { + "url": "https://${passerelle}/", + "title": "Passerelle" + }}, + {"create-combo": { + "url": "https://${combo}/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://${combo_agent}/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-wcs": { + "url": "https://${wcs}/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"set-theme": { + "theme": "grandlyon" + }} + ] +} diff --git a/grandlyon/recipes/oullins.json b/grandlyon/recipes/oullins.json new file mode 100644 index 0000000..ce5ee63 --- /dev/null +++ b/grandlyon/recipes/oullins.json @@ -0,0 +1,36 @@ +{ + "variables": { + "commune": "oullins" + }, + "steps": [ + {"create-hobo": { + "url": "https://hobo-${commune}.guichet-recette.grandlyon.com/" + }}, + {"set-idp": { + }}, + {"create-combo": { + "url": "https://portail-citoyen-${commune}.guichet-recette.grandlyon.com/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://portail-agent-${commune}.guichet-recette.grandlyon.com/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-wcs": { + "url": "https://demarches-${commune}.guichet-recette.grandlyon.com/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"create-chrono": { + "url": "https://agendas-${commune}.guichet-recette.grandlyon.com/", + "title": "Agendas" + }}, + {"set-theme": { + "theme": "${commune}" + }} + ] +} diff --git a/grandlyon/recipes/vaulx-en-velin.json b/grandlyon/recipes/vaulx-en-velin.json new file mode 100644 index 0000000..f87c5fa --- /dev/null +++ b/grandlyon/recipes/vaulx-en-velin.json @@ -0,0 +1,36 @@ +{ + "variables": { + "commune": "vaulx-en-velin" + }, + "steps": [ + {"create-hobo": { + "url": "https://hobo-${commune}.guichet-recette.grandlyon.com/" + }}, + {"set-idp": { + }}, + {"create-combo": { + "url": "https://portail-citoyen-${commune}.guichet-recette.grandlyon.com/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://portail-agent-${commune}.guichet-recette.grandlyon.com/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-wcs": { + "url": "https://demarches-${commune}.guichet-recette.grandlyon.com/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"create-chrono": { + "url": "https://agendas-${commune}.guichet-recette.grandlyon.com/", + "title": "Agendas" + }}, + {"set-theme": { + "theme": "${commune}" + }} + ] +} diff --git a/grandlyon/recipes/villeurbanne.json b/grandlyon/recipes/villeurbanne.json new file mode 100644 index 0000000..eca75b6 --- /dev/null +++ b/grandlyon/recipes/villeurbanne.json @@ -0,0 +1,36 @@ +{ + "variables": { + "commune": "villeurbanne" + }, + "steps": [ + {"create-hobo": { + "url": "https://hobo-${commune}.guichet-recette.grandlyon.com/" + }}, + {"set-idp": { + }}, + {"create-combo": { + "url": "https://portail-citoyen-${commune}.guichet-recette.grandlyon.com/", + "title": "Portail", + "template_name": "portal-user" + }}, + {"create-combo": { + "url": "https://portail-agent-${commune}.guichet-recette.grandlyon.com/", + "slug": "portal-agent", + "title": "Portail Agent", + "template_name": "portal-agent" + }}, + {"create-wcs": { + "url": "https://demarches-${commune}.guichet-recette.grandlyon.com/", + "slug": "eservices", + "title": "D\u00e9marches", + "template_name": "modele.zip" + }}, + {"create-chrono": { + "url": "https://agendas-${commune}.guichet-recette.grandlyon.com/", + "title": "Agendas" + }}, + {"set-theme": { + "theme": "${commune}" + }} + ] +} diff --git a/grandlyon/scripts/communes.json b/grandlyon/scripts/communes.json new file mode 100644 index 0000000..c26c7b0 --- /dev/null +++ b/grandlyon/scripts/communes.json @@ -0,0 +1,11 @@ +{ + "orig": "Bron", + "dests": [ + {"name": "Dardilly"}, + {"name": "Oullins"}, + {"name": "Vaulx-en-Velin"}, + {"name": "Villeurbanne"} + ], + "dests-off": [ + ] +} diff --git a/grandlyon/scripts/copy-chrono.py b/grandlyon/scripts/copy-chrono.py new file mode 100644 index 0000000..f9622b5 --- /dev/null +++ b/grandlyon/scripts/copy-chrono.py @@ -0,0 +1,26 @@ +#! /usr/bin/env python + +import json +import os +import subprocess +import sys + +from django.utils.text import slugify + +communes_json = os.path.join(os.path.dirname(__file__), 'communes.json') + +orig_city = json.load(open(communes_json))['orig'] +slug_orig_city = slugify(orig_city) +orig_site = 'agendas-%s.guichet-recette.grandlyon.com' % slug_orig_city + +site_export_orig = subprocess.check_output(['sudo', '-u', 'chrono', 'chrono-manage', 'tenant_command', 'export_site', '-d', orig_site]) + +for dest in json.load(open(communes_json))['dests']: + dest_city = dest['name'] + slug_dest_city = slugify(dest_city) + dest_site = 'agendas-%s.guichet-recette.grandlyon.com' % slug_dest_city + + site_export = site_export_orig.replace(orig_city, dest_city) + site_export = site_export.replace(slug_orig_city, slug_dest_city) + open('/tmp/site-export.json', 'w').write(site_export) + subprocess.call(['sudo', '-u', 'chrono', 'chrono-manage', 'tenant_command', 'import_site', '-d', dest_site, '/tmp/site-export.json']) diff --git a/grandlyon/scripts/copy-portal-agent.py b/grandlyon/scripts/copy-portal-agent.py new file mode 100644 index 0000000..e945d35 --- /dev/null +++ b/grandlyon/scripts/copy-portal-agent.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python + +import json +import os +import subprocess +import sys + +from django.utils.text import slugify + +communes_json = os.path.join(os.path.dirname(__file__), 'communes.json') + +orig_city = json.load(open(communes_json))['orig'] +slug_orig_city = slugify(orig_city) +orig_site = 'portail-agent-%s.guichet-recette.grandlyon.com' % slug_orig_city + +site_export_orig = subprocess.check_output(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'export_site', '-d', orig_site]) + +for dest in json.load(open(communes_json))['dests']: + dest_city = dest['name'] + slug_dest_city = slugify(dest_city) + dest_site = 'portail-agent-%s.guichet-recette.grandlyon.com' % slug_dest_city + + site_export = site_export_orig.replace(orig_city, dest_city) + site_export = site_export.replace(slug_orig_city, slug_dest_city) + open('/tmp/site-export.json', 'w').write(site_export) + subprocess.call(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'import_site', '-d', dest_site, '/tmp/site-export.json']) + + subprocess.call(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'runscript', '-d', dest_site, '/data/home/tma/scripts/fsck-combo.py']) diff --git a/grandlyon/scripts/copy-portal-users.py b/grandlyon/scripts/copy-portal-users.py new file mode 100644 index 0000000..0e48f91 --- /dev/null +++ b/grandlyon/scripts/copy-portal-users.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python + +import json +import os +import subprocess +import sys + +from django.utils.text import slugify + +communes_json = os.path.join(os.path.dirname(__file__), 'communes.json') + +orig_city = json.load(open(communes_json))['orig'] +slug_orig_city = slugify(orig_city) +orig_site = 'portail-citoyen-%s.guichet-recette.grandlyon.com' % slug_orig_city + +site_export_orig = subprocess.check_output(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'export_site', '-d', orig_site]) + +for dest in json.load(open(communes_json))['dests']: + dest_city = dest['name'] + slug_dest_city = slugify(dest_city) + dest_site = 'portail-citoyen-%s.guichet-recette.grandlyon.com' % slug_dest_city + + site_export = site_export_orig.replace(orig_city, dest_city) + site_export = site_export.replace(slug_orig_city, slug_dest_city) + open('/tmp/site-export.json', 'w').write(site_export) + subprocess.call(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'import_site', '-d', dest_site, '/tmp/site-export.json']) + + subprocess.call(['sudo', '-u', 'combo', 'combo-manage', 'tenant_command', 'runscript', '-d', dest_site, '/data/home/tma/scripts/fsck-combo.py']) diff --git a/grandlyon/scripts/copy-wcs.py b/grandlyon/scripts/copy-wcs.py new file mode 100755 index 0000000..3484065 --- /dev/null +++ b/grandlyon/scripts/copy-wcs.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python +# usage: sudo -u wcs-au-quotidien ~tma/scripts/copy-wcs.py + +import json +import os +import subprocess +import sys + +from django.utils.text import slugify + +communes_json = os.path.join(os.path.dirname(__file__), 'communes.json') + +orig_city = json.load(open(communes_json))['orig'] +slug_orig_city = slugify(orig_city) +orig_site = 'demarches-%s.guichet-recette.grandlyon.com' % slug_orig_city + +roles_mapping = json.load(open('/tmp/roles.mapping.json')) + + +def copy(orig, dest, dest_city): + if os.path.exists(dest): + return # do not overwrite + src = open(orig).read() + for role_id in roles_mapping.keys(): + src = src.replace(role_id, roles_mapping[role_id][dest_city]) + fd = open(dest, 'w') + fd.write(src) + fd.close() + +for dest in json.load(open(communes_json))['dests']: + dest_city = dest['name'] + print dest_city + slug_dest_city = slugify(dest_city) + dest_site = 'demarches-%s.guichet-recette.grandlyon.com' % slug_dest_city + + for object_type in ('formdefs', 'workflows', 'categories', 'datasources', 'models'): + orig_dir = os.path.join('/var/lib/wcs-au-quotidien/%s/%s/' % (orig_site, object_type)) + dest_dir = os.path.join('/var/lib/wcs-au-quotidien/%s/%s/' % (dest_site, object_type)) + if not os.path.exists(orig_dir): + continue + if not os.path.exists(dest_dir): + os.mkdir(dest_dir) + for object_id in os.listdir(orig_dir): + copy(os.path.join(orig_dir, object_id), + os.path.join(dest_dir, object_id), + dest_city) + + subprocess.call(['/usr/bin/python', '/usr/sbin/wcsctl', '-f', '/etc/wcs/wcs-au-quotidien.cfg', + 'runscript', '--extra', '/usr/lib/pymodules/python2.7/extra-wcs-au-quotidien/', + '--vhost', dest_site, + '/data/home/tma/scripts/fsck-wcs.py']) diff --git a/grandlyon/scripts/duplicate-roles.py b/grandlyon/scripts/duplicate-roles.py new file mode 100644 index 0000000..0fbba8f --- /dev/null +++ b/grandlyon/scripts/duplicate-roles.py @@ -0,0 +1,36 @@ +# usage: +# cmd ou-orig ou-dest +# ex: +# authentic2-multitenant-manage tenant_command runscript -d connexion.guichet-recette.grandlyon.com ~tma/scripts/duplicate-roles.py Bron Dardilly + +import datetime +import json +import sys + +from authentic2.models import Attribute +from authentic2.compat import get_user_model +from authentic2.utils import datetime_to_utc +from django_rbac.utils import get_role_model, get_ou_model +from hobo.agent.authentic2.provisionning import Provisionning + +ORIG = json.load(open('communes.json'))['orig'] +DESTS = [x['name'] for x in json.load(open('communes.json'))['dests']] + +User = get_user_model() +Role = get_role_model() +Ou = get_ou_model() + +ou_orig = Ou.objects.get(name=ORIG) + +with Provisionning(): + mapping = {} + for orig_role in Role.objects.filter(ou=ou_orig): + if orig_role.slug.startswith('_a2'): + continue + mapping[orig_role.uuid] = {} + for dest in DESTS: + ou_dest = Ou.objects.get(name=dest) + dest_role, created = Role.objects.get_or_create(ou=ou_dest, name=orig_role.name.replace(ORIG, dest)) + dest_role.save() + mapping[orig_role.uuid][dest] = dest_role.uuid + json.dump(mapping, open('/tmp/roles.mapping.json', 'w'), indent=2) diff --git a/grandlyon/scripts/fsck-combo.py b/grandlyon/scripts/fsck-combo.py new file mode 100644 index 0000000..973f015 --- /dev/null +++ b/grandlyon/scripts/fsck-combo.py @@ -0,0 +1,7 @@ +# run .save() to fill cached properties + +from combo.apps.wcs.models import WcsFormCell, WcsCategoryCell, WcsFormsOfCategoryCell + +for obj_type in (WcsFormCell, WcsCategoryCell, WcsFormsOfCategoryCell): + for obj in obj_type.objects.all(): + obj.save() diff --git a/grandlyon/scripts/fsck-wcs.py b/grandlyon/scripts/fsck-wcs.py new file mode 100644 index 0000000..b4ac191 --- /dev/null +++ b/grandlyon/scripts/fsck-wcs.py @@ -0,0 +1,8 @@ +# iterate over all objects and store them again to make sure side-code is run. + +from quixote import get_publisher +from wcs.formdef import FormDef + +for formdef in FormDef.select(): + formdef.store() +