Compare commits

161 Commits

Author SHA1 Message Date
6619246346 fix no password 2025-08-06 00:04:26 +02:00
4d127a57e2 inscription utilisateur complète 2025-07-28 17:07:01 +02:00
6e58f328e4 Merge branch 'master' into feat/python 2025-07-26 15:45:22 +02:00
813e0e761f typo 2025-07-26 15:41:38 +02:00
2e62e9782e mattermost canal creation comptes 2025-07-26 15:40:15 +02:00
9f0b8f2e1e paheko standby 2025-07-26 15:39:49 +02:00
fc4adc0fae mattermost first launch 2025-07-26 15:32:54 +02:00
74812fa79a mattermost admin user/pass 2025-07-26 14:45:27 +02:00
490c527d9a smallies 2025-07-26 14:41:31 +02:00
3220d862a6 fix mattermost 2025-07-26 13:52:15 +02:00
51cd89c16d smallies 2025-07-25 15:55:30 +02:00
1936326535 fix default matterport 2025-07-25 15:52:47 +02:00
a630e47bfe fix mattermost pgsql 2025-07-25 15:10:43 +02:00
b4eee312df python 2025-07-25 14:49:46 +02:00
27ca4dfce3 init python 2025-07-24 21:47:54 +02:00
33fc237cb8 fix traefik 2025-07-17 18:26:36 +02:00
ed5ef23ed2 fix traefik 2025-07-17 17:23:13 +02:00
6f33808736 fix vm 2025-07-17 16:13:30 +02:00
nom
477a9155fe upgrade traefik to 3.4.4 2025-07-16 06:43:16 +02:00
bce3b9eff5 Nouveau service spip ! 2025-07-05 00:36:43 +02:00
d506f000a3 grafana: save current dashboards
Add custom dashboards, remove unused ones.
2025-06-25 22:57:36 +02:00
nom
8906974a83 upgrade MM en 10.9.1 2025-06-23 17:23:16 +02:00
nom
c12cafc277 empêche les écho dans interoPahko (pour éviter les mails) 2025-06-20 09:33:55 +02:00
nom
f268f5f5f4 corrige tty sur createUser sur les docker exec maintenenat qu'on est en cron 2025-06-20 09:22:55 +02:00
nom
d8bc48ec3a vire echo "Rien à créer" 2025-06-20 07:01:42 +02:00
3940c3801d fin de la commande Setup 2025-06-19 23:43:58 +02:00
00f9e3ee5f ajout de laposte.net 2025-06-19 21:18:18 +02:00
nom
1bacfd307c vire snappymail de NC car plus supporté actuellemment 2025-06-18 08:10:08 +02:00
nom
8f6913565c rollback, il faut mariadb 11.4 pour les version de NC en cours 2025-06-15 09:57:41 +02:00
nom
62b34e4ac0 mariadb = mariaddb:latest 2025-06-15 09:55:01 +02:00
nom
70c32de959 tente une image mariadb latest sur docker-compose de wp et cloud !
rejoute MARIADB_AUTO_UPGRADE=1 dans docker-compose
2025-06-15 09:52:49 +02:00
nom
3eedd4293b je tente un mariadb:latest pour gitea, pas taper :-p 2025-06-15 09:09:24 +02:00
nom
a2f737eb46 upgrade la base mariadb en auto 2025-06-15 09:03:54 +02:00
nom
82a3440d5a upgrade mariadb to 11.8.2 2025-06-15 08:58:51 +02:00
a3e86ac6ac dmarc sympa 2025-06-11 09:38:19 +02:00
556471d321 doc certbot 2025-06-10 09:45:52 +02:00
9d666afab5 certbot dns chall pour alwaysdata 2025-06-10 09:43:17 +02:00
5eb4ccb58e mastodon 2025-06-06 14:51:27 +02:00
nom
84849b71b1 mets les logs traefik dans un volume
affiches les erreurs 4xx (pour utilisation d'un fail2ban sur le host)
2025-06-06 09:59:41 +02:00
nom
316206140a suppr --no-pdf-header-footer du chromium headless pour impression pdf 2025-05-27 10:46:34 +02:00
nom
7cc7df6ac1 upgrade MM 2025-05-21 19:47:14 +02:00
nom
0d1c13d125 upgrade MM to 10.8 2025-05-20 07:07:34 +02:00
nom
cb9a449882 upgrade de séu sur paheko 2025-05-16 16:16:28 +02:00
nom
678388afaa maj paheko en 1.3.14 2025-05-13 14:13:25 +02:00
016b47774b prometheus: portainer ids pour grafana
Ajout des ids portainer de chaque machine pour générer une url.
2025-05-11 22:00:07 +02:00
nom
6db4d1a5a8 ajout les logs pour les erreurs 404 403 401 renvoyées par le reverse 2025-05-11 09:32:07 +02:00
f54de7a26c update css 2025-05-10 16:52:20 +02:00
nom
75678ca093 enlève l'url en dur 2025-05-10 10:00:42 +02:00
nom
554d7a5ddc upgrade mailServer en 15.0.2 2025-05-10 09:39:17 +02:00
62e75a42f2 mastodon passwords WIP 2025-05-09 16:52:04 +02:00
nom
4a6b575ce0 maj traefik 3.4.0 2025-05-08 18:50:45 +02:00
8d83a2716b correction du mail 2025-05-07 08:12:57 +02:00
nom
4807624dbc corrige url pour kazkouil 2025-05-02 13:05:42 +02:00
nom
b5aa7e9945 je remets sur le git la version de prod1 2025-05-02 11:55:40 +02:00
nom
8d0caad3c7 simplifie la conf prometheus 2025-05-02 11:47:09 +02:00
nom
87b007d4b9 ajout label pour cadvisor 2025-05-02 11:45:39 +02:00
7852e82e74 env cadvisor 2025-04-30 15:23:17 +02:00
9b92276fc1 settings cadvisor 2025-04-30 15:11:24 +02:00
nom
e39ce5518c corrige monitoring (cadvisor passe par traefik) 2025-04-29 23:36:14 +02:00
nom
ea6e48886d maj clean acme.json 2025-04-25 11:07:53 +02:00
4187f4b772 add cadvisor/prometheus/grafana + dashboards 2025-04-24 23:10:06 +02:00
nom
b00916ceba maj nettoye acme en prenant la bonne IP du srv 2025-04-24 14:35:44 +02:00
nom
f95b959bf2 maj nettoyement 2025-04-24 00:27:47 +02:00
nom
609b5c1d62 maj nettoyer_acme_json 2025-04-24 00:16:51 +02:00
nom
a6a20e0dea jq, c'est une tuerie ! 2025-04-24 00:03:30 +02:00
nom
821335e1ca init nettoyage acme.json des certifs LE pour traefik 2025-04-23 22:33:03 +02:00
nom
e31c75d8b1 upgrade MM en 10.7 2025-04-22 16:28:57 +02:00
nom
c041bac532 upgrade traefik 2025-04-21 09:05:18 +02:00
8eb33813d6 date du fichier 2025-04-20 17:57:31 +02:00
faf2e2bc8e add dyn DNS 2025-04-20 10:51:20 +02:00
adc0528c81 peertube 2025-04-20 09:34:17 +02:00
1259857474 add peertube 2025-04-19 17:10:33 +02:00
db684d4ebd sympa ssl 2025-04-19 16:59:09 +02:00
df657bb035 challenge acme traefik 2025-04-19 16:56:03 +02:00
5d8634c8df sympa traefik 2025-04-19 16:40:16 +02:00
c55e984918 Merge branch 'master' of ssh://git.kaz.bzh:2202/KAZ/KazV2 2025-04-19 14:23:14 +02:00
4b95553be0 certificats et webmail 2025-04-19 14:23:06 +02:00
1f8520db90 webmail 2025-04-19 13:49:22 +02:00
9de98c4021 correction bug des alias 2025-04-18 15:16:55 +02:00
85b8048aa9 certificats pour mail et listes 2025-04-18 13:36:44 +02:00
0bf808f0cf mails en minuscule 2025-04-16 19:32:01 +02:00
nom
1609e7725f ajoute AD account 2025-04-11 09:27:46 +02:00
nom
6bd95d1056 on passe de gandi à alwaysdata pour les dns ! 2025-04-11 09:25:05 +02:00
nom
07f8ef8151 maj dns_alwaysdata.sh 2025-04-06 00:38:16 +02:00
nom
aad57eafae maj dns AD 2025-04-05 21:19:36 +02:00
4370436c42 modif pour officeurl 2025-03-25 00:33:01 +01:00
79c52c2067 ajout mastodon 2025-03-24 19:33:04 +01:00
nom
d341122676 init api pour alwaysdata 2025-03-19 19:05:37 +01:00
nom
93a929d291 upgrade mm en 10.6 2025-03-19 10:44:09 +01:00
5d6e46bb37 volumes mastodon 2025-03-17 08:33:18 +01:00
545ed42968 volume images mastodon 2025-03-17 08:31:21 +01:00
53ba95b9d3 env mastodon 2025-03-15 10:26:57 +01:00
61f4629d1f ajout backup mastodon 2025-03-14 22:47:36 +01:00
b7bb45869a mastodon traefik streaming 2025-03-14 17:44:29 +01:00
888c614bdd doc mastodon 2025-03-14 17:37:17 +01:00
16683616c1 suite mastodon 2025-03-14 17:04:23 +01:00
c613184594 bootstrap mastodon 2025-03-14 16:58:02 +01:00
aaf3d9343e paheko fix gd/webp 2025-03-12 09:41:17 +01:00
nom
e8fdead666 workaround pour paheko install gd avec dompdf 2025-03-12 08:46:50 +01:00
b28c04928b ajout webmail 2025-03-10 22:23:54 +01:00
nom
286b2fa144 maj Mailserver 2025-03-10 21:52:15 +01:00
nom
6a7fd829e5 maj Dockerfile pour install gd 2025-03-10 21:48:14 +01:00
nom
5f20548e21 upgrade 2025-03-10 21:05:01 +01:00
b0dd373a00 date 2025-03-10 15:54:01 +01:00
6eec84f2ab refonte exnvoi des mails 2025-03-10 15:53:10 +01:00
nom
ece04aa063 upgrade traefik 2025-03-04 20:24:31 +01:00
1b9de25c4a ajout de l'alias rouncube 2025-03-03 13:24:35 +01:00
de02375bb8 cosmetique 2025-03-03 10:28:42 +01:00
12469c9f2f Integration de la nouvelle version dans le build 2025-03-02 07:42:50 +01:00
e26a1792af modif de la liste des sites possibles 2025-03-01 10:57:02 +01:00
144c3f8dfa mattermost en 10.5 2025-02-26 08:11:21 +01:00
8479756376 modif du heatlcheck 2025-02-25 13:02:41 +01:00
879fb2bae0 ajout vaulwarden 2025-02-17 18:00:03 +01:00
ec57edd77b modif matterPG 2025-02-16 09:32:29 +01:00
8fceb7e6c8 test bodam.fr 2025-02-15 10:57:46 +01:00
2cd446c6df nettoyage 2025-02-14 15:44:31 +01:00
b127b04869 save mysql et postgres 2025-02-13 16:21:28 +01:00
hpl
97414214f8 permettre aux domaines hébergés chez kaz d'utiliser vaultwarden 2025-02-13 15:34:43 +01:00
fa1d5ac349 correction mineure 2025-02-13 15:34:21 +01:00
0843f04bab ajout de dump postgresql et nettoyage d'autres options 2025-02-13 15:22:06 +01:00
hpl
eaaa86ac64 rattrapage jirafeau sur git par rapport à prod 2025-02-13 09:47:12 +01:00
hpl
fb49f567e9 force l'email kaz en minuscule 2025-02-13 09:24:40 +01:00
60a9cbf8fe modif liees au passage en 14.0.0 2025-02-11 13:20:48 +01:00
2e5557e760 modif restart 2025-02-11 13:00:51 +01:00
hpl
ec510e670a suppr libellé du srv de DEV 2025-02-06 11:27:53 +01:00
hpl
34360d7b6e ajout fastapi 2025-02-04 08:24:26 +01:00
0bb82bb51f ajout restartPolicy 2025-01-26 15:00:30 +01:00
d06989c4c6 clean jirafeau 2025-01-26 13:56:26 +01:00
hpl
a97d555362 fermer l'api de jirafeau pour les ip non admin !!!! de dious ! 2025-01-21 20:34:55 +01:00
hpl
c015378405 maj treafik 2025-01-20 16:34:39 +01:00
hpl
03300a9089 maj docker-compose 2025-01-20 01:11:51 +01:00
hpl
19c98e6a8b ajout path 2025-01-15 18:22:03 +01:00
hpl
5d727bd85b on ne restart plus le traefik en création d'orga 2025-01-15 14:29:22 +01:00
hpl
2a03d327a6 connecte le réseau de l'orga à traefik 2025-01-15 10:57:45 +01:00
hpl
5b02701090 fix proprio du répertoire de l'asso dans paheko 2025-01-15 10:24:32 +01:00
hpl
a0a9bdafec maj RC avec la bonne image ! 2025-01-14 14:00:19 +01:00
hpl
e4abafc6ee maj roundcube 2025-01-14 13:54:47 +01:00
hpl
d439fc1fcb plugin facturation : zip au lieu du tar.gz 2025-01-05 18:55:27 +01:00
hpl
658bcd0986 upgrade plugin facturation en 0.12 2025-01-05 18:50:08 +01:00
ebe549f41f proxy 2024-12-27 20:30:13 +01:00
hpl
3089a0b38d upgrade facturation 0.8.7 2024-12-27 13:19:47 +01:00
hpl
7ddd793f29 fixe "export excel" en installanr le module calendar 2024-12-26 13:20:11 +01:00
4652d72c1d fix init postfix 2024-12-24 11:08:06 +01:00
f899570c9a fix init ldap 2024-12-24 10:34:55 +01:00
b426782a59 fix init traefik 2024-12-24 10:22:15 +01:00
3a074ca3c4 fix droit x 2024-12-23 15:16:33 +01:00
4d22bfb766 fix vm vagrant 2024-12-23 14:51:48 +01:00
b73f123b5f ajout .dummy 2024-12-18 21:17:44 +01:00
hpl
e9cf3275ea maj traefik en 3.2.3 2024-12-18 16:53:56 +01:00
hpl
95bf43adef update traefik 2024-12-14 13:10:10 +01:00
cc9bb0e8ac commentaire config.local 2024-12-13 17:48:18 +01:00
a997f06054 raccrochage prod 2024-12-13 17:47:26 +01:00
e016e2ef14 Merge branch 'master' of ssh://git.kaz.bzh:2202/KAZ/KazV2 2024-12-13 17:32:55 +01:00
53859eee4b update gitignore 2024-12-13 17:32:48 +01:00
28284c151e snappymail env 2024-12-13 17:32:26 +01:00
hpl
8be89fa74a ajout logo.svg 2024-12-13 17:31:20 +01:00
6715a03f1e conf sympa 2024-12-13 17:21:25 +01:00
5433830a72 conf postfix 2024-12-13 17:15:02 +01:00
dae1b98c54 confmobilizon 2024-12-13 17:09:53 +01:00
62ff1d823e Merge branch 'master' of ssh://git.kaz.bzh:2202/KAZ/KazV2 2024-12-13 17:08:06 +01:00
92f47e3c97 update docker compose 2024-12-13 17:07:55 +01:00
115 changed files with 33435 additions and 377 deletions

0
.dummy Normal file
View File

5
.gitignore vendored
View File

@@ -31,6 +31,7 @@ DEADJOE
/config/skip-email.txt
/config/updateGit.conf
/config/autorized-domains.txt
/config/domains/
/dockers/*-orga
/dockers/postfix/filter
/dockers/proxy/config/nginx.conf
@@ -51,3 +52,7 @@ DEADJOE
/state
/dockers/paheko/config/config.local.php
/dockers/traefik/conf/conf.local.yml
/dockers/ldap/ldifs/
/dockers/web/autoconfig.yml
# contient un password il faudrait faire plus propre
/dockers/jirafeau/config/config.local.php

View File

@@ -224,10 +224,10 @@ waitUrl () {
# $1 URL to waitfor
# $2 timeout en secondes (optional)
starttime=$(date +%s)
if [[ $(curl --connect-timeout 2 -s -D - "$1" -o /dev/null 2>/dev/null | head -n1) != *[23]0[0-9]* ]]; then
if [[ $(curl -k --connect-timeout 2 -s -D - "$1" -o /dev/null 2>/dev/null | head -n1) != *[23]0[0-9]* ]]; then
printKazMsg "service not available ($1). Please wait..."
echo curl --connect-timeout 2 -s -D - "$1" -o /dev/null \| head -n1
while [[ $(curl --connect-timeout 2 -s -D - "$1" -o /dev/null 2>/dev/null | head -n1) != *[23]0[0-9]* ]]
echo curl -k --connect-timeout 2 -s -D - "$1" -o /dev/null \| head -n1
while [[ $(curl -k --connect-timeout 2 -s -D - "$1" -o /dev/null 2>/dev/null | head -n1) != *[23]0[0-9]* ]]
do
sleep 5
if [ $# -gt 1 ]; then

View File

@@ -85,6 +85,7 @@ done
-e "s|__VIGILO_HOST__|${vigiloHost}|g"\
-e "s|__WEBMAIL_HOST__|${webmailHost}|g"\
-e "s|__CASTOPOD_HOST__|${castopodHost}|g"\
-e "s|__SPIP_HOST__|${spipHost}|g"\
-e "s|__IMAPSYNC_HOST__|${imapsyncHost}|g"\
-e "s|__YAKFORMS_HOST__|${yakformsHost}|g"\
-e "s|__WORDPRESS_HOST__|${wordpressHost}|g"\

View File

@@ -0,0 +1,24 @@
#/bin/bash
# certbot certonly --manual --preferred-challenges=dns --manual-auth-hook certbot-dns-alwaysdata.sh --manual-cleanup-hook certbot-dns-alwaysdata.sh -d "*.kaz.bzh" -d "kaz.bzh"
ALWAYSDATA_TOKEN="TOKEN"
ALWAYSDATA_ACCOUNT="ACCOUNT"
ALWAYSDATA_API="https://api.alwaysdata.com/v1/"
DOMAIN_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" ${ALWAYSDATA_API}/domain/?name=${CERTBOT_DOMAIN} | jq '.[0].id')
add_record(){
RECORD_ID=$(curl -s -X POST -d "{\"domain\":\"${DOMAIN_ID}\", \"type\":\"TXT\", \"name\":\"_acme-challenge\", \"value\":\"${CERTBOT_VALIDATION}\"}" --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/")
}
del_record(){
RECORD_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?name=_acme-challenge&type=TXT&domain=${DOMAIN_ID}" | jq ".[0].id")
curl -s -X DELETE --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/${RECORD_ID}/"
}
if [ -z ${CERTBOT_AUTH_OUTPUT} ]; then
add_record
else
del_record
fi

30
bin/cleanDepot.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
#SIMU=echo
cd /var/lib/docker/volumes/jirafeau_fileData/_data
find links/ -type f -print | while read link ; do
name=$(head -1 "${link}")
#if [[ -z $(head -1 "${link}" | grep "7z$") ]]; then
if [[ -z $(head -9 "${link}" | tail -1) ]]; then
# si c'est pas un 7z on continue
continue;
fi
# recherche le fichier de contenu
filename=$(head -6 "${link}" | tail -1)
l1=$(echo $filename | cut -c 1-8)
l2=$(echo $filename | cut -c 9-16)
l3=$(echo $filename | cut -c 17-24)
l4=$(echo $filename | cut -c 25-32)
# supprime le fichier de contenu
${SIMU} rm -f "files/${l1}/${l2}/${l3}/${l4}/${filename}"
# coupe les branches mortes
${SIMU} rmdir -p "files/${l1}/${l2}/${l3}/${l4}" 2>/dev/null
# supprime le lien
${SIMU} rm -f "${link}"
# log
echo "$(date +%d-%m-%Y-%H-%M-%S) Find ${link} <${name}>"
done

View File

@@ -1,5 +1,17 @@
#!/bin/bash
#Ki: François
#Kan: 2021
#Koi: gestion dockers
# 15/01/2025: Dernière modif by fab: ne pas redémarrer Traefik en cas de créaio d'orga
# Did : 13 fevrier 2025 modif des save en postgres et mysql
# Did : ajout des sauvegardes de mobilizon et mattermost en postgres
# 20/04/2025
# Did : Ajout des sauvegardes de peertube dans les services generaux
# En cas d'absence de postfix, il faut lancer :
# docker network create postfix_mailNet
@@ -104,20 +116,22 @@ updateProxy () {
}
saveDB () {
#attention, soucis avec l'option "-ti" qui ne semble pas rendre la main avec docker exec
containerName=$1
userName=$2
userPass=$3
dbName=$4
backName=$5
#on utilise mysqldump (v=10.5) et mariadb-dump (v>=11.4) pour être certain d'avoir un dump. L'une des 2 lignes fera une erreur
backDbType=$6
#on utilise mysqldump (v=10.5) et mariadb-dump (v>=11.4) et pgdump pour être certain d'avoir un dump. L'une des 3 lignes fera une erreur
# on teste si le backup est pour mysql ou postgres
if [[ -n "${SIMU}" ]] ; then
${SIMU} "docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
${SIMU} "docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
${SIMU} "[ ${backDbType} = mysql ] && docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
${SIMU} "[ ${backDbType} = mysql ] && docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
${SIMU} "[ ${backDbType} = postgres ] && docker exec ${containerName} pg_dumpall --username=${userName} | gzip >${PATH_SAUVE}/${backName}.pgdump.sql.gz"
else
docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
[ ${backDbType} = mysql ] && docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
[ ${backDbType} = mysql ] && docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
[ ${backDbType} = postgres ] && docker exec ${containerName} pg_dumpall --username=${userName} | gzip >${PATH_SAUVE}/${backName}.pgdump.sql.gz
fi
}
@@ -136,7 +150,8 @@ startComposes () {
doComposes "up -d" ${enableMailComposes[@]}
doComposes "up -d" ${enableComposesNeedMail[@]}
updateProxy "on" ${enableComposesNoNeedMail[@]} ${enableComposesNeedMail[@]}
doComposes "up -d" ${enableProxyComposes[@]}
#fab le 15/01/25: on ne redémarre plus le proxy avec container.sh
#doComposes "up -d" ${enableProxyComposes[@]}
for item in "${enableProxyComposes[@]}"; do
[[ -x "${KAZ_COMP_DIR}/${item}/reload.sh" ]] && ${SIMU} "${KAZ_COMP_DIR}/${item}/reload.sh"
done
@@ -178,35 +193,51 @@ saveComposes () {
ethercalc)
#inutile car le backup de /var/lib/docker/volumes/ethercalc_calcDB/_data/dump.rdb est suffisant
;;
#grav)
# ???
#;;
#postfix)
sympa)
echo "save sympa"
saveDB ${sympaDBName} "${sympa_MYSQL_USER}" "${sympa_MYSQL_PASSWORD}" "${sympa_MYSQL_DATABASE}" sympa
saveDB ${sympaDBName} "${sympa_MYSQL_USER}" "${sympa_MYSQL_PASSWORD}" "${sympa_MYSQL_DATABASE}" sympa mysql
;;
web)
# rien à faire (fichiers)
;;
etherpad)
echo "save pad"
saveDB ${etherpadDBName} "${etherpad_MYSQL_USER}" "${etherpad_MYSQL_PASSWORD}" "${etherpad_MYSQL_DATABASE}" etherpad
saveDB ${etherpadDBName} "${etherpad_MYSQL_USER}" "${etherpad_MYSQL_PASSWORD}" "${etherpad_MYSQL_DATABASE}" etherpad mysql
;;
framadate)
echo "save date"
saveDB ${framadateDBName} "${framadate_MYSQL_USER}" "${framadate_MYSQL_PASSWORD}" "${framadate_MYSQL_DATABASE}" framadate
saveDB ${framadateDBName} "${framadate_MYSQL_USER}" "${framadate_MYSQL_PASSWORD}" "${framadate_MYSQL_DATABASE}" framadate mysql
;;
cloud)
echo "save cloud"
saveDB ${nextcloudDBName} "${nextcloud_MYSQL_USER}" "${nextcloud_MYSQL_PASSWORD}" "${nextcloud_MYSQL_DATABASE}" nextcloud
saveDB ${nextcloudDBName} "${nextcloud_MYSQL_USER}" "${nextcloud_MYSQL_PASSWORD}" "${nextcloud_MYSQL_DATABASE}" nextcloud mysql
;;
paheko)
# rien à faire (fichiers)
;;
mattermost)
echo "save mattermost"
saveDB ${mattermostDBName} "${mattermost_MYSQL_USER}" "${mattermost_MYSQL_PASSWORD}" "${mattermost_MYSQL_DATABASE}" mattermost
saveDB matterPG "${mattermost_POSTGRES_USER}" "${mattermost_POSTGRES_PASSWORD}" "${mattermost_POSTGRES_DB}" mattermost postgres
;;
mobilizon)
echo "save mobilizon"
saveDB ${mobilizonDBName} "${mobilizon_POSTGRES_USER}" "${mobilizon_POSTGRES_PASSWORD}" "${mobilizon_POSTGRES_DB}" mobilizon postgres
;;
peertube)
echo "save peertube"
saveDB ${peertubeDBName} "${peertube_POSTGRES_USER}" "${peertube_POSTGRES_PASSWORD}" "${PEERTUBE_DB_HOSTNAME}" peertube postgres
;;
mastodon)
echo "save mastodon"
saveDB ${mastodonDBName} "${mastodon_POSTGRES_USER}" "${mastodon_POSTGRES_PASSWORD}" "${mastodon_POSTGRES_DB}" mastodon postgres
;;
roundcube)
echo "save roundcube"
saveDB ${roundcubeDBName} "${roundcube_MYSQL_USER}" "${roundcube_MYSQL_PASSWORD}" "${roundcube_MYSQL_DATABASE}" roundcube mysql
;;
vaultwarden)
echo "save vaultwarden"
saveDB ${vaultwardenDBName} "${vaultwarden_MYSQL_USER}" "${vaultwarden_MYSQL_PASSWORD}" "${vaultwarden_MYSQL_DATABASE}" vaultwarden mysql
;;
dokuwiki)
# rien à faire (fichiers)
@@ -216,15 +247,15 @@ saveComposes () {
echo "save ${ORGA}"
if grep -q "cloud:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
echo " => cloud"
saveDB "${ORGA}-DB" "${nextcloud_MYSQL_USER}" "${nextcloud_MYSQL_PASSWORD}" "${nextcloud_MYSQL_DATABASE}" "${ORGA}-cloud"
saveDB "${ORGA}-DB" "${nextcloud_MYSQL_USER}" "${nextcloud_MYSQL_PASSWORD}" "${nextcloud_MYSQL_DATABASE}" "${ORGA}-cloud" mysql
fi
if grep -q "agora:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
echo " => mattermost"
saveDB "${ORGA}-DB" "${mattermost_MYSQL_USER}" "${mattermost_MYSQL_PASSWORD}" "${mattermost_MYSQL_DATABASE}" "${ORGA}-mattermost"
saveDB "${ORGA}-DB" "${mattermost_MYSQL_USER}" "${mattermost_MYSQL_PASSWORD}" "${mattermost_MYSQL_DATABASE}" "${ORGA}-mattermost" mysql
fi
if grep -q "wordpress:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
echo " => wordpress"
saveDB "${ORGA}-DB" "${wp_MYSQL_USER}" "${wp_MYSQL_PASSWORD}" "${wp_MYSQL_DATABASE}" "${ORGA}-wordpress"
saveDB "${ORGA}-DB" "${wp_MYSQL_USER}" "${wp_MYSQL_PASSWORD}" "${wp_MYSQL_DATABASE}" "${ORGA}-wordpress" mysql
fi
;;
esac

5
bin/createUser.py Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/python3
from lib.user import create_users_from_file
create_users_from_file()

View File

@@ -41,8 +41,6 @@ cd "${KAZ_ROOT}"
# DOCK_DIR="${KAZ_COMP_DIR}" # ???
SETUP_MAIL="docker exec -ti mailServ setup"
# on détermine le script appelant, le fichier log et le fichier source, tous issus de la même racine
PRG=$(basename $0)
RACINE=${PRG%.sh}
@@ -210,15 +208,6 @@ done
echo "numero,nom,quota_disque,action_auto" > "${TEMP_PAHEKO}"
echo "curl \"https://${paheko_API_USER}:${paheko_API_PASSWORD}@kaz-paheko.kaz.bzh/api/user/import\" -T \"${TEMP_PAHEKO}\"" >> "${CMD_PAHEKO}"
#echo "récupération des login postfix... "
## on stocke les emails et les alias KAZ déjà créés
#(
# ${SETUP_MAIL} email list
# ${SETUP_MAIL} alias list
#) | cut -d ' ' -f 2 | grep @ | sort > "${TFILE_EMAIL}"
# did on supprime le ^M en fin de fichier pour pas faire planter les grep
#dos2unix "${TFILE_EMAIL}"
echo "on récupère tous les emails (secours/alias/kaz) sur le ldap"
FILE_LDIF=/home/sauve/ldap.ldif
/kaz/bin/ldap/ldap_sauve.sh
@@ -226,13 +215,13 @@ gunzip ${FILE_LDIF}.gz -f
grep -aEiorh '([[:alnum:]]+([._-][[:alnum:]]+)*@[[:alnum:]]+([._-][[:alnum:]]+)*\.[[:alpha:]]{2,6})' ${FILE_LDIF} | sort -u > ${TFILE_EMAIL}
echo "récupération des login mattermost... "
docker exec -ti mattermostServ bin/mmctl user list --all | grep ":.*(" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sort > "${TFILE_MM}"
docker exec -i mattermostServ bin/mmctl user list --all | grep ":.*(" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sort > "${TFILE_MM}"
dos2unix "${TFILE_MM}"
echo "done"
# se connecter à l'agora pour ensuite pouvoir passer toutes les commandes mmctl
echo "docker exec -ti mattermostServ bin/mmctl auth login ${httpProto}://${URL_AGORA} --name local-server --username ${mattermost_user} --password ${mattermost_pass}" | tee -a "${CMD_INIT}"
echo "docker exec -i mattermostServ bin/mmctl auth login ${httpProto}://${URL_AGORA} --name local-server --username ${mattermost_user} --password ${mattermost_pass}" | tee -a "${CMD_INIT}"
# vérif des emails
regex="^(([A-Za-z0-9]+((\.|\-|\_|\+)?[A-Za-z0-9]?)*[A-Za-z0-9]+)|[A-Za-z0-9]+)@(([A-Za-z0-9]+)+((\.|\-|\_)?([A-Za-z0-9]+)+)*)+\.([A-Za-z]{2,})+$"
@@ -287,7 +276,8 @@ while read ligne; do
PASSWORD=$(awk -F ";" '{print $16}' <<< "${ligne}" | xargs)
IDENT_KAZ=$(unaccent utf8 "${PRENOM,,}.${NOM,,}")
EMAIL_SOUHAITE=${tab_email[EMAIL_SOUHAITE]}
#email en minuscule
EMAIL_SOUHAITE=${tab_email[EMAIL_SOUHAITE],,}
EMAIL_SECOURS=${tab_email[EMAIL_SECOURS]}
echo -e "${NL}***************************** traitement de ${ligne}" | tee -a "${LOG}"
@@ -378,8 +368,6 @@ while read ligne; do
else
SEND_MSG_CREATE=true
echo "${EMAIL_SOUHAITE} n'existe pas" | tee -a "${LOG}"
echo "${SETUP_MAIL} email add ${EMAIL_SOUHAITE} ${PASSWORD}" | tee -a "${CMD_LOGIN}"
echo "${SETUP_MAIL} quota set ${EMAIL_SOUHAITE} ${QUOTA}G" | tee -a "${CMD_LOGIN}"
# LDAP, à tester
user=$(echo ${EMAIL_SOUHAITE} | awk -F '@' '{print $1}')
domain=$(echo ${EMAIL_SOUHAITE} | awk -F '@' '{print $2}')
@@ -596,11 +584,11 @@ userPassword: {CRYPT}${pass}\n\n' | ldapmodify -c -H ldap://${LDAP_IP} -D \"cn=$
echo "${IDENT_KAZ} existe déjà sur mattermost" | tee -a "${LOG}"
else
# on créé le compte mattermost
echo "docker exec -ti mattermostServ bin/mmctl user create --email ${EMAIL_SOUHAITE} --username ${IDENT_KAZ} --password ${PASSWORD}" | tee -a "${CMD_LOGIN}"
echo "docker exec -i mattermostServ bin/mmctl user create --email ${EMAIL_SOUHAITE} --username ${IDENT_KAZ} --password ${PASSWORD}" | tee -a "${CMD_LOGIN}"
# et enfin on ajoute toujours le user à l'équipe KAZ et aux 2 channels publiques
echo "docker exec -ti mattermostServ bin/mmctl team users add kaz ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
echo "docker exec -ti mattermostServ bin/mmctl channel users add kaz:une-question--un-soucis ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
echo "docker exec -ti mattermostServ bin/mmctl channel users add kaz:cafe-du-commerce--ouvert-2424h ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
echo "docker exec -i mattermostServ bin/mmctl team users add kaz ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
echo "docker exec -i mattermostServ bin/mmctl channel users add kaz:une-question--un-soucis ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
echo "docker exec -i mattermostServ bin/mmctl channel users add kaz:cafe-du-commerce--ouvert-2424h ${EMAIL_SOUHAITE}" | tee -a "${CMD_LOGIN}"
NB_SERVICES_BASE=$((NB_SERVICES_BASE+1))
fi
@@ -608,10 +596,10 @@ userPassword: {CRYPT}${pass}\n\n' | ldapmodify -c -H ldap://${LDAP_IP} -D \"cn=$
# l'équipe existe t-elle déjà ?
nb=$(docker exec mattermostServ bin/mmctl team list | grep -w "${EQUIPE_AGORA}" | wc -l)
if [ "${nb}" == "0" ];then # non, on la créé en mettant le user en admin de l'équipe
echo "docker exec -ti mattermostServ bin/mmctl team create --name ${EQUIPE_AGORA} --display_name ${EQUIPE_AGORA} --email ${EMAIL_SOUHAITE}" --private | tee -a "${CMD_INIT}"
echo "docker exec -i mattermostServ bin/mmctl team create --name ${EQUIPE_AGORA} --display_name ${EQUIPE_AGORA} --email ${EMAIL_SOUHAITE}" --private | tee -a "${CMD_INIT}"
fi
# puis ajouter le user à l'équipe
echo "docker exec -ti mattermostServ bin/mmctl team users add ${EQUIPE_AGORA} ${EMAIL_SOUHAITE}" | tee -a "${CMD_INIT}"
echo "docker exec -i mattermostServ bin/mmctl team users add ${EQUIPE_AGORA} ${EMAIL_SOUHAITE}" | tee -a "${CMD_INIT}"
fi
if [ -n "${CREATE_ORGA_SERVICES}" ]; then
@@ -628,16 +616,16 @@ userPassword: {CRYPT}${pass}\n\n' | ldapmodify -c -H ldap://${LDAP_IP} -D \"cn=$
# TODO : utiliser liste sur dev également
# on inscrit le user sur sympa, à la liste infos@${domain_sympa}
# docker exec -ti sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=https://listes.kaz.sns/sympasoap --trusted_application=SOAP_USER --trusted_application_password=SOAP_PASSWORD --proxy_vars="USER_EMAIL=contact1@kaz.sns" --service=which
# docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=https://listes.kaz.sns/sympasoap --trusted_application=SOAP_USER --trusted_application_password=SOAP_PASSWORD --proxy_vars="USER_EMAIL=contact1@kaz.sns" --service=which
if [[ "${mode}" = "dev" ]]; then
echo "# DEV, on teste l'inscription à sympa"| tee -a "${CMD_SYMPA}"
LISTMASTER=$(echo ${sympa_LISTMASTERS} | cut -d',' -f1)
echo "docker exec -ti sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
echo "docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
else
echo "# PROD, on inscrit à sympa"| tee -a "${CMD_SYMPA}"
LISTMASTER=$(echo ${sympa_LISTMASTERS} | cut -d',' -f1)
echo "docker exec -ti sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
echo "docker exec -ti sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SECOURS}\"" | tee -a "${CMD_SYMPA}"
echo "docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
echo "docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SECOURS}\"" | tee -a "${CMD_SYMPA}"
fi
if [ "${service[ADMIN_ORGA]}" == "O" ]; then
@@ -759,7 +747,7 @@ ${MAIL_KAZ}
EOF" | tee -a "${CMD_MSG}"
echo " # on envoie la confirmation d'inscription sur l'agora " | tee -a "${CMD_MSG}"
echo "docker exec -ti mattermostServ bin/mmctl post create kaz:Creation-Comptes --message \"${MAIL_KAZ}\"" | tee -a "${CMD_MSG}"
echo "docker exec -i mattermostServ bin/mmctl post create kaz:Creation-Comptes --message \"${MAIL_KAZ}\"" | tee -a "${CMD_MSG}"
# fin des inscriptions
done <<< "${ALL_LINES}"

View File

@@ -1,6 +1,11 @@
#!/bin/bash
#/bin/bash
# list/ajout/supprime/ un sous-domaine
#koi: gestion des records dns sur AlwaysData
#ki: fanch&gaël&fab
#kan: 06/04/2025
#doc: https://api.alwaysdata.com/v1/record/doc/
#doc: https://help.alwaysdata.com/fr/api/
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
@@ -15,6 +20,7 @@ export ETC_HOSTS="/etc/hosts"
# no more export in .env
export $(set | grep "domain=")
#TODO: récupérer la liste des services kaz au lieu des les écrire en dur
declare -a forbidenName
forbidenName=(${calcHost} calc ${cloudHost} bureau ${dateHost} date ${dokuwikiHost} dokuwiki ${fileHost} file ${ldapHost} ${pahekoHost} ${gitHost} ${gravHost} ${matterHost} ${officeHost} collabora ${padHost} ${sympaHost} listes ${webmailHost} ${wordpressHost} www ${vigiloHost} form)
@@ -31,6 +37,15 @@ usage(){
exit 1
}
. "${KAZ_KEY_DIR}/env-alwaysdata"
if [[ -z "${ALWAYSDATA_TOKEN}" ]] ; then
echo "no ALWAYSDATA_TOKEN set in ${KAZ_KEY_DIR}/env-alwaysdata"
usage
fi
DOMAIN_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" ${ALWAYSDATA_API}/domain/?name=${domain} | jq '.[0].id')
for ARG in $@
do
case "${ARG}" in
@@ -60,78 +75,15 @@ if [ -z "${CMD}" ]; then
usage
fi
. "${KAZ_KEY_DIR}/env-gandi"
if [[ -z "${GANDI_KEY}" ]] ; then
echo
echo "no GANDI_KEY set in ${KAZ_KEY_DIR}/env-gandi"
usage
fi
waitNet () {
if [[ "${domain}" = "kaz.local" ]]; then
return
fi
### wait when error code 503
if [[ $(curl -H "authorization: Apikey ${GANDI_KEY}" --connect-timeout 2 -s -D - "${GANDI_API}" -o /dev/null 2>/dev/null | head -n1) != *200* ]]; then
echo "DNS not available. Please wait..."
while [[ $(curl -H "authorization: Apikey ${GANDI_KEY}" --connect-timeout 2 -s -D - "${GANDI_API}" -o /dev/null 2>/dev/null | head -n1) != *200* ]]
do
sleep 5
done
exit
fi
}
list(){
if [[ "${domain}" = "kaz.local" ]]; then
grep --perl-regex "^${IP}\s.*${domain}" "${ETC_HOSTS}" 2> /dev/null | sed -e "s|^${IP}\s*\([0-9a-z.-]${domain}\)$|\1|g"
return
fi
waitNet
trap 'rm -f "${TMPFILE}"' EXIT
TMPFILE="$(mktemp)" || exit 1
if [[ -n "${SIMU}" ]] ; then
${SIMU} curl -X GET "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}"
else
curl -X GET "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}" 2>/dev/null | \
sed "s/,{/\n/g" | \
sed 's/.*rrset_name":"\([^"]*\)".*rrset_values":\["\([^"]*\)".*/\1:\2/g'| \
grep -v '^[_@]'| \
grep -e ":${domain}\.*$" -e ":prod[0-9]*$" > ${TMPFILE}
fi
if [ $# -lt 1 ]; then
cat ${TMPFILE}
else
for ARG in $@
do
cat ${TMPFILE} | grep "${ARG}.*:"
done
fi
TARGET=$@
LISTE=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}&type=CNAME&name=${TARGET}" | jq '.[] | "\(.name):\(.value)"')
echo ${LISTE}
}
saveDns () {
for ARG in $@ ; do
if [[ "${ARG}" =~ .local$ ]] ; then
echo "${PRG}: old fasion style (remove .local at the end)"
usage;
fi
if [[ "${ARG}" =~ .bzh$ ]] ; then
echo "${PRG}: old fasion style (remove .bzh at the end)"
usage;
fi
if [[ "${ARG}" =~ .dev$ ]] ; then
echo "${PRG}: old fasion style (remove .dev at the end)"
usage;
fi
done
if [[ "${domain}" = "kaz.local" ]]; then
return
fi
waitNet
${SIMU} curl -X POST "${GANDI_API}/snapshots" -H "authorization: Apikey ${GANDI_KEY}" 2>/dev/null
mkdir -p /root/dns
${SIMU} curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}" -o /root/dns/dns_save_$(date +'%Y%m%d%H%M%S')
}
badName(){
@@ -154,28 +106,14 @@ add(){
echo "can't manage '${ARG}'. Use -f option"
continue
fi
case "${domain}" in
kaz.local )
if grep -q --perl-regex "^${IP}.*[ \t]${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null ; then
break
fi
if grep -q --perl-regex "^${IP}[ \t]" "${ETC_HOSTS}" 2> /dev/null ; then
${SIMU} sudo sed -i -e "0,/^${IP}[ \t]/s/^\(${IP}[ \t]\)/\1${ARG}.${domain} /g" "${ETC_HOSTS}"
else
${SIMU} sudo sed -i -e "$ a ${IP}\t${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null
fi
;;
*)
${SIMU} curl -X POST "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}" -H 'content-type: application/json' -d '{"rrset_type":"CNAME", "rrset_name":"'${ARG}'", "rrset_values":["'${site}'"]}'
echo
;;
esac
${SIMU} curl -s -X POST -d "{\"domain\":\"${DOMAIN_ID}\", \"type\":\"CNAME\", \"name\":\"${ARG}\", \"value\":\"${site}.${domain}\"}" --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/"
ADDED+=("${ARG}")
done
echo "Domains added to ${domain}: ${ADDED[@]}"
}
del(){
if [ $# -lt 1 ]; then
exit
fi
@@ -187,23 +125,11 @@ del(){
echo "can't manage '${ARG}'. Use -f option"
continue
fi
case "${domain}" in
kaz.local )
if !grep -q --perl-regex "^${IP}.*[ \t]${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null ; then
break
fi
${SIMU} sudo sed -i -e "/^${IP}[ \t]*${ARG}.${domain}[ \t]*$/d" \
-e "s|^\(${IP}.*\)[ \t]${ARG}.${domain}|\1|g" "${ETC_HOSTS}"
;;
* )
${SIMU} curl -X DELETE "${GANDI_API}/records/${ARG}" -H "authorization: Apikey ${GANDI_KEY}"
echo
;;
esac
RECORD_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?name=${ARG}&type=CNAME&domain=${DOMAIN_ID}" | jq ".[] | select(.name==\"${ARG}\").id")
${SIMU} curl -s -X DELETE --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/${RECORD_ID}/"
REMOVED+=("${ARG}")
done
echo "Domains removed from ${domain}: ${REMOVED[@]}"
}
#echo "CMD: ${CMD} $*"
${CMD} $*

135
bin/dns_alwaysdata.sh Executable file
View File

@@ -0,0 +1,135 @@
#/bin/bash
#koi: gestion des records dns sur AlwaysData
#ki: fanch&gaël&fab
#kan: 06/04/2025
#doc: https://api.alwaysdata.com/v1/record/doc/
#doc: https://help.alwaysdata.com/fr/api/
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
cd "${KAZ_ROOT}"
export PRG="$0"
export IP="127.0.0.1"
export ETC_HOSTS="/etc/hosts"
# no more export in .env
export $(set | grep "domain=")
#TODO: récupérer la liste des services kaz au lieu des les écrire en dur
declare -a forbidenName
forbidenName=(${calcHost} calc ${cloudHost} bureau ${dateHost} date ${dokuwikiHost} dokuwiki ${fileHost} file ${ldapHost} ${pahekoHost} ${gitHost} ${gravHost} ${matterHost} ${officeHost} collabora ${padHost} ${sympaHost} listes ${webmailHost} ${wordpressHost} www ${vigiloHost} form)
export FORCE="NO"
export CMD=""
export SIMU=""
usage(){
echo "Usage: ${PRG} list [sub-domain...]"
echo " ${PRG} [-n] [-f] {add/del} sub-domain..."
echo " -h help"
echo " -n simulation"
echo " -f force protected domain"
exit 1
}
. "${KAZ_KEY_DIR}/env-alwaysdata"
if [[ -z "${ALWAYSDATA_TOKEN}" ]] ; then
echo "no ALWAYSDATA_TOKEN set in ${KAZ_KEY_DIR}/env-alwaysdata"
usage
fi
DOMAIN_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" ${ALWAYSDATA_API}/domain/?name=${domain} | jq '.[0].id')
for ARG in $@
do
case "${ARG}" in
'-h' | '-help' )
usage
;;
'-f' )
shift
export FORCE="YES"
;;
'-n' )
shift
export SIMU="echo"
;;
'list'|'add'|'del' )
shift
CMD="${ARG}"
break
;;
* )
usage
;;
esac
done
if [ -z "${CMD}" ]; then
usage
fi
list(){
TARGET=$@
LISTE=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}&type=CNAME&name=${TARGET}" | jq '.[] | "\(.name):\(.value)"')
echo ${LISTE}
}
saveDns () {
mkdir -p /root/dns
${SIMU} curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}" -o /root/dns/dns_save_$(date +'%Y%m%d%H%M%S')
}
badName(){
[[ -z "$1" ]] && return 0;
for item in "${forbidenName[@]}"; do
[[ "${item}" == "$1" ]] && [[ "${FORCE}" == "NO" ]] && return 0
done
return 1
}
add(){
if [ $# -lt 1 ]; then
exit
fi
saveDns $@
declare -a ADDED
for ARG in $@
do
if badName "${ARG}" ; then
echo "can't manage '${ARG}'. Use -f option"
continue
fi
${SIMU} curl -s -X POST -d "{\"domain\":\"${DOMAIN_ID}\", \"type\":\"CNAME\", \"name\":\"${ARG}\", \"value\":\"${site}.${domain}\"}" --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/"
ADDED+=("${ARG}")
done
echo "Domains added to ${domain}: ${ADDED[@]}"
}
del(){
if [ $# -lt 1 ]; then
exit
fi
saveDns $@
declare -a REMOVED
for ARG in $@
do
if badName "${ARG}" ; then
echo "can't manage '${ARG}'. Use -f option"
continue
fi
RECORD_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?name=${ARG}&type=CNAME&domain=${DOMAIN_ID}" | jq ".[] | select(.name==\"${ARG}\").id")
${SIMU} curl -s -X DELETE --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/${RECORD_ID}/"
REMOVED+=("${ARG}")
done
echo "Domains removed from ${domain}: ${REMOVED[@]}"
}
${CMD} $*

209
bin/dns_gandi.sh Executable file
View File

@@ -0,0 +1,209 @@
#!/bin/bash
# list/ajout/supprime/ un sous-domaine
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
cd "${KAZ_ROOT}"
export PRG="$0"
export IP="127.0.0.1"
export ETC_HOSTS="/etc/hosts"
# no more export in .env
export $(set | grep "domain=")
declare -a forbidenName
forbidenName=(${calcHost} calc ${cloudHost} bureau ${dateHost} date ${dokuwikiHost} dokuwiki ${fileHost} file ${ldapHost} ${pahekoHost} ${gitHost} ${gravHost} ${matterHost} ${officeHost} collabora ${padHost} ${sympaHost} listes ${webmailHost} ${wordpressHost} www ${vigiloHost} form)
export FORCE="NO"
export CMD=""
export SIMU=""
usage(){
echo "Usage: ${PRG} list [sub-domain...]"
echo " ${PRG} [-n] [-f] {add/del} sub-domain..."
echo " -h help"
echo " -n simulation"
echo " -f force protected domain"
exit 1
}
for ARG in $@
do
case "${ARG}" in
'-h' | '-help' )
usage
;;
'-f' )
shift
export FORCE="YES"
;;
'-n' )
shift
export SIMU="echo"
;;
'list'|'add'|'del' )
shift
CMD="${ARG}"
break
;;
* )
usage
;;
esac
done
if [ -z "${CMD}" ]; then
usage
fi
. "${KAZ_KEY_DIR}/env-gandi"
if [[ -z "${GANDI_KEY}" ]] ; then
echo
echo "no GANDI_KEY set in ${KAZ_KEY_DIR}/env-gandi"
usage
fi
waitNet () {
if [[ "${domain}" = "kaz.local" ]]; then
return
fi
### wait when error code 503
if [[ $(curl -H "authorization: Apikey ${GANDI_KEY}" --connect-timeout 2 -s -D - "${GANDI_API}" -o /dev/null 2>/dev/null | head -n1) != *200* ]]; then
echo "DNS not available. Please wait..."
while [[ $(curl -H "authorization: Apikey ${GANDI_KEY}" --connect-timeout 2 -s -D - "${GANDI_API}" -o /dev/null 2>/dev/null | head -n1) != *200* ]]
do
sleep 5
done
exit
fi
}
list(){
if [[ "${domain}" = "kaz.local" ]]; then
grep --perl-regex "^${IP}\s.*${domain}" "${ETC_HOSTS}" 2> /dev/null | sed -e "s|^${IP}\s*\([0-9a-z.-]${domain}\)$|\1|g"
return
fi
waitNet
trap 'rm -f "${TMPFILE}"' EXIT
TMPFILE="$(mktemp)" || exit 1
if [[ -n "${SIMU}" ]] ; then
${SIMU} curl -X GET "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}"
else
curl -X GET "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}" 2>/dev/null | \
sed "s/,{/\n/g" | \
sed 's/.*rrset_name":"\([^"]*\)".*rrset_values":\["\([^"]*\)".*/\1:\2/g'| \
grep -v '^[_@]'| \
grep -e ":${domain}\.*$" -e ":prod[0-9]*$" > ${TMPFILE}
fi
if [ $# -lt 1 ]; then
cat ${TMPFILE}
else
for ARG in $@
do
cat ${TMPFILE} | grep "${ARG}.*:"
done
fi
}
saveDns () {
for ARG in $@ ; do
if [[ "${ARG}" =~ .local$ ]] ; then
echo "${PRG}: old fasion style (remove .local at the end)"
usage;
fi
if [[ "${ARG}" =~ .bzh$ ]] ; then
echo "${PRG}: old fasion style (remove .bzh at the end)"
usage;
fi
if [[ "${ARG}" =~ .dev$ ]] ; then
echo "${PRG}: old fasion style (remove .dev at the end)"
usage;
fi
done
if [[ "${domain}" = "kaz.local" ]]; then
return
fi
waitNet
${SIMU} curl -X POST "${GANDI_API}/snapshots" -H "authorization: Apikey ${GANDI_KEY}" 2>/dev/null
}
badName(){
[[ -z "$1" ]] && return 0;
for item in "${forbidenName[@]}"; do
[[ "${item}" == "$1" ]] && [[ "${FORCE}" == "NO" ]] && return 0
done
return 1
}
add(){
if [ $# -lt 1 ]; then
exit
fi
saveDns $@
declare -a ADDED
for ARG in $@
do
if badName "${ARG}" ; then
echo "can't manage '${ARG}'. Use -f option"
continue
fi
case "${domain}" in
kaz.local )
if grep -q --perl-regex "^${IP}.*[ \t]${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null ; then
break
fi
if grep -q --perl-regex "^${IP}[ \t]" "${ETC_HOSTS}" 2> /dev/null ; then
${SIMU} sudo sed -i -e "0,/^${IP}[ \t]/s/^\(${IP}[ \t]\)/\1${ARG}.${domain} /g" "${ETC_HOSTS}"
else
${SIMU} sudo sed -i -e "$ a ${IP}\t${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null
fi
;;
*)
${SIMU} curl -X POST "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}" -H 'content-type: application/json' -d '{"rrset_type":"CNAME", "rrset_name":"'${ARG}'", "rrset_values":["'${site}'"]}'
echo
;;
esac
ADDED+=("${ARG}")
done
echo "Domains added to ${domain}: ${ADDED[@]}"
}
del(){
if [ $# -lt 1 ]; then
exit
fi
saveDns $@
declare -a REMOVED
for ARG in $@
do
if badName "${ARG}" ; then
echo "can't manage '${ARG}'. Use -f option"
continue
fi
case "${domain}" in
kaz.local )
if !grep -q --perl-regex "^${IP}.*[ \t]${ARG}.${domain}" "${ETC_HOSTS}" 2> /dev/null ; then
break
fi
${SIMU} sudo sed -i -e "/^${IP}[ \t]*${ARG}.${domain}[ \t]*$/d" \
-e "s|^\(${IP}.*\)[ \t]${ARG}.${domain}|\1|g" "${ETC_HOSTS}"
;;
* )
${SIMU} curl -X DELETE "${GANDI_API}/records/${ARG}" -H "authorization: Apikey ${GANDI_KEY}"
echo
;;
esac
REMOVED+=("${ARG}")
done
echo "Domains removed from ${domain}: ${REMOVED[@]}"
}
#echo "CMD: ${CMD} $*"
${CMD} $*

176
bin/dynDNS.sh Executable file
View File

@@ -0,0 +1,176 @@
#!/bin/bash
# nohup /kaz/bin/dynDNS.sh &
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
# no more export in .env
export $(set | grep "domain=")
cd "${KAZ_ROOT}"
export PRG="$0"
export MYHOST="${site}"
MYIP_URL="https://kaz.bzh/myip.php"
DNS_IP=""
DELAI_WAIT=10 # DNS occupé
DELAI_GET=5 # min entre 2 requêtes
DELAI_CHANGE=3600 # propagation 1h
DELAI_NO_CHANGE=300 # pas de changement 5 min
BOLD='\e[1m'
RED='\e[0;31m'
GREEN='\e[0;32m'
YELLOW='\e[0;33m'
BLUE='\e[0;34m'
MAGENTA='\e[0;35m'
CYAN='\e[0;36m'
NC='\e[0m' # No Color
NL='
'
export VERBOSE=""
export SIMU=""
usage(){
echo "Usage: ${PRG} list [sub-domain...]"
echo " -h help"
echo " -v verbose"
echo " -n simulation"
exit 1
}
#. "${KAZ_KEY_DIR}/env-gandi"
. "${KAZ_KEY_DIR}/env-alwaysdata"
if [[ -z "${ALWAYSDATA_TOKEN}" ]] ; then
echo "no ALWAYSDATA_TOKEN set in ${KAZ_KEY_DIR}/env-alwaysdata"
usage
fi
DOMAIN_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" ${ALWAYSDATA_API}/domain/?name=${domain} | jq '.[0].id')
if [[ -z "${DOMAIN_ID}" ]] ; then
echo "no DOMAIN_ID give by alwaysdata"
usage
fi
# if [[ -z "${GANDI_KEY}" ]] ; then
# echo
# echo "no GANDI_KEY set in ${KAZ_KEY_DIR}/env-gandi"
# usage
# exit
# fi
for ARG in $@
do
case "${ARG}" in
'-h' | '-help' )
usage
;;
'-v' )
shift
export VERBOSE=":"
;;
'-n' )
shift
export SIMU="echo"
;;
* )
usage
;;
esac
done
log () {
echo -e "${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : $*"
}
simu () {
echo -e "${YELLOW}$(date +%d-%m-%Y-%H-%M-%S)${NC} : $*"
}
cmdWait () {
#ex gandi
#curl -H "authorization: Apikey ${GANDI_KEY}" --connect-timeout 2 -s -D - -o /dev/null "${GANDI_API}" 2>/dev/null
curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" --connect-timeout 2 -D - -o /dev/null "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}&type=CNAME&name=${TARGET}" 2>/dev/null
}
waitNet () {
### wait when error code 503
if [[ $(cmdWait | head -n1) != *200* ]]; then
log "DNS not available. Please wait..."
while [[ $(cmdWait | head -n1) != *200* ]]; do
[[ -z "${VERBOSE}" ]] || simu curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" --connect-timeout 2 -D - -o /dev/null "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}&type=CNAME&name=${TARGET}"
sleep "${DELAI_WAIT}"
done
exit
fi
}
getDNS () {
# curl -s -X GET "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}"|
# sed "s/,{/\n/g"|
# sed 's/.*rrset_name":"\([^"]*\)".*rrset_values":\["\([^"]*\)".*/\1:\2/g'|
# grep -e "^${MYHOST}:"|
# sed "s/^${MYHOST}://g" |
# tr -d '\n\t\r '
${SIMU} curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}&type=A&name=${MYHOST}" | jq '.[] | "\(.value)"' | tr -d '"'
}
saveDns () {
mkdir -p /root/dns
${SIMU} curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?domain=${DOMAIN_ID}" -o /root/dns/dns_save_$(date +'%Y%m%d%H%M%S')
}
setDNS () {
saveDns
# curl -s -X POST "${GANDI_API}/records" -H "authorization: Apikey ${GANDI_KEY}" -H 'content-type: application/json' -d '{"rrset_type":"A", "rrset_name":"'${MYHOST}'", "rrset_values":["'${IP}'"]}'
${SIMU} curl -s -X POST -d "{\"domain\":\"${DOMAIN_ID}\", \"type\":\"A\", \"name\":\"${MYHOST}\", \"value\":\"${IP}\"}" --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/"
}
while :; do
sleep "${DELAI_GET}"
IP=$(curl -s "${MYIP_URL}" | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | tr -d '\n\t\r ')
if ! [[ ${IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log "BAB IP ${IP}" ; continue
fi
if [ -z "${DNS_IP}" ]; then
# Variable pas encore initialisée
waitNet
DNS_IP=$(getDNS)
if [ -z "${DNS_IP}" ]; then
# C'est la première fois que le site est en prod
log "set ${MYHOST} : ${IP}"
setDNS
DNS_IP=$(getDNS)
log "DNS set ${MYHOST}:${IP} (=${DNS_IP})"
sleep "${DELAI_CHANGE}"
continue
fi
fi
if [ "${DNS_IP}" != "${IP}" ]; then
log "${MYHOST} : ${DNS_IP} must change to ${IP}"
# Changement d'adresse
waitNet
#curl -s -X DELETE "${GANDI_API}/records/${MYHOST}" -H "authorization: Apikey ${GANDI_KEY}"
RECORD_ID=$(curl -s -X GET --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/?name=${MYHOST}&type=A&domain=${DOMAIN_ID}" | jq ".[] | select(.name==\"${MYHOST}\").id")
${SIMU} curl -s -X DELETE --basic --user "${ALWAYSDATA_TOKEN} account=${ALWAYSDATA_ACCOUNT}:" "${ALWAYSDATA_API}/record/${RECORD_ID}/"
setDNS
DNS_IP=$(getDNS)
log "DNS reset ${MYHOST}:${IP} (=${DNS_IP})"
sleep "${DELAI_CHANGE}"
else
log "OK ${MYHOST}:${DNS_IP} / ${IP}"
sleep ${DELAI_NO_CHANGE}
fi
done

View File

@@ -23,7 +23,7 @@ PRG=$(basename $0)
# TEMPO_ACTION_STOP=2 # Lors de redémarrage avec tempo, on attend après le stop
# TEMPO_ACTION_START=60 # Lors de redémarrage avec tempo, avant de reload le proxy
# DEFAULTCONTAINERS="cloud agora wp wiki office paheko castopod"
# DEFAULTCONTAINERS="cloud agora wp wiki office paheko castopod spip"
# APPLIS_PAR_DEFAUT="tasks calendar contacts bookmarks mail richdocuments external drawio snappymail ransomware_protection" #rainloop richdocumentscode
@@ -42,16 +42,16 @@ CONTAINERS_TYPES=
declare -A DockerServNames # le nom des containers correspondant
DockerServNames=( [cloud]="${nextcloudServName}" [agora]="${mattermostServName}" [wiki]="${dokuwikiServName}" [wp]="${wordpressServName}" [office]="${officeServName}" [paheko]="${pahekoServName}" [castopod]="${castopodServName}" )
DockerServNames=( [cloud]="${nextcloudServName}" [agora]="${mattermostServName}" [wiki]="${dokuwikiServName}" [wp]="${wordpressServName}" [office]="${officeServName}" [paheko]="${pahekoServName}" [castopod]="${castopodServName}" [spip]="${spipServName}" )
declare -A FilterLsVolume # Pour trouver quel volume appartient à quel container
FilterLsVolume=( [cloud]="cloudMain" [agora]="matterConfig" [wiki]="wikiConf" [wp]="wordpress" [castopod]="castopodMedia" )
FilterLsVolume=( [cloud]="cloudMain" [agora]="matterConfig" [wiki]="wikiConf" [wp]="wordpress" [castopod]="castopodMedia" [spip]="spip")
declare -A composeDirs # Le nom du repertoire compose pour le commun
composeDirs=( [cloud]="cloud" [agora]="mattermost" [wiki]="dokuwiki" [office]="collabora" [paheko]="paheko" [castopod]="castopod" )
composeDirs=( [cloud]="cloud" [agora]="mattermost" [wiki]="dokuwiki" [office]="collabora" [paheko]="paheko" [castopod]="castopod" [spip]="spip")
declare -A serviceNames # Le nom du du service dans le dockerfile d'orga
serviceNames=( [cloud]="cloud" [agora]="agora" [wiki]="dokuwiki" [wp]="wordpress" [office]="collabora" [castopod]="castopod")
serviceNames=( [cloud]="cloud" [agora]="agora" [wiki]="dokuwiki" [wp]="wordpress" [office]="collabora" [castopod]="castopod" [spip]="spip")
declare -A subScripts
subScripts=( [cloud]="manageCloud.sh" [agora]="manageAgora.sh" [wiki]="manageWiki.sh" [wp]="manageWp.sh" [castopod]="manageCastopod.sh" )
@@ -93,6 +93,7 @@ CONTAINERS_TYPES
-office Les collabora
-paheko Le paheko
-castopod Les castopod
-spip Les spip
COMMANDES (on peut en mettre plusieurs dans l'ordre souhaité)
-I|--install L'initialisation du container
@@ -322,7 +323,7 @@ _reloadProxy() {
availableProxyComposes=($(getList "${KAZ_CONF_DIR}/container-proxy.list"))
for item in "${availableProxyComposes[@]}"; do
${SIMU} ${KAZ_COMP_DIR}/${item}/reload.sh
[ "${item}" = "proxy" ] && ${SIMU} ${KAZ_COMP_DIR}/${item}/reload.sh
done
}
@@ -551,6 +552,8 @@ for ARG in "$@"; do
CONTAINERS_TYPES="${CONTAINERS_TYPES} paheko" ;;
'-pod'|'--pod'|'-castopod'|'--castopod')
CONTAINERS_TYPES="${CONTAINERS_TYPES} castopod" ;;
'-spip')
CONTAINERS_TYPES="${CONTAINERS_TYPES} spip" ;;
'-t' )
COMMANDS="${COMMANDS} RESTART-COMPOSE" ;;
'-r' )

View File

@@ -1,5 +1,7 @@
#!/bin/bash
# gestion des utilisateurs de kaz ( mail, cloud général, mattermost )
# Ki : Did
# koi : gestion globale des users Kaz mais aussi les users d'autres domaines hébergés
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. $KAZ_ROOT/bin/.commonFunctions.sh
@@ -8,7 +10,7 @@ setKazVars
. $DOCKERS_ENV
. $KAZ_ROOT/secret/SetAllPass.sh
VERSION="5-12-2024"
VERSION="18-05-2025"
PRG=$(basename $0)
RACINE=$(echo $PRG | awk '{print $1}')
IFS=' '
@@ -26,7 +28,7 @@ LISTMASTER=$(echo ${sympa_LISTMASTERS} | cut -d',' -f1)
#### Test du serveur sur lequel s' execute le script ####
echo ${site} | grep -i prod2 && { echo "Le script ne fonctionne que sur Prod1 et Dev ";exit;}
echo ${site} | grep -E 'prod1|dev' || { echo "Le script ne fonctionne que sur Prod1 et Dev ";exit;}
##############################
TFILE_EMAILS=$(mktemp /tmp/$RACINE.XXXXXXXXX.TFILE_EMAILS)
@@ -968,9 +970,9 @@ updateUser() {
MAILALIAS_CHANGE=0
for VALMAIL in ${CONTENU_ATTRIBUT}
do
read -p " - On garde ${VALMAIL} (o/n) ? [o] : " READVALMAIL
read -p " - On garde ${VALMAIL} (o/n) [o] ? : " READVALMAIL
case ${READVALMAIL} in
* | "" | o | O )
"" | o | O )
NEW_CONTENU_ATTRIBUT="${NEW_CONTENU_ATTRIBUT} ${VALMAIL}"
;;
n | N )
@@ -1007,7 +1009,7 @@ updateUser() {
done
;;
"" | n | N )
#CHANGED+=([mailAlias]="${NEW_CONTENU_ATTRIBUT}")
CHANGED+=([mailAlias]="${NEW_CONTENU_ATTRIBUT}")
;;
* )
printKazMsg "Erreur"

18
bin/getX509Certificates.sh Executable file
View File

@@ -0,0 +1,18 @@
#/bin/bash
#koi: récupération des certifs traefik vers x509 pour mail et listes
#ki: fanch
#kan: 18/04/2025
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
certificates="mail listes"
for i in ${certificates}; do
jq -r ".letsencrypt.Certificates[] | select(.domain.main==\"${i}.${domain}\") | .certificate" /var/lib/docker/volumes/traefik_letsencrypt/_data/acme.json | base64 -d > /etc/ssl/certs/${i}.pem
jq -r ".letsencrypt.Certificates[] | select(.domain.main==\"${i}.${domain}\") | .key" /var/lib/docker/volumes/traefik_letsencrypt/_data/acme.json | base64 -d > /etc/ssl/private/${i}.key
chmod 600 /etc/ssl/private/${i}.key
done

View File

@@ -1,4 +1,4 @@
#!/bin/bash
g#!/bin/bash
set -e
# on pourra inclure le fichier dockers.env pour
@@ -120,6 +120,13 @@ export DebugLog="${KAZ_ROOT}/log/log-install-$(date +%y-%m-%d-%T)-"
# "${KAZ_ROOT}/bin/container.sh" stop ${DOCKERS_LIST[*]}
"${KAZ_ROOT}/bin/container.sh" start ${DOCKERS_LIST[*]}
if [[ " ${DOCKERS_LIST[*]} " =~ " traefik " ]]; then
# on initialise traefik :-(
${KAZ_COMP_DIR}/traefik/first.sh
# on démarre traefik (plus lancé dans container.sh)
docker-compose -f ${KAZ_COMP_DIR}/traefik/docker-compose.yml up -d
fi
if [[ " ${DOCKERS_LIST[*]} " =~ " etherpad " ]]; then
# pb avec la lanteur de démarrage du pad :-(
sleep 5

View File

@@ -1,6 +1,7 @@
#!/bin/bash
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. $KAZ_ROOT/bin/.commonFunctions.sh
setKazVars
@@ -76,6 +77,10 @@ Int_paheko_Action() {
do
eval $VAL_GAR=$(jq .$VAL_GAR ${TFILE_INT_PAHEKO_IDFILE})
done
################################
# test du mail valide en $domain
echo ${email} | grep -i "${domain}" || { echo "le mail ${email} n'est pas en ${domain}"; exit ;}
################################
#comme tout va bien on continue
#on compte le nom de champs dans la zone nom pour gérer les noms et prénoms composés
# si il y a 3 champs, on associe les 2 premieres valeurs avec un - et on laisse le 3ème identique
@@ -145,6 +150,9 @@ Int_paheko_Action() {
nc_base="N"
admin_orga="O"
fi
#On met le mail et le mail de secours en minuscules
email=$(echo $email | tr [:upper:] [:lower:])
email_secours=$(echo $email_secours | tr [:upper:] [:lower:])
# Pour le reste on renomme les null en N ( non ) et les valeurs 1 en O ( Oui)
cloud=$(echo $cloud | sed -e 's/0/N/g' | sed -e 's/1/O/g')
paheko=$(echo $garradin | sed -e 's/0/N/g' | sed -e 's/1/O/g')
@@ -155,11 +163,11 @@ Int_paheko_Action() {
echo "$nom_ok;$prenom_ok;$email;$email_secours;$nom_orga;$admin_orga;$cloud;$paheko;$wordpress;$agora;$docuwiki;$nc_base;$groupe_nc_base;$equipe_agora;$quota_disque">>${FILE_CREATEUSER}
done
else
echo "Rien à créer"
[ "$OPTION" = "silence" ] || echo "Rien à créer"
exit 2
fi
}
#Int_paheko_Action "A créer" "silence"
Int_paheko_Action "A créer"
# Main
Int_paheko_Action "A créer" "silence"
exit 0

View File

@@ -1,5 +1,11 @@
#!/bin/bash
#Ki: François
#Kan: 2021
#Koi: gestion des réseaux docker
#15/01/2025: Dernière modif by fab: connecter le réseau de l'orga nouvellement créé au ocntainter Traefik
# faire un completion avec les composant dispo
PRG=$(basename $0)
@@ -85,6 +91,10 @@ getNet() {
# the winner is...
echo "${netName} => ${subnet}/28"
${SIMU} docker network create --subnet "${subnet}/28" "${netName}"
#maj du 15/01 by fab (pour éviter de restart le traefik)
${SIMU} docker network connect "${netName}" traefikServ
find="ok"
done
minD=0

15
bin/lib/config.py Normal file
View File

@@ -0,0 +1,15 @@
DOCKERS_ENV = "/kaz/config/dockers.env"
SECRETS = "/kaz/secret/env-{serv}"
def getDockersConfig(key):
with open(DOCKERS_ENV) as config:
for line in config:
if line.startswith(f"{key}="):
return line.split("=", 1)[1].split("#")[0].strip()
def getSecretConfig(serv, key):
with open(SECRETS.format(serv=serv)) as config:
for line in config:
if line.startswith(f"{key}="):
return line.split("=", 2)[1].split("#")[0].strip()

101
bin/lib/ldap.py Normal file
View File

@@ -0,0 +1,101 @@
import ldap
from passlib.hash import sha512_crypt
from email_validator import validate_email, EmailNotValidError
import subprocess
from .config import getDockersConfig, getSecretConfig
class Ldap:
def __init__(self):
self.ldap_connection = None
self.ldap_root = getDockersConfig("ldap_root")
self.ldap_admin_username = getSecretConfig("ldapServ", "LDAP_ADMIN_USERNAME")
self.ldap_admin_password = getSecretConfig("ldapServ", "LDAP_ADMIN_PASSWORD")
cmd="docker inspect -f '{{.NetworkSettings.Networks.ldapNet.IPAddress}}' ldapServ"
self.ldap_host = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).strip().decode()
def __enter__(self):
self.ldap_connection = ldap.initialize(f"ldap://{self.ldap_host}")
self.ldap_connection.simple_bind_s("cn={},{}".format(self.ldap_admin_username, self.ldap_root), self.ldap_admin_password)
return self
def __exit__(self, tp, e, traceback):
self.ldap_connection.unbind_s()
def get_email(self, email):
"""
Vérifier si un utilisateur avec cet email existe dans le LDAP soit comme mail principal soit comme alias
"""
# Créer une chaîne de filtre pour rechercher dans les champs "cn" et "mailAlias"
filter_str = "(|(cn={})(mailAlias={}))".format(email, email)
result = self.ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, filter_str)
return result
def delete_user(self, email):
"""
Supprimer un utilisateur du LDAP par son adresse e-mail
"""
try:
# Recherche de l'utilisateur
result = self.ldap_connection.search_s("ou=users,{}".format(self.ldap_root), ldap.SCOPE_SUBTREE, "(cn={})".format(email))
if not result:
return False # Utilisateur non trouvé
# Récupération du DN de l'utilisateur
dn = result[0][0]
# Suppression de l'utilisateur
self.ldap_connection.delete_s(dn)
return True # Utilisateur supprimé avec succès
except ldap.NO_SUCH_OBJECT:
return False # Utilisateur non trouvé
except ldap.LDAPError as e:
return False # Erreur lors de la suppression
def create_user(self, email, prenom, nom, password, email_secours, quota):
"""
Créer une nouvelle entrée dans le LDAP pour un nouvel utilisateur. QUESTION: A QUOI SERVENT PRENOM/NOM/IDENT_KAZ DANS LE LDAP ? POURQUOI 3 QUOTA ?
"""
password_chiffre = sha512_crypt.hash(password)
if not validate_email(email) or not validate_email(email_secours):
return False
if self.get_email(email):
return False
# Construire le DN
dn = f"cn={email},ou=users,{self.ldap_root}"
mod_attrs = [
('objectClass', [b'inetOrgPerson', b'PostfixBookMailAccount', b'nextcloudAccount', b'kaznaute']),
('sn', f'{prenom} {nom}'.encode('utf-8')),
('mail', email.encode('utf-8')),
('mailEnabled', b'TRUE'),
('mailGidNumber', b'5000'),
('mailHomeDirectory', f"/var/mail/{email.split('@')[1]}/{email.split('@')[0]}/".encode('utf-8')),
('mailQuota', f'{quota}G'.encode('utf-8')),
('mailStorageDirectory', f"maildir:/var/mail/{email.split('@')[1]}/{email.split('@')[0]}/".encode('utf-8')),
('mailUidNumber', b'5000'),
('mailDeSecours', email_secours.encode('utf-8')),
('identifiantKaz', f'{prenom.lower()}.{nom.lower()}'.encode('utf-8')),
('quota', str(quota).encode('utf-8')),
('nextcloudEnabled', b'TRUE'),
('nextcloudQuota', f'{quota} GB'.encode('utf-8')),
('mobilizonEnabled', b'TRUE'),
('agoraEnabled', b'TRUE'),
('userPassword', f'{{CRYPT}}{password_chiffre}'.encode('utf-8')),
('cn', email.encode('utf-8'))
]
self.ldap_connection.add_s(dn, mod_attrs)
return True

134
bin/lib/mattermost.py Normal file
View File

@@ -0,0 +1,134 @@
import subprocess
from .config import getDockersConfig, getSecretConfig
mattermost_user = getSecretConfig("mattermostServ", "MM_ADMIN_USER")
mattermost_pass = getSecretConfig("mattermostServ", "MM_ADMIN_PASSWORD")
mattermost_url = f"https://{getDockersConfig('matterHost')}.{getDockersConfig('domain')}"
mmctl = "docker exec -i mattermostServ bin/mmctl"
class Mattermost:
def __init__(self):
pass
def __enter__(self):
self.authenticate()
return self
def __exit__(self, tp, e, traceback):
self.logout()
def authenticate(self):
# Authentification sur MM
cmd = f"{mmctl} auth login {mattermost_url} --name local-server --username {mattermost_user} --password {mattermost_pass}"
subprocess.run(cmd, shell=True, stderr=subprocess.STDOUT, check=True)
def logout(self):
# Authentification sur MM
cmd = f"{mmctl} auth clean"
subprocess.run(cmd, shell=True, stderr=subprocess.STDOUT, check=True)
def post_message(self, message, equipe="kaz", canal="creation-comptes"):
"""
Envoyer un message dans une Equipe/Canal de MM
"""
cmd = f"{mmctl} post create {equipe}:{canal} --message \"{message}\""
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def get_user(self, user):
"""
Le user existe t-il sur MM ?
"""
try:
cmd = f"{mmctl} user search {user} --json"
user_list_output = subprocess.check_output(cmd, shell=True)
return True # Le nom d'utilisateur existe
except subprocess.CalledProcessError:
return False
def create_user(self, user, email, password):
"""
Créer un utilisateur sur MM
"""
cmd = f"{mmctl} user create --email {email} --username {user} --password {password}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def delete_user(self, email):
"""
Supprimer un utilisateur sur MM
"""
cmd = f"{mmctl} user delete {email} --confirm"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def update_password(self, email, new_password):
"""
Changer un password pour un utilisateur de MM
"""
cmd = f"{mmctl} user change-password {email} --password {new_password}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_user_to_team(self, email, equipe):
"""
Affecte un utilisateur à une équipe MM
"""
cmd = f"{mmctl} team users add {equipe} {email}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_user_to_channel(self, email, equipe, canal):
"""
Affecte un utilisateur à un canal MM
"""
cmd = f'{mmctl} channel users add {equipe}:{canal} {email}'
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def get_teams(self):
"""
Lister les équipes sur MM
"""
cmd = f"{mmctl} team list --disable-pager"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
data_list = output.decode("utf-8").strip().split('\n')
data_list.pop()
return data_list
def create_team(self, equipe, email):
"""
Créer une équipe sur MM et affecter un admin si email est renseigné (set admin marche pô)
"""
#DANGER: l'option --email ne rend pas le user admin de l'équipe comme c'est indiqué dans la doc :(
cmd = f"{mmctl} team create --name {equipe} --display-name {equipe} --private --email {email}"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
#Workaround: on récup l'id du user et de l'équipe pour affecter le rôle "scheme_admin": true, "scheme_user": true avec l'api MM classique.
#TODO:
return output.decode()
def delete_team(self, equipe):
"""
Supprimer une équipe sur MM
"""
cmd = f"{mmctl} team delete {equipe} --confirm"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()

134
bin/lib/paheko.py Normal file
View File

@@ -0,0 +1,134 @@
import re
import requests
from .config import getDockersConfig, getSecretConfig
paheko_ident = getDockersConfig("paheko_API_USER")
paheko_pass = getDockersConfig("paheko_API_PASSWORD")
paheko_auth = (paheko_ident, paheko_pass)
paheko_url = f"https://kaz-paheko.{getDockersConfig('domain')}"
class Paheko:
def get_categories(self):
"""
Récupérer les catégories Paheko avec le compteur associé
"""
api_url = paheko_url + '/api/user/categories'
response = requests.get(api_url, auth=paheko_auth)
if response.status_code == 200:
data = response.json()
return data
else:
return None
def get_users_in_categorie(self,categorie):
"""
Afficher les membres d'une catégorie Paheko
"""
if not categorie.isdigit():
return 'Id de category non valide', 400
api_url = paheko_url + '/api/user/category/'+categorie+'.json'
response = requests.get(api_url, auth=paheko_auth)
if response.status_code == 200:
data = response.json()
return data
else:
return None
def get_user(self,ident):
"""
Afficher un membre de Paheko par son email kaz ou son numéro ou le non court de l'orga
"""
emailmatchregexp = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
if emailmatchregexp.match(ident):
data = { "sql": f"select * from users where email='{ident}' or alias = '{ident}'" }
api_url = paheko_url + '/api/sql/'
response = requests.post(api_url, auth=paheko_auth, data=data)
#TODO: if faut Rechercher count et vérifier que = 1 et supprimer le count=1 dans la réponse
elif ident.isdigit():
api_url = paheko_url + '/api/user/'+ident
response = requests.get(api_url, auth=paheko_auth)
else:
nomorga = re.sub(r'\W+', '', ident) # on vire les caractères non alphanumérique
data = { "sql": f"select * from users where admin_orga=1 and nom_orga='{nomorga}'" }
api_url = paheko_url + '/api/sql/'
response = requests.post(api_url, auth=paheko_auth, data=data)
#TODO:if faut Rechercher count et vérifier que = 1 et supprimer le count=1 dans la réponse
if response.status_code == 200:
data = response.json()
if data["count"] == 1:
return data["results"][0]
elif data["count"] == 0:
return None
else:
return data["results"]
else:
return None
def set_user(self,ident,field,new_value):
"""
Modifie la valeur d'un champ d'un membre paheko (ident= numéro paheko ou email kaz)
"""
#récupérer le numero paheko si on fournit un email kaz
emailmatchregexp = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
if emailmatchregexp.match(ident):
data = { "sql": f"select id from users where email='{ident}'" }
api_url = paheko_url + '/api/sql/'
response = requests.post(api_url, auth=paheko_auth, data=data)
if response.status_code == 200:
#on extrait l'id de la réponse
data = response.json()
if data['count'] == 0:
print("email non trouvé")
return None
elif data['count'] > 1:
print("trop de résultat")
return None
else:
#OK
ident = data['results'][0]['id']
else:
print("pas de résultat")
return None
elif not ident.isdigit():
print("Identifiant utilisateur invalide")
return None
regexp = re.compile("[^a-zA-Z0-9 \\r\\n\\t" + re.escape(string.punctuation) + "]")
valeur = regexp.sub('',new_value) # mouais, il faudrait être beaucoup plus précis ici en fonction des champs qu'on accepte...
champ = re.sub(r'\W+','',field) # pas de caractères non alphanumériques ici, dans l'idéal, c'est à choisir dans une liste plutot
api_url = paheko_url + '/api/user/'+str(ident)
payload = {champ: valeur}
response = requests.post(api_url, auth=paheko_auth, data=payload)
return response.json()
def get_users_with_action(self, action):
"""
retourne tous les membres de paheko avec une action à mener (création du compte kaz / modification...)
"""
api_url = paheko_url + '/api/sql/'
payload = { "sql": f"select * from users where action_auto='{action}'" }
response = requests.post(api_url, auth=paheko_auth, data=payload)
if response.status_code == 200:
return response.json()
else:
return None

40
bin/lib/sympa.py Normal file
View File

@@ -0,0 +1,40 @@
import subprocess
from email_validator import validate_email, EmailNotValidError
from .config import getDockersConfig, getSecretConfig
sympa_user = getSecretConfig("sympaServ", "SOAP_USER")
sympa_pass = getSecretConfig("sympaServ", "SOAP_PASSWORD")
sympa_listmaster = getSecretConfig("sympaServ", "ADMINEMAIL")
sympa_url = f"https://{getDockersConfig('sympaHost')}.{getDockersConfig('domain')}"
sympa_soap = "docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl"
sympa_domain = getDockersConfig('domain_sympa')
sympa_liste_info = "infos"
# docker exec -i sympaServ /usr/lib/sympa/bin/sympa_soap_client.pl --soap_url=${httpProto}://${URL_LISTE}/sympasoap --trusted_application=${sympa_SOAP_USER} --trusted_application_password=${sympa_SOAP_PASSWORD} --proxy_vars=\"USER_EMAIL=${LISTMASTER}\" --service=add --service_parameters=\"${NL_LIST},${EMAIL_SOUHAITE}\"" | tee -a "${CMD_SYMPA}"
class Sympa:
def _execute_sympa_command(self, email, liste, service):
if validate_email(email) and validate_email(liste):
cmd = f'{sympa_soap} --soap_url={sympa_url}/sympasoap --trusted_application={sympa_user} --trusted_application_password={sympa_pass} --proxy_vars=USER_EMAIL={sympa_listmaster} --service={service} --service_parameters="{liste},{email}" && echo $?'
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
return output.decode()
def add_email_to_list(self, email, liste=sympa_liste_info):
"""
Ajouter un email dans une liste sympa
"""
output = self._execute_sympa_command(email, f"{liste}@{sympa_domain}", 'add')
return output
def delete_email_from_list(self, email, liste=sympa_liste_info):
"""
Supprimer un email dans une liste sympa
"""
output = self._execute_sympa_command(email, f"{liste}@{sympa_domain}", 'del')
return output

8
bin/lib/template.py Normal file
View File

@@ -0,0 +1,8 @@
import jinja2
templateLoader = jinja2.FileSystemLoader(searchpath="../templates")
templateEnv = jinja2.Environment(loader=templateLoader)
def render_template(filename, args):
template = templateEnv.get_template(filename)
return template.render(args)

213
bin/lib/user.py Normal file
View File

@@ -0,0 +1,213 @@
from email_validator import validate_email, EmailNotValidError
from glob import glob
import tempfile
import subprocess
import re
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
from .paheko import Paheko
from .ldap import Ldap
from .mattermost import Mattermost
from .sympa import Sympa
from .template import render_template
from .config import getDockersConfig, getSecretConfig
DEFAULT_FILE = "/kaz/tmp/createUser.txt"
webmail_url = f"https://webmail.{getDockersConfig('domain')}"
mattermost_url = f"https://agora.{getDockersConfig('domain')}"
mdp_url = f"https://mdp.{getDockersConfig('domain')}"
sympa_url = f"https://listes.{getDockersConfig('domain')}"
site_url = f"https://{getDockersConfig('domain')}"
cloud_url = f"https://cloud.{getDockersConfig('domain')}"
def _generate_password(self):
cmd="apg -n 1 -m 10 -M NCL -d"
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
new_password="_"+output.decode("utf-8")+"_"
return new_password
def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, prenom, nc_orga, garradin_orga, wp_orga, agora_orga, wiki_orga, nc_base, groupe_nc_base, equipe_agora, password=None):
email = email.lower()
with Ldap() as ldap:
# est-il déjà dans le ldap ? (mail ou alias)
if ldap.get_email(email):
print(f"ERREUR 1: {email} déjà existant dans ldap. on arrête tout")
return None
#test nom orga
if admin_orga == 1:
if nom_orga is None:
print(f"ERREUR 0 sur paheko: {email} : nom_orga vide, on arrête tout")
return
if not bool(re.match(r'^[a-z0-9-]+$', nom_orga)):
print(f"ERREUR 0 sur paheko: {email} : nom_orga ({tab['nom_orga']}) incohérent (minuscule/chiffre/-), on arrête tout")
return
#test email_secours
email_secours = email_secours.lower()
if not validate_email(email_secours):
print("Mauvais email de secours")
return
#test quota
quota = quota_disque
if not quota.isdigit():
print(f"ERREUR 2: quota non numérique : {quota}, on arrête tout")
return
#on génère un password
password = password or _generate_password()
#on créé dans le ldap
#à quoi servent prenom/nom dans le ldap ?
data = {
"prenom": prenom,
"nom": nom,
"password": password,
"email_secours": email_secours,
"quota": quota
}
if not ldap.create_user(email, **data):
print("Erreur LDAP")
return
with Mattermost() as mm:
#on créé dans MM
user = email.split('@')[0]
mm.create_user(user, email, password)
mm.add_user_to_team(email, "kaz")
#et aux 2 canaux de base
mm.add_user_to_channel(email, "kaz", "une-question--un-soucis")
mm.add_user_to_channel(email, "kaz", "cafe-du-commerce--ouvert-2424h")
#on créé une nouvelle équipe ds MM si besoin
if admin_orga == 1:
mm.create_team(nom_orga, email)
#BUG: créer la nouvelle équipe n'a pas rendu l'email admin, on le rajoute comme membre simple
mm.add_user_to_team(email, nom_orga)
#on inscrit email et email_secours à la nl sympa_liste_info
sympa = Sympa()
sympa.add_email_to_list(email)
sympa.add_email_to_list(email_secours)
#on construit/envoie le mail
context = {
'ADMIN_ORGA': admin_orga,
'NOM': f"{prenom} {nom}",
'EMAIL_SOUHAITE': email,
'PASSWORD': password,
'QUOTA': quota_disque,
'URL_WEBMAIL': webmail_url,
'URL_AGORA': mattermost_url,
'URL_MDP': mdp_url,
'URL_LISTE': sympa_url,
'URL_SITE': site_url,
'URL_CLOUD': cloud_url,
}
html = render_template("email_inscription.html", context)
raw = render_template("email_inscription.txt", context)
message = MIMEMultipart()
message["Subject"] = "KAZ: confirmation d'inscription !"
message["From"] = f"contact@{getDockersConfig('domain')}"
message["To"] = f"{email}, {email_secours}"
message.attach(MIMEText(raw, "plain"))
message.attach(MIMEText(html, "html"))
with smtplib.SMTP(f"mail.{getDockersConfig('domain')}", 25) as server:
server.sendmail(f"contact@{getDockersConfig('domain')}", [email,email_secours], message.as_string())
#on met le flag paheko action à Aucune
paheko = Paheko()
try:
paheko.set_user(email, "action_auto", "Aucune")
except:
print(f"Erreur paheko pour remettre action_auto = Aucune pour {email}")
#on post sur MM pour dire ok
with Mattermost() as mm:
msg=f"**POST AUTO** Inscription réussie pour {email} avec le secours {email_secours} Bisou!"
mm.post_message(message=msg)
def create_waiting_users():
"""
Créé les kaznautes en attente: inscription sur MM / Cloud / email + msg sur MM + email à partir de action="a créer" sur paheko
"""
#verrou pour empêcher de lancer en même temps la même api
prefixe="create_user_lock_"
if glob(f"{tempfile.gettempdir()}/{prefixe}*"):
print("Lock présent")
return None
lock_file = tempfile.NamedTemporaryFile(prefix=prefixe,delete=True)
#qui sont les kaznautes à créer ?
paheko = Paheko()
liste_kaznautes = paheko.get_users_with_action("A créer")
if liste_kaznautes:
count=liste_kaznautes['count']
if count==0:
print("aucun nouveau kaznaute à créer")
return
#au moins un kaznaute à créer
for tab in liste_kaznautes['results']:
create_user(**tab)
print("fin des inscriptions")
def create_users_from_file(file=DEFAULT_FILE):
"""
Créé les kaznautes en attente: inscription sur MM / Cloud / email + msg sur MM + email à partir du ficher
"""
#verrou pour empêcher de lancer en même temps la même api
prefixe="create_user_lock_"
if glob(f"{tempfile.gettempdir()}/{prefixe}*"):
print("Lock présent")
return None
lock_file = tempfile.NamedTemporaryFile(prefix=prefixe,delete=True)
#qui sont les kaznautes à créer ?
liste_kaznautes = []
with open(file) as lines:
for line in lines:
line = line.strip()
if not line.startswith("#") and line != "":
user_data = line.split(';')
user_dict = {
"nom": user_data[0],
"prenom": user_data[1],
"email": user_data[2],
"email_secours": user_data[3],
"nom_orga": user_data[4],
"admin_orga": user_data[5],
"nc_orga": user_data[6],
"garradin_orga": user_data[7],
"wp_orga": user_data[8],
"agora_orga": user_data[9],
"wiki_orga": user_data[10],
"nc_base": user_data[11],
"groupe_nc_base": user_data[12],
"equipe_agora": user_data[13],
"quota_disque": user_data[14],
"password": user_data.get(15),
}
liste_kaznautes.append(user_dict)
if liste_kaznautes:
for tab in liste_kaznautes:
create_user(**tab)
print("fin des inscriptions")

72
bin/look/feminin/logo.svg Normal file
View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.0"
width="640.000000pt"
height="1280.000000pt"
viewBox="0 0 640.000000 1280.000000"
preserveAspectRatio="xMidYMid meet"
id="svg18"
sodipodi:docname="logo.svg"
xml:space="preserve"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs22" /><sodipodi:namedview
id="namedview20"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="pt"
showgrid="false"
inkscape:zoom="0.36440298"
inkscape:cx="428.09749"
inkscape:cy="753.28693"
inkscape:window-width="1920"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg18" /><g
transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
fill="#000000"
stroke="none"
id="g16"><path
d="M1450 12780 c-28 -28 -38 -56 -65 -190 -70 -337 -103 -1013 -111 -2260 l-6 -785 69 -32 c218 -103 428 -212 520 -270 133 -84 182 -103 396 -159 350 -91 440 -127 536 -211 65 -57 94 -102 118 -184 l19 -64 274 0 274 0 17 60 c31 102 63 147 162 221 77 57 183 96 406 150 386 92 459 117 766 259 262 121 388 175 408 175 23 0 24 44 15 915 -13 1328 -47 1950 -124 2250 -35 134 -58 158 -129 130 -78 -29 -169 -147 -453 -587 -216 -333 -330 -485 -385 -512 -32 -15 -76 -19 -265 -27 -269 -10 -1017 -10 -1288 0 -176 6 -194 8 -240 32 -64 33 -95 73 -419 559 -272 408 -340 497 -406 530 -48 25 -64 25 -89 0z m197 -402 c50 -55 184 -325 220 -445 22 -76 23 -250 0 -309 -41 -108 -100 -164 -173 -164 -50 0 -67 17 -88 90 -24 80 -72 370 -92 549 -20 188 -16 257 16 283 32 26 91 24 117 -4z m3353 12 c29 -16 43 -84 36 -170 -20 -223 -80 -593 -112 -693 -18 -54 -36 -67 -93 -67 -53 0 -110 49 -148 128 -22 47 -28 75 -31 154 -7 150 13 217 125 437 52 102 102 194 110 204 18 19 83 23 113 7z m-2675 -1975 c22 -4 67 -21 99 -38 95 -51 142 -134 117 -209 -14 -41 -72 -103 -120 -127 -46 -23 -139 -47 -148 -38 -3 4 5 20 20 35 37 39 59 98 59 162 1 82 -17 134 -62 182 -45 46 -47 51 -22 45 9 -3 35 -8 57 -12z m-199 -36 c-48 -56 -59 -97 -54 -188 5 -78 19 -118 58 -159 12 -13 20 -25 18 -28 -7 -6 -108 26 -137 44 -75 46 -111 99 -111 162 0 49 17 84 63 128 36 35 136 81 175 82 23 0 22 -2 -12 -41z m1984 37 c0 -3 -13 -19 -30 -37 -79 -87 -79 -255 1 -340 16 -18 28 -33 26 -36 -2 -2 -34 6 -72 18 -79 24 -157 89 -176 146 -30 92 44 191 179 239 37 13 72 18 72 10z m223 -16 c60 -23 130 -78 152 -121 19 -36 19 -102 1 -138 -17 -32 -73 -84 -114 -105 -59 -30 -193 -45 -140 -15 10 5 29 30 44 54 54 94 39 240 -33 310 l-36 35 36 0 c20 0 60 -9 90 -20z m-1089 -306 c9 -3 59 -69 113 -146 53 -77 106 -146 118 -154 11 -7 39 -16 60 -19 52 -6 75 -34 75 -92 0 -67 -31 -93 -111 -93 -36 0 -75 7 -96 17 -34 16 -117 106 -170 186 -14 20 -29 37 -33 37 -4 0 -19 -17 -32 -37 -44 -66 -118 -147 -160 -175 -34 -23 -52 -28 -105 -28 -55 0 -68 4 -88 25 -20 19 -25 34 -25 73 0 60 17 78 84 91 57 10 72 26 186 193 44 64 85 119 92 121 19 8 74 8 92 1z"
id="path2" /><path
d="M1130 9411 c-340 -102 -544 -266 -581 -467 -34 -181 103 -365 345 -466 158 -65 303 -89 656 -108 569 -31 954 -31 1065 1 190 54 276 205 195 345 -73 128 -194 193 -509 274 -286 74 -348 98 -515 199 -188 114 -457 243 -515 248 -30 2 -79 -7 -141 -26z"
id="path4" /><path
d="M5105 9354 c-550 -254 -547 -253 -925 -345 -236 -57 -301 -77 -377 -114 -204 -100 -290 -244 -223 -374 39 -78 115 -129 232 -156 99 -23 629 -25 838 -4 52 5 187 14 300 19 292 14 442 43 596 116 222 105 340 285 304 461 -32 154 -131 268 -311 356 -111 54 -240 97 -290 97 -13 -1 -78 -26 -144 -56z"
id="path6" /><path
d="M1200 6430 l0 -1120 165 0 165 0 2 496 3 496 206 -494 207 -493 181 -3 181 -2 -6 27 c-4 16 -12 39 -20 53 -7 14 -116 264 -243 555 l-231 530 216 510 c118 281 220 518 225 527 19 37 13 38 -177 36 l-186 -3 -177 -463 -176 -462 -3 465 -2 465 -165 0 -165 0 0 -1120z"
id="path8" /><path
d="M3005 7528 c-3 -13 -97 -504 -210 -1093 -113 -588 -208 -1082 -211 -1097 l-6 -28 161 0 c89 0 161 3 162 8 0 4 15 97 32 207 l32 200 212 3 213 2 5 -22 c3 -13 16 -95 30 -183 14 -88 28 -172 31 -187 l6 -28 160 0 160 0 -5 23 c-3 12 -99 508 -212 1102 -113 594 -208 1088 -211 1098 -5 15 -22 17 -174 17 -168 0 -170 0 -175 -22z m258 -1010 c43 -266 78 -486 77 -490 0 -5 -75 -8 -166 -8 l-166 0 5 26 c2 14 38 234 78 490 42 263 78 464 84 464 6 0 44 -209 88 -482z"
id="path10" /><path
d="M4150 7399 l0 -150 290 3 c286 3 290 3 284 -17 -4 -11 -144 -402 -312 -870 l-305 -850 -5 -102 -4 -103 516 0 516 0 0 151 0 150 -315 -3 c-173 -2 -315 -2 -315 -1 0 1 120 334 266 740 380 1054 364 1004 364 1113 l0 90 -490 0 -490 0 0 -151z"
id="path12" /><path
d="M1251 4291 c-15 -4 -27 -17 -31 -31 -12 -46 -20 -984 -10 -1269 30 -885 107 -1328 426 -2460 109 -387 161 -468 329 -516 169 -50 310 55 370 275 26 92 31 634 14 1355 -7 308 -13 585 -14 615 l0 55 256 3 257 2 6 -142 c35 -740 202 -1240 531 -1587 69 -73 201 -179 262 -210 100 -50 231 -33 303 39 22 22 42 40 44 40 2 0 9 -37 16 -82 20 -144 63 -245 129 -306 111 -103 309 -85 415 39 68 80 92 145 196 525 282 1027 353 1413 390 2109 16 300 10 1519 -8 1537 -11 11 -373 13 -1935 14 -1057 0 -1933 -2 -1946 -5z m2775 -2093 c-14 -256 -26 -764 -26 -1055 0 -167 -4 -303 -8 -303 -5 0 -17 10 -28 21 -10 12 -47 41 -80 65 -128 92 -247 242 -324 408 -106 228 -160 493 -184 904 l-5 82 330 0 331 0 -6 -122z"
id="path14" /></g><image
width="156.53996"
height="217.31963"
preserveAspectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAfCAYAAAD9cg1AAAAABHNCSVQICAgIfAhkiAAAAghJREFU
SIm1lrFrFFEQxn+bi/E0EAU7ESxsEgsJFyGNQuwVFEQQrC1S2tjnHxCEWFmlFC3Ezlo8rwmiqJfG
Iu2JqHARzO39LLIJu2/vdt8lOjDcze033/duHjOzUGPiBXFNbIs/xL74XtwQV8SkjmMc8XHxkfhH
tMI3xdak5HPimxrivO+I12PJE/HVBOT73hcvxQjcHZH8TrwjzmaYJXFdHAS4tzECH4Kk5+L0GOwN
cTfAX6kivxiAv4unag70OMhZzz+fCvBLQfwsIflZJQA8DeLLVQKng/hzDTnApyA+VyUwDOITEQIn
g3inSuBjEK9ECFwL4q9jkeJs1jT7FzYUx4qIzayT85f8sPI44pMg4Zt4dQRubkRD/hbP1gmcz4Za
PjEVX4oPxPvZjOqNaMi1SvKcyM2sPJOMitfisSiBTOSW+CuS/MX+GJnI3NsFG44f2V3xnjU7IQm+
l8DiGfFLQH47kpNd9hrM3GcKDLJnKTDs0CmcfpHFNHuWZnkFfMbjNHAwKROSpEULyg3ILMUSL7Aw
1aCR/6kBsM02PXpBBTJv0px0yZR8lVXznKWTHtWS4Ar/u0BhU6WkdOgwTXmBzTNfuIcuXfr0S7iw
/pCrV5W3aRdqvcxyVN6hSzRgEIWLFhAL8bC0m44oUCf4zwVibeT7zijbYosZZg7ineLqHWsJRP7X
Q9pfySZ/u3a+10wAAAAASUVORK5CYII=
"
id="image32"
x="233.91249"
y="24.324821" /></svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

85
bin/look/greve/logo.svg Normal file
View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.0"
width="640.000000pt"
height="1280.000000pt"
viewBox="0 0 640.000000 1280.000000"
preserveAspectRatio="xMidYMid meet"
id="svg18"
sodipodi:docname="logo.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs22">
<rect
x="179.93953"
y="196.11891"
width="517.72233"
height="120.71095"
id="rect248" />
<rect
x="144.39207"
y="193.77589"
width="604.30237"
height="115.55072"
id="rect182" />
</defs>
<sodipodi:namedview
id="namedview20"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="pt"
showgrid="false"
inkscape:zoom="0.48229806"
inkscape:cx="427.12177"
inkscape:cy="902.9686"
inkscape:window-width="1920"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg18" />
<g
transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
fill="#000000"
stroke="none"
id="g16">
<path
d="M1450 12780 c-28 -28 -38 -56 -65 -190 -70 -337 -103 -1013 -111 -2260 l-6 -785 69 -32 c218 -103 428 -212 520 -270 133 -84 182 -103 396 -159 350 -91 440 -127 536 -211 65 -57 94 -102 118 -184 l19 -64 274 0 274 0 17 60 c31 102 63 147 162 221 77 57 183 96 406 150 386 92 459 117 766 259 262 121 388 175 408 175 23 0 24 44 15 915 -13 1328 -47 1950 -124 2250 -35 134 -58 158 -129 130 -78 -29 -169 -147 -453 -587 -216 -333 -330 -485 -385 -512 -32 -15 -76 -19 -265 -27 -269 -10 -1017 -10 -1288 0 -176 6 -194 8 -240 32 -64 33 -95 73 -419 559 -272 408 -340 497 -406 530 -48 25 -64 25 -89 0z m197 -402 c50 -55 184 -325 220 -445 22 -76 23 -250 0 -309 -41 -108 -100 -164 -173 -164 -50 0 -67 17 -88 90 -24 80 -72 370 -92 549 -20 188 -16 257 16 283 32 26 91 24 117 -4z m3353 12 c29 -16 43 -84 36 -170 -20 -223 -80 -593 -112 -693 -18 -54 -36 -67 -93 -67 -53 0 -110 49 -148 128 -22 47 -28 75 -31 154 -7 150 13 217 125 437 52 102 102 194 110 204 18 19 83 23 113 7z m-2675 -1975 c22 -4 67 -21 99 -38 95 -51 142 -134 117 -209 -14 -41 -72 -103 -120 -127 -46 -23 -139 -47 -148 -38 -3 4 5 20 20 35 37 39 59 98 59 162 1 82 -17 134 -62 182 -45 46 -47 51 -22 45 9 -3 35 -8 57 -12z m-199 -36 c-48 -56 -59 -97 -54 -188 5 -78 19 -118 58 -159 12 -13 20 -25 18 -28 -7 -6 -108 26 -137 44 -75 46 -111 99 -111 162 0 49 17 84 63 128 36 35 136 81 175 82 23 0 22 -2 -12 -41z m1984 37 c0 -3 -13 -19 -30 -37 -79 -87 -79 -255 1 -340 16 -18 28 -33 26 -36 -2 -2 -34 6 -72 18 -79 24 -157 89 -176 146 -30 92 44 191 179 239 37 13 72 18 72 10z m223 -16 c60 -23 130 -78 152 -121 19 -36 19 -102 1 -138 -17 -32 -73 -84 -114 -105 -59 -30 -193 -45 -140 -15 10 5 29 30 44 54 54 94 39 240 -33 310 l-36 35 36 0 c20 0 60 -9 90 -20z m-1089 -306 c9 -3 59 -69 113 -146 53 -77 106 -146 118 -154 11 -7 39 -16 60 -19 52 -6 75 -34 75 -92 0 -67 -31 -93 -111 -93 -36 0 -75 7 -96 17 -34 16 -117 106 -170 186 -14 20 -29 37 -33 37 -4 0 -19 -17 -32 -37 -44 -66 -118 -147 -160 -175 -34 -23 -52 -28 -105 -28 -55 0 -68 4 -88 25 -20 19 -25 34 -25 73 0 60 17 78 84 91 57 10 72 26 186 193 44 64 85 119 92 121 19 8 74 8 92 1z"
id="path2" />
<path
d="M1130 9411 c-340 -102 -544 -266 -581 -467 -34 -181 103 -365 345 -466 158 -65 303 -89 656 -108 569 -31 954 -31 1065 1 190 54 276 205 195 345 -73 128 -194 193 -509 274 -286 74 -348 98 -515 199 -188 114 -457 243 -515 248 -30 2 -79 -7 -141 -26z"
id="path4" />
<path
d="M5105 9354 c-550 -254 -547 -253 -925 -345 -236 -57 -301 -77 -377 -114 -204 -100 -290 -244 -223 -374 39 -78 115 -129 232 -156 99 -23 629 -25 838 -4 52 5 187 14 300 19 292 14 442 43 596 116 222 105 340 285 304 461 -32 154 -131 268 -311 356 -111 54 -240 97 -290 97 -13 -1 -78 -26 -144 -56z"
id="path6" />
<path
d="M1200 6430 l0 -1120 165 0 165 0 2 496 3 496 206 -494 207 -493 181 -3 181 -2 -6 27 c-4 16 -12 39 -20 53 -7 14 -116 264 -243 555 l-231 530 216 510 c118 281 220 518 225 527 19 37 13 38 -177 36 l-186 -3 -177 -463 -176 -462 -3 465 -2 465 -165 0 -165 0 0 -1120z"
id="path8" />
<path
d="M3005 7528 c-3 -13 -97 -504 -210 -1093 -113 -588 -208 -1082 -211 -1097 l-6 -28 161 0 c89 0 161 3 162 8 0 4 15 97 32 207 l32 200 212 3 213 2 5 -22 c3 -13 16 -95 30 -183 14 -88 28 -172 31 -187 l6 -28 160 0 160 0 -5 23 c-3 12 -99 508 -212 1102 -113 594 -208 1088 -211 1098 -5 15 -22 17 -174 17 -168 0 -170 0 -175 -22z m258 -1010 c43 -266 78 -486 77 -490 0 -5 -75 -8 -166 -8 l-166 0 5 26 c2 14 38 234 78 490 42 263 78 464 84 464 6 0 44 -209 88 -482z"
id="path10" />
<path
d="M4150 7399 l0 -150 290 3 c286 3 290 3 284 -17 -4 -11 -144 -402 -312 -870 l-305 -850 -5 -102 -4 -103 516 0 516 0 0 151 0 150 -315 -3 c-173 -2 -315 -2 -315 -1 0 1 120 334 266 740 380 1054 364 1004 364 1113 l0 90 -490 0 -490 0 0 -151z"
id="path12" />
<path
d="M1251 4291 c-15 -4 -27 -17 -31 -31 -12 -46 -20 -984 -10 -1269 30 -885 107 -1328 426 -2460 109 -387 161 -468 329 -516 169 -50 310 55 370 275 26 92 31 634 14 1355 -7 308 -13 585 -14 615 l0 55 256 3 257 2 6 -142 c35 -740 202 -1240 531 -1587 69 -73 201 -179 262 -210 100 -50 231 -33 303 39 22 22 42 40 44 40 2 0 9 -37 16 -82 20 -144 63 -245 129 -306 111 -103 309 -85 415 39 68 80 92 145 196 525 282 1027 353 1413 390 2109 16 300 10 1519 -8 1537 -11 11 -373 13 -1935 14 -1057 0 -1933 -2 -1946 -5z m2775 -2093 c-14 -256 -26 -764 -26 -1055 0 -167 -4 -303 -8 -303 -5 0 -17 10 -28 21 -10 12 -47 41 -80 65 -128 92 -247 242 -324 408 -106 228 -160 493 -184 904 l-5 82 330 0 331 0 -6 -122z"
id="path14" />
</g>
<text
xml:space="preserve"
transform="matrix(0.96846201,0,0,0.86019954,-43.878364,-38.095408)"
id="text246"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:106.667px;line-height:125%;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;white-space:pre;shape-inside:url(#rect248);fill:#00ff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><tspan
x="179.93945"
y="291.75453"
id="tspan371">GREVE</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

72
bin/look/kaz/logo.svg Normal file
View File

@@ -0,0 +1,72 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="640.000000pt" height="1280.000000pt" viewBox="0 0 640.000000 1280.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1450 12780 c-28 -28 -38 -56 -65 -190 -70 -337 -103 -1013 -111
-2260 l-6 -785 69 -32 c218 -103 428 -212 520 -270 133 -84 182 -103 396 -159
350 -91 440 -127 536 -211 65 -57 94 -102 118 -184 l19 -64 274 0 274 0 17 60
c31 102 63 147 162 221 77 57 183 96 406 150 386 92 459 117 766 259 262 121
388 175 408 175 23 0 24 44 15 915 -13 1328 -47 1950 -124 2250 -35 134 -58
158 -129 130 -78 -29 -169 -147 -453 -587 -216 -333 -330 -485 -385 -512 -32
-15 -76 -19 -265 -27 -269 -10 -1017 -10 -1288 0 -176 6 -194 8 -240 32 -64
33 -95 73 -419 559 -272 408 -340 497 -406 530 -48 25 -64 25 -89 0z m197
-402 c50 -55 184 -325 220 -445 22 -76 23 -250 0 -309 -41 -108 -100 -164
-173 -164 -50 0 -67 17 -88 90 -24 80 -72 370 -92 549 -20 188 -16 257 16 283
32 26 91 24 117 -4z m3353 12 c29 -16 43 -84 36 -170 -20 -223 -80 -593 -112
-693 -18 -54 -36 -67 -93 -67 -53 0 -110 49 -148 128 -22 47 -28 75 -31 154
-7 150 13 217 125 437 52 102 102 194 110 204 18 19 83 23 113 7z m-2675
-1975 c22 -4 67 -21 99 -38 95 -51 142 -134 117 -209 -14 -41 -72 -103 -120
-127 -46 -23 -139 -47 -148 -38 -3 4 5 20 20 35 37 39 59 98 59 162 1 82 -17
134 -62 182 -45 46 -47 51 -22 45 9 -3 35 -8 57 -12z m-199 -36 c-48 -56 -59
-97 -54 -188 5 -78 19 -118 58 -159 12 -13 20 -25 18 -28 -7 -6 -108 26 -137
44 -75 46 -111 99 -111 162 0 49 17 84 63 128 36 35 136 81 175 82 23 0 22 -2
-12 -41z m1984 37 c0 -3 -13 -19 -30 -37 -79 -87 -79 -255 1 -340 16 -18 28
-33 26 -36 -2 -2 -34 6 -72 18 -79 24 -157 89 -176 146 -30 92 44 191 179 239
37 13 72 18 72 10z m223 -16 c60 -23 130 -78 152 -121 19 -36 19 -102 1 -138
-17 -32 -73 -84 -114 -105 -59 -30 -193 -45 -140 -15 10 5 29 30 44 54 54 94
39 240 -33 310 l-36 35 36 0 c20 0 60 -9 90 -20z m-1089 -306 c9 -3 59 -69
113 -146 53 -77 106 -146 118 -154 11 -7 39 -16 60 -19 52 -6 75 -34 75 -92 0
-67 -31 -93 -111 -93 -36 0 -75 7 -96 17 -34 16 -117 106 -170 186 -14 20 -29
37 -33 37 -4 0 -19 -17 -32 -37 -44 -66 -118 -147 -160 -175 -34 -23 -52 -28
-105 -28 -55 0 -68 4 -88 25 -20 19 -25 34 -25 73 0 60 17 78 84 91 57 10 72
26 186 193 44 64 85 119 92 121 19 8 74 8 92 1z"/>
<path d="M1130 9411 c-340 -102 -544 -266 -581 -467 -34 -181 103 -365 345
-466 158 -65 303 -89 656 -108 569 -31 954 -31 1065 1 190 54 276 205 195 345
-73 128 -194 193 -509 274 -286 74 -348 98 -515 199 -188 114 -457 243 -515
248 -30 2 -79 -7 -141 -26z"/>
<path d="M5105 9354 c-550 -254 -547 -253 -925 -345 -236 -57 -301 -77 -377
-114 -204 -100 -290 -244 -223 -374 39 -78 115 -129 232 -156 99 -23 629 -25
838 -4 52 5 187 14 300 19 292 14 442 43 596 116 222 105 340 285 304 461 -32
154 -131 268 -311 356 -111 54 -240 97 -290 97 -13 -1 -78 -26 -144 -56z"/>
<path d="M1200 6430 l0 -1120 165 0 165 0 2 496 3 496 206 -494 207 -493 181
-3 181 -2 -6 27 c-4 16 -12 39 -20 53 -7 14 -116 264 -243 555 l-231 530 216
510 c118 281 220 518 225 527 19 37 13 38 -177 36 l-186 -3 -177 -463 -176
-462 -3 465 -2 465 -165 0 -165 0 0 -1120z"/>
<path d="M3005 7528 c-3 -13 -97 -504 -210 -1093 -113 -588 -208 -1082 -211
-1097 l-6 -28 161 0 c89 0 161 3 162 8 0 4 15 97 32 207 l32 200 212 3 213 2
5 -22 c3 -13 16 -95 30 -183 14 -88 28 -172 31 -187 l6 -28 160 0 160 0 -5 23
c-3 12 -99 508 -212 1102 -113 594 -208 1088 -211 1098 -5 15 -22 17 -174 17
-168 0 -170 0 -175 -22z m258 -1010 c43 -266 78 -486 77 -490 0 -5 -75 -8
-166 -8 l-166 0 5 26 c2 14 38 234 78 490 42 263 78 464 84 464 6 0 44 -209
88 -482z"/>
<path d="M4150 7399 l0 -150 290 3 c286 3 290 3 284 -17 -4 -11 -144 -402
-312 -870 l-305 -850 -5 -102 -4 -103 516 0 516 0 0 151 0 150 -315 -3 c-173
-2 -315 -2 -315 -1 0 1 120 334 266 740 380 1054 364 1004 364 1113 l0 90
-490 0 -490 0 0 -151z"/>
<path d="M1251 4291 c-15 -4 -27 -17 -31 -31 -12 -46 -20 -984 -10 -1269 30
-885 107 -1328 426 -2460 109 -387 161 -468 329 -516 169 -50 310 55 370 275
26 92 31 634 14 1355 -7 308 -13 585 -14 615 l0 55 256 3 257 2 6 -142 c35
-740 202 -1240 531 -1587 69 -73 201 -179 262 -210 100 -50 231 -33 303 39 22
22 42 40 44 40 2 0 9 -37 16 -82 20 -144 63 -245 129 -306 111 -103 309 -85
415 39 68 80 92 145 196 525 282 1027 353 1413 390 2109 16 300 10 1519 -8
1537 -11 11 -373 13 -1935 14 -1057 0 -1933 -2 -1946 -5z m2775 -2093 c-14
-256 -26 -764 -26 -1055 0 -167 -4 -303 -8 -303 -5 0 -17 10 -28 21 -10 12
-47 41 -80 65 -128 92 -247 242 -324 408 -106 228 -160 493 -184 904 l-5 82
330 0 331 0 -6 -122z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

86
bin/look/noel/logo.svg Normal file
View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.0"
width="640.000000pt"
height="1280.000000pt"
viewBox="0 0 640.000000 1280.000000"
preserveAspectRatio="xMidYMid meet"
id="svg18"
sodipodi:docname="logo.svg"
xml:space="preserve"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs22" /><sodipodi:namedview
id="namedview20"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="pt"
showgrid="false"
inkscape:zoom="0.36440298"
inkscape:cx="428.09749"
inkscape:cy="939.89353"
inkscape:window-width="1920"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg18" /><g
transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
fill="#000000"
stroke="none"
id="g16"><path
d="M1450 12780 c-28 -28 -38 -56 -65 -190 -70 -337 -103 -1013 -111 -2260 l-6 -785 69 -32 c218 -103 428 -212 520 -270 133 -84 182 -103 396 -159 350 -91 440 -127 536 -211 65 -57 94 -102 118 -184 l19 -64 274 0 274 0 17 60 c31 102 63 147 162 221 77 57 183 96 406 150 386 92 459 117 766 259 262 121 388 175 408 175 23 0 24 44 15 915 -13 1328 -47 1950 -124 2250 -35 134 -58 158 -129 130 -78 -29 -169 -147 -453 -587 -216 -333 -330 -485 -385 -512 -32 -15 -76 -19 -265 -27 -269 -10 -1017 -10 -1288 0 -176 6 -194 8 -240 32 -64 33 -95 73 -419 559 -272 408 -340 497 -406 530 -48 25 -64 25 -89 0z m197 -402 c50 -55 184 -325 220 -445 22 -76 23 -250 0 -309 -41 -108 -100 -164 -173 -164 -50 0 -67 17 -88 90 -24 80 -72 370 -92 549 -20 188 -16 257 16 283 32 26 91 24 117 -4z m3353 12 c29 -16 43 -84 36 -170 -20 -223 -80 -593 -112 -693 -18 -54 -36 -67 -93 -67 -53 0 -110 49 -148 128 -22 47 -28 75 -31 154 -7 150 13 217 125 437 52 102 102 194 110 204 18 19 83 23 113 7z m-2675 -1975 c22 -4 67 -21 99 -38 95 -51 142 -134 117 -209 -14 -41 -72 -103 -120 -127 -46 -23 -139 -47 -148 -38 -3 4 5 20 20 35 37 39 59 98 59 162 1 82 -17 134 -62 182 -45 46 -47 51 -22 45 9 -3 35 -8 57 -12z m-199 -36 c-48 -56 -59 -97 -54 -188 5 -78 19 -118 58 -159 12 -13 20 -25 18 -28 -7 -6 -108 26 -137 44 -75 46 -111 99 -111 162 0 49 17 84 63 128 36 35 136 81 175 82 23 0 22 -2 -12 -41z m1984 37 c0 -3 -13 -19 -30 -37 -79 -87 -79 -255 1 -340 16 -18 28 -33 26 -36 -2 -2 -34 6 -72 18 -79 24 -157 89 -176 146 -30 92 44 191 179 239 37 13 72 18 72 10z m223 -16 c60 -23 130 -78 152 -121 19 -36 19 -102 1 -138 -17 -32 -73 -84 -114 -105 -59 -30 -193 -45 -140 -15 10 5 29 30 44 54 54 94 39 240 -33 310 l-36 35 36 0 c20 0 60 -9 90 -20z m-1089 -306 c9 -3 59 -69 113 -146 53 -77 106 -146 118 -154 11 -7 39 -16 60 -19 52 -6 75 -34 75 -92 0 -67 -31 -93 -111 -93 -36 0 -75 7 -96 17 -34 16 -117 106 -170 186 -14 20 -29 37 -33 37 -4 0 -19 -17 -32 -37 -44 -66 -118 -147 -160 -175 -34 -23 -52 -28 -105 -28 -55 0 -68 4 -88 25 -20 19 -25 34 -25 73 0 60 17 78 84 91 57 10 72 26 186 193 44 64 85 119 92 121 19 8 74 8 92 1z"
id="path2" /><path
d="M1130 9411 c-340 -102 -544 -266 -581 -467 -34 -181 103 -365 345 -466 158 -65 303 -89 656 -108 569 -31 954 -31 1065 1 190 54 276 205 195 345 -73 128 -194 193 -509 274 -286 74 -348 98 -515 199 -188 114 -457 243 -515 248 -30 2 -79 -7 -141 -26z"
id="path4" /><path
d="M5105 9354 c-550 -254 -547 -253 -925 -345 -236 -57 -301 -77 -377 -114 -204 -100 -290 -244 -223 -374 39 -78 115 -129 232 -156 99 -23 629 -25 838 -4 52 5 187 14 300 19 292 14 442 43 596 116 222 105 340 285 304 461 -32 154 -131 268 -311 356 -111 54 -240 97 -290 97 -13 -1 -78 -26 -144 -56z"
id="path6" /><path
d="M1200 6430 l0 -1120 165 0 165 0 2 496 3 496 206 -494 207 -493 181 -3 181 -2 -6 27 c-4 16 -12 39 -20 53 -7 14 -116 264 -243 555 l-231 530 216 510 c118 281 220 518 225 527 19 37 13 38 -177 36 l-186 -3 -177 -463 -176 -462 -3 465 -2 465 -165 0 -165 0 0 -1120z"
id="path8" /><path
d="M3005 7528 c-3 -13 -97 -504 -210 -1093 -113 -588 -208 -1082 -211 -1097 l-6 -28 161 0 c89 0 161 3 162 8 0 4 15 97 32 207 l32 200 212 3 213 2 5 -22 c3 -13 16 -95 30 -183 14 -88 28 -172 31 -187 l6 -28 160 0 160 0 -5 23 c-3 12 -99 508 -212 1102 -113 594 -208 1088 -211 1098 -5 15 -22 17 -174 17 -168 0 -170 0 -175 -22z m258 -1010 c43 -266 78 -486 77 -490 0 -5 -75 -8 -166 -8 l-166 0 5 26 c2 14 38 234 78 490 42 263 78 464 84 464 6 0 44 -209 88 -482z"
id="path10" /><path
d="M4150 7399 l0 -150 290 3 c286 3 290 3 284 -17 -4 -11 -144 -402 -312 -870 l-305 -850 -5 -102 -4 -103 516 0 516 0 0 151 0 150 -315 -3 c-173 -2 -315 -2 -315 -1 0 1 120 334 266 740 380 1054 364 1004 364 1113 l0 90 -490 0 -490 0 0 -151z"
id="path12" /><path
d="M1251 4291 c-15 -4 -27 -17 -31 -31 -12 -46 -20 -984 -10 -1269 30 -885 107 -1328 426 -2460 109 -387 161 -468 329 -516 169 -50 310 55 370 275 26 92 31 634 14 1355 -7 308 -13 585 -14 615 l0 55 256 3 257 2 6 -142 c35 -740 202 -1240 531 -1587 69 -73 201 -179 262 -210 100 -50 231 -33 303 39 22 22 42 40 44 40 2 0 9 -37 16 -82 20 -144 63 -245 129 -306 111 -103 309 -85 415 39 68 80 92 145 196 525 282 1027 353 1413 390 2109 16 300 10 1519 -8 1537 -11 11 -373 13 -1935 14 -1057 0 -1933 -2 -1946 -5z m2775 -2093 c-14 -256 -26 -764 -26 -1055 0 -167 -4 -303 -8 -303 -5 0 -17 10 -28 21 -10 12 -47 41 -80 65 -128 92 -247 242 -324 408 -106 228 -160 493 -184 904 l-5 82 330 0 331 0 -6 -122z"
id="path14" /></g><image
width="205.84871"
height="157.69467"
preserveAspectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAaCAYAAACkVDyJAAAABHNCSVQICAgIfAhkiAAABS9JREFU
SIm1lVuIXWcVx39r7332Pmfm3DvNxM5kmlQT05SmtfGhtY2CsUwVCsXavETQF0PBUlosptDigC8q
PlkQFEQiFYQBA0pN6Rh7p2pCmoGWNkY604nJ3M51n9s++7p8mBmZmJNpKvYPH3zs72P9+K+19reE
T1CqavSS/g/S2Pvcbjf7/sKcYf2vwY4/e+DTd5yuHCpV+5/P1P2bvbQxETlWUVvBpT66XCvZSxeO
/2x2z7cfnwLBNi2GrGE+FvCR6UfMJ56ffWjnheqTpefe+UK6E4qoApAgdBWaItt9YPjDhJxRQtec
EiUJYRRdP/DEd/buueuHLx/fcaF5j4QxsulMgb4KTVFqJLgIPlBGieMYP4houm0qtTrm9cBePbLv
q/e+sPDitoX2bkkSZB2yAQ2ApkAVqGLgAh5CXCiRuvseao0mHy4tMbd4+aMdzhz57L0HZuZPZGte
evP3DVgCdBHqQFWglkDHMcLWrsKPLg0tPl/553u/7rXCg+1OV3vqnZKrCJv01FP7h49Nz58f+Vdn
fM3TlVKgh1BBuIyyDNQFlu4sPzb1du3nAN//w09ymahciIKWjBZSq1u6e+e+Hc+oIarCwBUKugo6
i+hJEf2ViP54JNOemtpnXyumca2D6cf275r4R/17qrrWaevp27z3FVoCDVlLZxNwUV26KXN1OtY1
sIYzh/d87XO/n/uFU+2VQhWQjSbZiLPWhcsizKsyJ8JFVVZRPOX87sXcNYFX1fDPD++dvOOl+ZPp
TmiAXnFDAU+go0oVYQ7hA5TLQAXoOLIc31fYe+pUw71uh+b71UNuNzC6CJYIBiCiJCoEKK6CC6wo
LIpSB/qAopj51KmXtoANBJ4rGvMrgC0JGYSMCmkEBzBUCUUwENIiFFWJBNIKRRHidjS7FWywQ1Uz
BEKgB6RQUgoOiiNCWtdcDwtEAomCLdAX6G0bvpWF9pbAK7r06C8PpMYWvEdvQCkBBSCDkBJBRQiA
LtAWaAMdlEAgRlGFUm7Ht154483Xf/OX6bGPBJ44+9qtD9YfnItWvNtc1l4PT5U+CZ4m9FRpozQl
oUFCk4Q24AE+Qmya7H/0u9aNheLBgj1yfGp6atC/KBbAc3/7bb6swzPFB74+3k2XaJ09w9zMDOp5
GKZJ7PtIEBKnLMwgJFUqIuUSQ9tGyeYL7Jy8n+zYBJ86+EXqLZehbvYrE4UDh4AXB9VQCu3yN+K8
jpvFLLuOfJP80aMcsoSw3cW0UwT9PtW5Dxj9zG4un5tl9PbbyI1uBxRUiOOYXt+n3e2hiSKJYoTG
4U1AWV93CRB+aXLSfPLYs7L9hjLlYp5iNksm45C2bUzDQGTwk6uqRHGC7wd0PI9Wu0Ot6bJcqfHX
c6f56dPH4MrBggVYhe0jrFSqJHFMFMWEfkQ+O0QmncGxLSzLwjAEYx2cqKJxTBjH9IOQrtfH7fZo
uC6r9QarjQZ/f/WV/9Ttv1PK0sVL9IOQxZVV3E6HciFPMZcjOzxExrGxbRvLNNeBuuYsiugHIT3P
p93r0Wh1aLZcup7Pe+dnefftswOzIoAapsHd93+ZyYcOUxougIBlmTi2Q8Z2cByHlGVhigECcZIQ
hCF938cPAvpBQBTFxCizZ97iT9O/o7Y8eBJtDG8A7LTD2C07GR0bZ+/+OxmfuBk7ZZPPlYg1wTRM
ZL0iqoqKUKuskLJtXj75R2qVVd49fWYgaCBwkAzTYCiXxet0sTNpRiZuonpxEUMMDMuk03TRZMsQ
Hw/4/9Y1B/AnpX8DQ2J16tSILa8AAAAASUVORK5CYII=
"
id="image136"
x="239.88551"
y="10.151023" /></svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -16,7 +16,7 @@ availableOrga=($(getList "${KAZ_CONF_DIR}/container-orga.list"))
AVAILABLE_ORGAS=${availableOrga[*]//-orga/}
# CLOUD
APPLIS_PAR_DEFAUT="tasks calendar contacts bookmarks mail richdocuments external drawio snappymail ransomware_protection" #rainloop richdocumentscode
APPLIS_PAR_DEFAUT="tasks calendar contacts bookmarks mail richdocuments external drawio ransomware_protection" #rainloop richdocumentscode
QUIET="1"
ONNAS=
@@ -120,10 +120,11 @@ firstInstall(){
}
setOfficeUrl(){
OFFICE_URL="https://${officeHost}.${domain}"
if [ ! "${site}" = "prod1" ]; then
OFFICE_URL="https://${site}-${officeHost}.${domain}"
fi
# Did le 25 mars les offices sont tous normalisé sur les serveurs https://${site}-${officeHost}.${domain}
#OFFICE_URL="https://${officeHost}.${domain}"
#if [ ! "${site}" = "prod1" ]; then
OFFICE_URL="https://${site}-${officeHost}.${domain}"
#fi
occCommand "config:app:set --value $OFFICE_URL richdocuments public_wopi_url"
occCommand "config:app:set --value $OFFICE_URL richdocuments wopi_url"
occCommand "config:app:set --value $OFFICE_URL richdocuments disable_certificate_verification"

View File

@@ -10,12 +10,12 @@ setKazVars
. $DOCKERS_ENV
. $KAZ_ROOT/secret/SetAllPass.sh
. $KAZ_ROOT/secret/env-kaz
NAS_VOL="/mnt/disk-nas1/docker/volumes/"
#TODO: ce tab doit être construit à partir de la liste des machines dispos et pas en dur
tab_sites_destinations_possibles=("kazoulet" "prod2")
tab_sites_destinations_possibles=${TAB_SITES_POSSIBLES}
#par défaut, on prend le premier site
SITE_DST="${tab_sites_destinations_possibles[0]}"
@@ -143,6 +143,4 @@ for orgaLong in ${Orgas}; do
${SIMU} ssh -p 2201 root@${SITE_DST}.${domain} "${KAZ_BIN_DIR}/manageCloud.sh" --officeURL "${orgaCourt}"
fi
done

View File

@@ -0,0 +1,41 @@
#!/bin/bash
#date: 23/04/2025
#ki: fab
#koi: supprimer de acme.json les certificats LE devenus inutiles
KAZ_ROOT=$(cd "$(dirname $0)"/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
FILE_ACME_ORI="/var/lib/docker/volumes/traefik_letsencrypt/_data/acme.json"
FILE_ACME="/tmp/acme.json"
FILE_URL=$(mktemp)
FILE_ACME_TMP=$(mktemp)
#l'ip du serveur:
#marche po pour les machines hébergée chez T.C... :( on récupère l'IP dans config/dockers.env
#MAIN_IP=$(curl ifconfig.me)
#DANGER: IP depuis config/dockers.env ne fonctionne pas pour les domaines hors *.kaz.bzh (ex:radiokalon.fr)
#sauvegarde
cp $FILE_ACME_ORI $FILE_ACME
cp $FILE_ACME "$FILE_ACME"_$(date +%Y%m%d_%H%M%S)
#je cherche toutes les url
jq -r '.letsencrypt.Certificates[].domain.main' $FILE_ACME > $FILE_URL
while read -r url; do
#echo "Traitement de : $url"
nb=$(dig $url | grep $MAIN_IP | wc -l)
if [ "$nb" -eq 0 ]; then
#absent, on vire de acme.json
echo "on supprime "$url
jq --arg url "$url" 'del(.letsencrypt.Certificates[] | select(.domain.main == $url))' $FILE_ACME > $FILE_ACME_TMP
mv -f $FILE_ACME_TMP $FILE_ACME
fi
done < "$FILE_URL"
echo "si satisfait, remettre "$FILE_ACME" dans "$FILE_ACME_ORI

View File

@@ -1,7 +1,7 @@
#! /bin/sh
# date: 12/11/2020
#PATH=/bin:/sbin:/usr/bin:/usr/sbin
PATH=/bin:/sbin:/usr/bin:/usr/sbin
PATH_SAUVE="/home/sauve/"
iptables-save > $PATH_SAUVE/iptables.sav

View File

@@ -1,7 +1,6 @@
#!/bin/bash
# --------------------------------------------------------------------------------------
# Didier
#
# Script de sauvegarde avec BorgBackup
# la commande de creation du dépot est : borg init --encryption=repokey /mnt/backup-nas1/BorgRepo
# la conf de borg est dans /root/.config/borg
@@ -20,7 +19,7 @@ setKazVars
. $DOCKERS_ENV
. $KAZ_ROOT/secret/SetAllPass.sh
VERSION="V-3-11-2024"
VERSION="V-10-03-2025"
PRG=$(basename $0)
RACINE=$(echo $PRG | awk '{print $1}')
#IFS=' '
@@ -72,20 +71,10 @@ LogFic() {
}
#
ExpMail() {
MAIL_SOURCE=$1
MAIL_DEST=$1
MAIL_SUJET=$2
MAIL_DEST=$3
MAIL_TEXTE=$4
# a mettre ailleurs
mailexp=${borg_MAILEXP}
mailpassword=${borg_MAILPASSWORD}
mailserveur=${borg_MAILSERVEUR}
#
#sendemail -t ${MAIL_DEST} -u ${MAIL_SUJET} -m ${MAIL_TEXTE} -f $mailexp -s $mailserveur:587 -xu $mailexp -xp $mailpassword -o tls=yes >/dev/null 2>&1
MAIL_TEXTE=$3
printf "Subject:${MAIL_SUJET}\n${MAIL_TEXTE}" | msmtp ${MAIL_DEST}
#docker exec -i mailServ mailx -a 'Content-Type: text/plain; charset="UTF-8"' -r ${MAIL_SOURCE} -s "${MAIL_SUJET}" ${MAIL_DEST} << EOF
#${MAIL_TEXTE}
#EOF
}
Pre_Sauvegarde() {
@@ -297,7 +286,7 @@ if [ "${REPO_MOUNT_ACTIVE}" = "true" ]
then
echo "le REPO : ${BORG_REPO} est monté , je sors"
LogFic "le REPO : ${BORG_REPO} est monté , je sors"
ExpMail borg@${domain} "${site} : Sauvegarde en erreur" ${MAIL_RAPPORT} "le REPO : ${BORG_REPO} est monté, sauvegarde impossible"
ExpMail ${MAIL_RAPPORT} "${site} : Sauvegarde en erreur" "le REPO : ${BORG_REPO} est monté, sauvegarde impossible"
exit 1
fi
@@ -349,7 +338,7 @@ BorgBackup
"
LogFic " - la sauvegarde est OK"
[ "$MAILOK" = true ] && ExpMail borg@${domain} "${site} : Sauvegarde Ok" ${MAIL_RAPPORT} ${MESS_SAUVE_OK}${LOGDATA}
[ "$MAILOK" = true ] && ExpMail ${MAIL_RAPPORT} "${site} : Sauvegarde Ok" ${MESS_SAUVE_OK}${LOGDATA}
IFS=' '
;;
'1' )
@@ -365,7 +354,7 @@ BorgBackup
"
LogFic " - Sauvegarde en Warning: ${BACKUP_EXIT}"
[ "$MAILWARNING" = true ] && ExpMail borg@${domain} "${site} : Sauvegarde en Warning: ${BACKUP_EXIT}" ${MAIL_RAPPORT} ${MESS_SAUVE_ERR}${LOGDATA}
[ "$MAILWARNING" = true ] && ExpMail ${MAIL_RAPPORT} "${site} : Sauvegarde en Warning: ${BACKUP_EXIT}" ${MESS_SAUVE_ERR}${LOGDATA}
IFS=' '
;;
* )
@@ -381,7 +370,7 @@ BorgBackup
"
LogFic " - !!!!! Sauvegarde en Erreur !!!!! : ${BACKUP_EXIT}"
ExpMail borg@${domain} "${site} : Sauvegarde en Erreur !!!! : ${BACKUP_EXIT}" ${MAIL_RAPPORT} ${MESS_SAUVE_ERR}${LOGDATA}
ExpMail ${MAIL_RAPPORT} "${site} : Sauvegarde en Erreur !!!! : ${BACKUP_EXIT}" ${MESS_SAUVE_ERR}${LOGDATA}
IFS=' '
;;
esac

View File

@@ -30,12 +30,12 @@ while read line ; do
sed "s%\(.*\)--clean_val--\(.*\)%\1${JIRAFEAU_DIR}\2%" <<< ${line}
continue
;;
*DATABASE*)
*DATABASE*|*DB_NAME*)
dbName="$(sed "s/\([^_]*\)_.*/\1/" <<< ${line})_$(apg -n 1 -m 2 -M NCL | cut -c 1-2)"
sed "s/\(.*\)--clean_val--\(.*\)/\1${dbName}\2/" <<< ${line}
continue
;;
*ROOT_PASSWORD*|*PASSWORD*)
*ROOT_PASSWORD*|*PASSWORD*|*SECRET*)
pass="$(apg -n 1 -m 16 -M NCL)"
sed "s/\(.*\)--clean_val--\(.*\)/\1${pass}\2/" <<< ${line}
continue

82
bin/templates/email.css Normal file
View File

@@ -0,0 +1,82 @@
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-content {
background-color: #f0f0f0; /* Light gray background */
margin: 20px auto;
padding: 20px;
border: 1px solid #dddddd;
max-width: 600px;
width: 90%; /* This makes the content take 90% width of its container */
text-align: left; /* Remove text justification */
}
header {
background-color: #E16969;
color: white;
text-align: center;
height: 50px; /* Fixed height for header */
line-height: 50px; /* Vertically center the text */
width: 100%; /* Make header full width */
}
footer {
background-color: #E16969;
color: white;
text-align: center;
height: 50px; /* Fixed height for footer */
line-height: 50px; /* Vertically center the text */
width: 100%; /* Make footer full width */
}
.header-container {
position: relative; /* Pour positionner le logo et le texte dans le header */
height: 50px; /* Hauteur maximale du header */
}
.logo {
position: absolute; /* Pour positionner le logo */
max-height: 100%; /* Taille maximale du logo égale à la hauteur du header */
top: 0; /* Aligner le logo en haut */
left: 0; /* Aligner le logo à gauche */
margin-right: 10px; /* Marge à droite du logo */
}
.header-container h1, .footer-container p {
margin: 0;
font-size: 24px;
}
.footer-container p {
font-size: 12px;
}
.footer-container a {
color: #FFFFFF; /* White color for links in footer */
text-decoration: none;
}
.footer-container a:hover {
text-decoration: underline; /* Optional: add underline on hover */
}
a {
color: #E16969; /* Same color as header/footer background for all other links */
text-decoration: none;
}
a:hover {
text-decoration: underline; /* Optional: add underline on hover */
}
h2 {
color: #E16969;
}
p {
line-height: 1.6;
}

View File

@@ -0,0 +1,9 @@
<footer>
<div class="footer-container">
<p>
Ici, on prend soin de vos données et on ne les vend pas !
<br>
<a href="https://kaz.bzh">https://kaz.bzh</a>
</p>
</div>
</footer>

View File

@@ -0,0 +1,6 @@
<header>
<div class="header-container">
<img class="logo" src="https://kaz-cloud.kaz.bzh/apps/theming/image/logo?v=33" alt="KAZ Logo">
<h1>Kaz : Le numérique sobre, libre, éthique et local</h1>
</div>
</header>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email d'inscription'</title>
<style>
{% include 'email.css' %}
</style>
</head>
<body>
{% include 'email_header.html' %}
<div class="email-content">
<p>
Bonjour {{NOM}}!<br><br>
Bienvenue chez KAZ!<br><br>
Vous disposez de :
<ul>
<li>une messagerie classique : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
<li>une messagerie instantanée pour discuter au sein d'équipes : <a href={{URL_AGORA}}>{{URL_AGORA}}</a></li>
</ul>
Votre email et identifiant pour ces services : {{EMAIL_SOUHAITE}}<br>
Le mot de passe : <b>{{PASSWORD}}</b><br><br>
Pour changer votre mot de passe de messagerie, c'est ici: <a href={{URL_MDP}}>{{URL_MDP}}</a><br>
Si vous avez perdu votre mot de passe, c'est ici: <a href={{URL_MDP}}/?action=sendtoken>{{URL_MDP}}/?action=sendtoken</a><br><br>
Vous pouvez accéder à votre messagerie classique:
<ul>
<li>soit depuis votre webmail : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
<li>soit depuis votre bureau virtuel : <a href={{URL_CLOUD}}>{{URL_CLOUD}}</a></li>
<li>soit depuis un client de messagerie comme thunderbird<br>
</ul>
</p>
{% if ADMIN_ORGA == '1' %}
<p>
En tant qu'association/famille/société. Vous avez la possibilité d'ouvrir, quand vous le voulez, des services kaz, il vous suffit de nous le demander.<br><br>
Pourquoi n'ouvrons-nous pas tous les services tout de suite ? parce que nous aimons la sobriété et que nous préservons notre espace disque ;)<br>
A quoi sert d'avoir un site web si on ne l'utilise pas, n'est-ce pas ?<br><br>
Par retour de mail, dites-nous de quoi vous avez besoin tout de suite entre:
<ul>
<li>une comptabilité : un service de gestion adhérents/clients</li>
<li>un site web de type WordPress</li>
<li>un cloud : bureau virtuel pour stocker des fichiers/calendriers/contacts et partager avec vos connaissances</li>
</ul>
Une fois que vous aurez répondu à ce mail, votre demande sera traitée manuellement.
</p>
{% endif %}
<p>
Vous avez quelques docs intéressantes sur le wiki de kaz:
<ul>
<li>Migrer son site internet wordpress vers kaz : <a href="https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz">https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz</a></li>
<li>Migrer sa messagerie vers kaz : <a href="https://wiki.kaz.bzh/messagerie/gmail/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
<li>Démarrer simplement avec son cloud : <a href="https://wiki.kaz.bzh/nextcloud/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
</ul>
Votre quota est de {{QUOTA}}GB. Si vous souhaitez plus de place pour vos fichiers ou la messagerie, faites-nous signe !<br><br>
Pour accéder à la messagerie instantanée et communiquer avec les membres de votre équipe ou ceux de kaz : <a href={{URL_AGORA}}/login>{{URL_AGORA}}/login</a><br>
</p>
{% if ADMIN_ORGA == '1' %}
<p>
Comme administrateur de votre organisation, vous pouvez créer des listes de diffusion en vous rendant sur <a href={{URL_LISTE}}>{{URL_LISTE}}</a><br>
</p>
{% endif %}
<p>
Enfin, vous disposez de tous les autres services KAZ où l'authentification n'est pas nécessaire : <a href={{URL_SITE}}>{{URL_SITE}}</a><br><br>
En cas de soucis, n'hésitez pas à poser vos questions sur le canal 'Une question ? un soucis' de l'agora dispo ici : <a href={{URL_AGORA}}>{{URL_AGORA}}</a><br><br>
Si vous avez besoin d'accompagnement pour votre site, votre cloud, votre compta, votre migration de messagerie,...<br>nous proposons des formations mensuelles gratuites. Si vous souhaitez être accompagné par un professionnel, nous pouvons vous donner une liste de pros, référencés par KAZ.<br><br>
À bientôt 😉<br><br>
La collégiale de KAZ.<br>
</p>
</div> <!-- <div class="email-content"> -->
{% include 'email_footer.html' %}
</body>
</html>

View File

@@ -0,0 +1,70 @@
Bonjour {{NOM}}!
Bienvenue chez KAZ!<br><br>
Vous disposez de :
<ul>
<li>une messagerie classique : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
<li>une messagerie instantanée pour discuter au sein d'équipes : <a href={{URL_AGORA}}>{{URL_AGORA}}</a></li>
</ul>
Votre email et identifiant pour ces services : {{EMAIL_SOUHAITE}}<br>
Le mot de passe : <b>{{PASSWORD}}</b><br><br>
Pour changer votre mot de passe de messagerie, c'est ici: <a href={{URL_MDP}}>{{URL_MDP}}</a><br>
Si vous avez perdu votre mot de passe, c'est ici: <a href={{URL_MDP}}/?action=sendtoken>{{URL_MDP}}/?action=sendtoken</a><br><br>
Vous pouvez accéder à votre messagerie classique:
<ul>
<li>soit depuis votre webmail : <a href={{URL_WEBMAIL}}>{{URL_WEBMAIL}}</a></li>
<li>soit depuis votre bureau virtuel : <a href={{URL_CLOUD}}>{{URL_CLOUD}}</a></li>
<li>soit depuis un client de messagerie comme thunderbird<br>
</ul>
</p>
{% if ADMIN_ORGA == '1' %}
<p>
En tant qu'association/famille/société. Vous avez la possibilité d'ouvrir, quand vous le voulez, des services kaz, il vous suffit de nous le demander.<br><br>
Pourquoi n'ouvrons-nous pas tous les services tout de suite ? parce que nous aimons la sobriété et que nous préservons notre espace disque ;)<br>
A quoi sert d'avoir un site web si on ne l'utilise pas, n'est-ce pas ?<br><br>
Par retour de mail, dites-nous de quoi vous avez besoin tout de suite entre:
<ul>
<li>une comptabilité : un service de gestion adhérents/clients</li>
<li>un site web de type WordPress</li>
<li>un cloud : bureau virtuel pour stocker des fichiers/calendriers/contacts et partager avec vos connaissances</li>
</ul>
Une fois que vous aurez répondu à ce mail, votre demande sera traitée manuellement.
</p>
{% endif %}
<p>
Vous avez quelques docs intéressantes sur le wiki de kaz:
<ul>
<li>Migrer son site internet wordpress vers kaz : <a href="https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz">https://wiki.kaz.bzh/wordpress/start#migrer_son_site_wordpress_vers_kaz</a></li>
<li>Migrer sa messagerie vers kaz : <a href="https://wiki.kaz.bzh/messagerie/gmail/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
<li>Démarrer simplement avec son cloud : <a href="https://wiki.kaz.bzh/nextcloud/start">https://wiki.kaz.bzh/messagerie/gmail/start</a></li>
</ul>
Votre quota est de {{QUOTA}}GB. Si vous souhaitez plus de place pour vos fichiers ou la messagerie, faites-nous signe !<br><br>
Pour accéder à la messagerie instantanée et communiquer avec les membres de votre équipe ou ceux de kaz : <a href={{URL_AGORA}}/login>{{URL_AGORA}}/login</a><br>
</p>
{% if ADMIN_ORGA == '1' %}
<p>
Comme administrateur de votre organisation, vous pouvez créer des listes de diffusion en vous rendant sur <a href={{URL_LISTE}}>{{URL_LISTE}}</a><br>
</p>
{% endif %}
<p>
Enfin, vous disposez de tous les autres services KAZ où l'authentification n'est pas nécessaire : <a href={{URL_SITE}}>{{URL_SITE}}</a><br><br>
En cas de soucis, n'hésitez pas à poser vos questions sur le canal 'Une question ? un soucis' de l'agora dispo ici : <a href={{URL_AGORA}}>{{URL_AGORA}}</a><br><br>
Si vous avez besoin d'accompagnement pour votre site, votre cloud, votre compta, votre migration de messagerie,...<br>nous proposons des formations mensuelles gratuites. Si vous souhaitez être accompagné par un professionnel, nous pouvons vous donner une liste de pros, référencés par KAZ.<br><br>
À bientôt 😉<br><br>
La collégiale de KAZ.<br>

View File

@@ -84,7 +84,6 @@ jirafeauUpdate(){
updateEnvDB "etherpad" "${KAZ_KEY_DIR}/env-${etherpadDBName}" "${etherpadDBName}"
updateEnvDB "framadate" "${KAZ_KEY_DIR}/env-${framadateDBName}" "${framadateDBName}"
updateEnvDB "gitea" "${KAZ_KEY_DIR}/env-${gitDBName}" "${gitDBName}"
updateEnvDB "mattermost" "${KAZ_KEY_DIR}/env-${mattermostDBName}" "${mattermostDBName}"
updateEnvDB "nextcloud" "${KAZ_KEY_DIR}/env-${nextcloudDBName}" "${nextcloudDBName}"
updateEnvDB "roundcube" "${KAZ_KEY_DIR}/env-${roundcubeDBName}" "${roundcubeDBName}"
updateEnvDB "sympa" "${KAZ_KEY_DIR}/env-${sympaDBName}" "${sympaDBName}"
@@ -92,6 +91,8 @@ updateEnvDB "vigilo" "${KAZ_KEY_DIR}/env-${vigiloDBName}" "${vigiloDBName}"
updateEnvDB "wp" "${KAZ_KEY_DIR}/env-${wordpressDBName}" "${wordpressDBName}"
updateEnvDB "vaultwarden" "${KAZ_KEY_DIR}/env-${vaultwardenDBName}" "${vaultwardenDBName}"
updateEnvDB "castopod" "${KAZ_KEY_DIR}/env-${castopodDBName}" "${castopodDBName}"
updateEnvDB "spip" "${KAZ_KEY_DIR}/env-${spipDBName}" "${spipDBName}"
updateEnvDB "mastodon" "${KAZ_KEY_DIR}/env-${mastodonDBName}" "${mastodonDBName}"
updateEnv "apikaz" "${KAZ_KEY_DIR}/env-${apikazServName}"
updateEnv "ethercalc" "${KAZ_KEY_DIR}/env-${ethercalcServName}"
@@ -101,6 +102,7 @@ updateEnv "gandi" "${KAZ_KEY_DIR}/env-gandi"
updateEnv "gitea" "${KAZ_KEY_DIR}/env-${gitServName}"
updateEnv "jirafeau" "${KAZ_KEY_DIR}/env-${jirafeauServName}"
updateEnv "mattermost" "${KAZ_KEY_DIR}/env-${mattermostServName}"
updateEnv "mattermost" "${KAZ_KEY_DIR}/env-${mattermostDBName}"
updateEnv "nextcloud" "${KAZ_KEY_DIR}/env-${nextcloudServName}"
updateEnv "office" "${KAZ_KEY_DIR}/env-${officeServName}"
updateEnv "roundcube" "${KAZ_KEY_DIR}/env-${roundcubeServName}"
@@ -113,7 +115,11 @@ updateEnv "mobilizon" "${KAZ_KEY_DIR}/env-${mobilizonServName}"
updateEnv "mobilizon" "${KAZ_KEY_DIR}/env-${mobilizonDBName}"
updateEnv "vaultwarden" "${KAZ_KEY_DIR}/env-${vaultwardenServName}"
updateEnv "castopod" "${KAZ_KEY_DIR}/env-${castopodServName}"
updateEnv "spip" "${KAZ_KEY_DIR}/env-${spipServName}"
updateEnv "ldap" "${KAZ_KEY_DIR}/env-${ldapUIName}"
updateEnv "peertube" "${KAZ_KEY_DIR}/env-${peertubeServName}"
updateEnv "peertube" "${KAZ_KEY_DIR}/env-${peertubeDBName}" "${peertubeDBName}"
updateEnv "mastodon" "${KAZ_KEY_DIR}/env-${mastodonServName}"
framadateUpdate

View File

@@ -1,2 +1,2 @@
proxy
#traefik
# proxy
traefik

View File

@@ -4,7 +4,7 @@ dokuwiki
paheko
gitea
jirafeau
mattermost
#mattermost
roundcube
mobilizon
vaultwarden

View File

@@ -4,3 +4,4 @@ collabora
etherpad
web
imapsync
spip

View File

@@ -93,13 +93,15 @@ vaultwardenHost=koffre
traefikHost=dashboard
imapsyncHost=imapsync
castopodHost=pod
spipHost=spip
mastodonHost=masto
apikazHost=apikaz
snappymailHost=snappymail
########################################
# ports internes
matterPort=8000
matterPort=8065
imapsyncPort=8080
apikaz=5000
@@ -147,6 +149,10 @@ ldapUIName=ldapUI
imapsyncServName=imapsyncServ
castopodDBName=castopodDB
castopodServName=castopodServ
mastodonServName=mastodonServ
spipDBName=spipDB
spipServName=spipServ
mastodonDBName=mastodonDB
apikazServName=apikazServ
########################################

View File

@@ -13,6 +13,8 @@ services:
- orgaDB:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
environment:
- MARIADB_AUTO_UPGRADE=1
env_file:
- ../../secret/env-${nextcloudDBName}
# - ../../secret/env-${mattermostDBName}
@@ -23,7 +25,8 @@ services:
#maridb10.5
#test: ["CMD", 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p$$MYSQL_ROOT_PASSWORD' ]
#maridb11.4
test: ["CMD", 'healthcheck.sh', '--su-mysql', '--connect', '--innodb_initialized']
#test: ["CMD", 'healthcheck.sh', '--su-mysql', '--connect', '--innodb_initialized']
test: ["CMD", "mariadb-admin", "ping", "--silent"]
interval: 30s
timeout: 30s
retries: 5
@@ -213,6 +216,31 @@ services:
- ../../secret/env-${castopodServName}
command: --requirepass ${castopodRedisPassword}
#}}
#{{spip
spip:
image: ipeos/spip:4.4
restart: ${restartPolicy}
depends_on:
- db
links:
- db
env_file:
- ../../secret/env-${spipServName}
environment:
- SPIP_AUTO_INSTALL=1
- SPIP_DB_HOST=db
- SPIP_SITE_ADDRESS=https://${orga}${spipHost}.${domain}
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.${orga}${spipServName}.rule=Host(`${orga}${spipHost}.${domain}`){{FOREIGN_SPIP}}"
networks:
- orgaNet
volumes:
- spip:/usr/src/spip
#}}
@@ -295,8 +323,13 @@ volumes:
castopodCache:
external: true
name: orga_${orga}castopodCache
#}}
#{{spip
spip:
external: true
name: orga_${orga}spip
#}}
networks:

View File

@@ -68,6 +68,18 @@ GRANT ALL ON ${castopod_MYSQL_DATABASE}.* TO '${castopod_MYSQL_USER}'@'%' IDENTI
FLUSH PRIVILEGES;"
;;
'spip' )
SQL="$SQL
CREATE DATABASE IF NOT EXISTS ${spip_MYSQL_DATABASE};
DROP USER IF EXISTS '${spip_MYSQL_USER}';
CREATE USER '${spip_MYSQL_USER}'@'%';
GRANT ALL ON ${spip_MYSQL_DATABASE}.* TO '${spip_MYSQL_USER}'@'%' IDENTIFIED BY '${spip_MYSQL_PASSWORD}';
FLUSH PRIVILEGES;"
;;
esac
done

View File

@@ -37,3 +37,7 @@ docker volume create --name=orga_${orga}wordpress
docker volume create --name=orga_${orga}castopodCache
docker volume create --name=orga_${orga}castopodMedia
#}}
#{{spip
docker volume create --name=orga_${orga}spip
#}}

View File

@@ -20,7 +20,7 @@ STAGE_CREATE=
STAGE_INIT=
usage(){
echo "Usage: $0 [-h] [-l] [+/-paheko] [-/+cloud [-/+collabora}]] [+/-agora] [+/-wiki] [+/-wp] [+/-pod] [x{G/M/k}] OrgaName"
echo "Usage: $0 [-h] [-l] [+/-paheko] [-/+cloud [-/+collabora}]] [+/-agora] [+/-wiki] [+/-wp] [+/-pod] [+/-spip] [x{G/M/k}] OrgaName"
echo " -h|--help : this help"
echo " -l|--list : list service"
@@ -34,6 +34,7 @@ usage(){
echo " +/- wiki : on/off wiki"
echo " +/- wp|word* : on/off wp"
echo " +/- casto*|pod : on/off castopod"
echo " +/- spip : on/off spip"
echo " x[GMk] : set quota"
echo " OrgaName : name must contain a-z0-9_\-"
}
@@ -141,6 +142,7 @@ export agora=$(flagInCompose docker-compose.yml agora: off)
export wiki=$(flagInCompose docker-compose.yml dokuwiki: off)
export wp=$(flagInCompose docker-compose.yml wordpress: off)
export castopod=$(flagInCompose docker-compose.yml castopod: off)
export spip=$(flagInCompose docker-compose.yml spip: off)
export db="off"
export services="off"
export paheko=$([[ -f usePaheko ]] && echo "on" || echo "off")
@@ -159,7 +161,7 @@ INITCMD2="--install"
for ARG in "$@"; do
case "${ARG}" in
'-show' )
for i in cloud collabora agora wiki wp castopod db; do
for i in cloud collabora agora wiki wp castopod spip db; do
echo "${i}=${!i}"
done
exit;;
@@ -225,6 +227,11 @@ for ARG in "$@"; do
DBaInitialiser="$DBaInitialiser castopod"
INITCMD2="$INITCMD2 -pod"
;;
'+spip' )
spip="on"
DBaInitialiser="$DBaInitialiser spip"
;;
[.0-9]*[GMk] )
quota="${ARG}"
;;
@@ -262,6 +269,7 @@ fi
if [[ "${paheko}" = "on" ]]; then
touch usePaheko
mkdir -p /var/lib/docker/volumes/paheko_assoUsers/_data/${ORGA}
chown www-data:www-data /var/lib/docker/volumes/paheko_assoUsers/_data/${ORGA} -R
ADD_DOMAIN+="${ORGA}-${pahekoHost} "
else
rm -f usePaheko
@@ -303,6 +311,13 @@ if [[ "${castopod}" = "on" ]]; then
else
DEL_DOMAIN+="${ORGA}-${castopodHost} "
fi
if [[ "${spip}" = "on" ]]; then
DOMAIN_AREA+=" - ${ORGA}-\${spipServName}:${ORGA}-\${spipHost}.\${domain}\n"
ADD_DOMAIN+="${ORGA}-${spipHost} "
else
DEL_DOMAIN+="${ORGA}-${spipHost} "
fi
DOMAIN_AREA+="}}\n"
if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
@@ -357,6 +372,9 @@ update() {
sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
FOREIGN_POD=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/pod_kaz_map" 2>/dev/null | \
sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
FOREIGN_SPIP=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/spip_kaz_map" 2>/dev/null | \
sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
awk '
BEGIN {cp=1}
/#}}/ {cp=1 ; next};
@@ -370,6 +388,7 @@ update() {
-e "s/{{FOREIGN_NC}}/${FOREIGN_NC}/"\
-e "s/{{FOREIGN_DW}}/${FOREIGN_DW}/"\
-e "s/{{FOREIGN_POD}}/${FOREIGN_POD}/"\
-e "s/{{FOREIGN_SPIP}}/${FOREIGN_SPIP}/"\
-e "s|\${orga}|${ORGA}-|g"
) > "$2"
sed "s/storage_opt:.*/storage_opt: ${quota}/g" -i "$2"

View File

@@ -1,6 +1,6 @@
yo, ceci est l'api de kaz !
https://apikaz.kazkouil.fr/
https://apikaz.DEV/
Je pars de ça: python api + docker-compose: https://dev.to/alissonzampietro/the-amazing-journey-of-docker-compose-17lj
@@ -14,6 +14,7 @@ autre piste: abandonnée pour l'instant. trop jeune ?
Documentation (OpenApi remplace swagger)
https://pypi.org/project/flask-openapi3/
autre piste ? https://github.com/fastapi/fastapi (mais y a du node :( )
TODO:
* sécurisation de l'API : un token ? otp ?

View File

@@ -38,8 +38,6 @@ gandi_url_api=os.environ.get('gandi_GANDI_API')
#kaz_user
site_url=os.environ.get('site_url')
#pour webmail_url et mdp_url, ça renvoie des tuples et non des str, bizarre, du coup, je mets en dur
#webmail_url=os.environ.get('webmail_url'),
#mdp_url=os.environ.get('mdp_url'),
webmail_url='https://webmail.kaz.bzh',
mdp_url='https://mdp.kazkouil.fr',
#pour webmail_url et mdp_url, ça renvoie des tuples et non des str, bizarre, il fat mettre les url en dur
webmail_url=os.environ.get('webmail_url')
mdp_url=os.environ.get('mdp_url')

View File

@@ -9,7 +9,7 @@ class Quota(Resource):
#https://doc.dovecot.org/configuration_manual/authentication/master_users/
#https://blog.debugo.fr/serveur-messagerie-dovecot/
# sur kazkouil.fr, j'ai modifié /etc/dovecot/conf.d/20-lmtp.conf
# sur DEV, j'ai modifié /etc/dovecot/conf.d/20-lmtp.conf
#mail_plugins = $mail_plugins sieve quota
@jwt_required()

View File

@@ -35,7 +35,7 @@ class Test(Resource):
auth = (self.paheko_ident, self.paheko_pass)
api_url = self.paheko_url + '/api/sql/'
payload = { "sql": f"select * from users where id_category <> 13 and email='fab@kazkouil.fr'" }
payload = { "sql": f"select * from users where id_category <> 13 and email='MONEMAIL@perso'" }
#payload = { "sql": f"select * from users where id_category <> 13 " }
response = requests.post(api_url, auth=auth, data=payload)

View File

@@ -0,0 +1,42 @@
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.52.0
container_name: cadvisor
command:
- "--store_container_labels=false"
- "--whitelisted_container_labels=com.docker.compose.project"
- "--housekeeping_interval=60s"
- "--docker_only=true"
- "--disable_metrics=percpu,sched,tcp,udp,disk,diskIO,hugetlb,referenced_memory,cpu_topology,resctrl"
networks:
- traefikNet
labels:
- "traefik.enable=true"
- "traefik.http.routers.cadvisor-secure.entrypoints=websecure"
- "traefik.http.routers.cadvisor-secure.rule=Host(`cadvisor-${site}.${domain}`)"
#- "traefik.http.routers.grafana-secure.tls=true"
- "traefik.http.routers.cadvisor-secure.service=cadvisor"
- "traefik.http.routers.cadvisor-secure.middlewares=test-adminipallowlist@file"
- "traefik.http.services.cadvisor.loadbalancer.server.port=8080"
- "traefik.docker.network=traefikNet"
# ports:
# - 8098:8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg
privileged: true
restart: unless-stopped
networks:
traefikNet:
external: true
name: traefikNet

102
dockers/cloud/up.sh Normal file
View File

@@ -0,0 +1,102 @@
#!/bin/bash
KAZ_ROOT=$(cd $(dirname $0)/../..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
. "${DOCKERS_ENV}"
. $KAZ_ROOT/secret/SetAllPass.sh
#"${KAZ_BIN_DIR}/initCloud.sh"
docker exec -ti -u 33 nextcloudServ /var/www/html/occ app:enable user_ldap
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:delete-config s01
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:create-empty-config
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapAgentName cn=cloud,ou=applications,${ldap_root}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapAgentPassword ${ldap_LDAP_CLOUD_PASSWORD}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapAgentPassword ${ldap_LDAP_CLOUD_PASSWORD}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapBase ${ldap_root}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapBaseGroups ${ldap_root}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapBaseUsers ou=users,${ldap_root}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapExpertUsernameAttr identifiantKaz
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapHost ${ldapServName}
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapPort 389
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapTLS 0
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapLoginFilter "(&(objectclass=nextcloudAccount)(|(cn=%uid)(identifiantKaz=%uid)))"
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapQuotaAttribute nextcloudQuota
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapUserFilter "(&(objectclass=nextcloudAccount)(nextcloudEnabled=TRUE))"
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapUserFilterObjectclass nextcloudAccount
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapEmailAttribute mail
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapUserDisplayName cn
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapUserFilterMode 1
docker exec -ti -u 33 nextcloudServ /var/www/html/occ ldap:set-config s01 ldapConfigurationActive 1
# Dans le mariadb, pour permettre au ldap de reprendre la main : delete from oc_users where uid<>'admin';
# docker exec -i nextcloudDB mysql --user=<user> --password=<password> <db> <<< "delete from oc_users where uid<>'admin';"
# Doc : https://help.nextcloud.com/t/migration-to-ldap-keeping-users-and-data/13205
# Exemple de table/clés :
# +-------------------------------+----------------------------------------------------------+
# | Configuration | s01 |
# +-------------------------------+----------------------------------------------------------+
# | hasMemberOfFilterSupport | 0 |
# | homeFolderNamingRule | |
# | lastJpegPhotoLookup | 0 |
# | ldapAgentName | cn=cloud,ou=applications,dc=kaz,dc=sns |
# | ldapAgentPassword | *** |
# | ldapAttributesForGroupSearch | |
# | ldapAttributesForUserSearch | |
# | ldapBackgroundHost | |
# | ldapBackgroundPort | |
# | ldapBackupHost | |
# | ldapBackupPort | |
# | ldapBase | ou=users,dc=kaz,dc=sns |
# | ldapBaseGroups | ou=users,dc=kaz,dc=sns |
# | ldapBaseUsers | ou=users,dc=kaz,dc=sns |
# | ldapCacheTTL | 600 |
# | ldapConfigurationActive | 1 |
# | ldapConnectionTimeout | 15 |
# | ldapDefaultPPolicyDN | |
# | ldapDynamicGroupMemberURL | |
# | ldapEmailAttribute | mail |
# | ldapExperiencedAdmin | 0 |
# | ldapExpertUUIDGroupAttr | |
# | ldapExpertUUIDUserAttr | |
# | ldapExpertUsernameAttr | uid |
# | ldapExtStorageHomeAttribute | |
# | ldapGidNumber | gidNumber |
# | ldapGroupDisplayName | cn |
# | ldapGroupFilter | |
# | ldapGroupFilterGroups | |
# | ldapGroupFilterMode | 0 |
# | ldapGroupFilterObjectclass | |
# | ldapGroupMemberAssocAttr | |
# | ldapHost | ldap |
# | ldapIgnoreNamingRules | |
# | ldapLoginFilter | (&(|(objectclass=nextcloudAccount))(cn=%uid)) |
# | ldapLoginFilterAttributes | |
# | ldapLoginFilterEmail | 0 |
# | ldapLoginFilterMode | 0 |
# | ldapLoginFilterUsername | 1 |
# | ldapMatchingRuleInChainState | unknown |
# | ldapNestedGroups | 0 |
# | ldapOverrideMainServer | |
# | ldapPagingSize | 500 |
# | ldapPort | 389 |
# | ldapQuotaAttribute | nextcloudQuota |
# | ldapQuotaDefault | |
# | ldapTLS | 0 |
# | ldapUserAvatarRule | default |
# | ldapUserDisplayName | cn |
# | ldapUserDisplayName2 | |
# | ldapUserFilter | (&(objectclass=nextcloudAccount)(nextcloudEnabled=TRUE)) |
# | ldapUserFilterGroups | |
# | ldapUserFilterMode | 1 |
# | ldapUserFilterObjectclass | nextcloudAccount |
# | ldapUuidGroupAttribute | auto |
# | ldapUuidUserAttribute | auto |
# | turnOffCertCheck | 0 |
# | turnOnPasswordChange | 0 |
# | useMemberOfToDetectMembership | 1 |
# +-------------------------------+----------------------------------------------------------+

View File

@@ -15,6 +15,8 @@ services:
environment:
- dictionaries=fr_FR en_GB es_ES
- aliasgroup1=https://.*${cloudHost}.${domain}:443
# test did sur un cloud distant
- aliasgroup2=https://cloud.bodam.fr:443
# si on veut ajouter d'autres domaines autorisés pour certaines orgas:
# - aliasgroup2=https://autre-domaine1:443
# - aliasgroup3=https://autre-domaine2:443

View File

@@ -27,11 +27,13 @@ services:
- "traefik.docker.network=giteaNet"
db:
image: mariadb:10.5
image: mariadb
container_name: ${gitDBName}
restart: ${restartPolicy}
env_file:
- ../../secret/env-${gitDBName}
environment:
- MARIADB_AUTO_UPGRADE=1
volumes:
- gitDB:/var/lib/mysql
- /etc/timezone:/etc/timezone:ro

View File

@@ -1,7 +1,7 @@
services:
prometheus:
image: prom/prometheus:v2.15.2
image: prom/prometheus:v3.3.0
restart: unless-stopped
container_name: ${prometheusServName}
volumes:
@@ -10,27 +10,27 @@ services:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
command:
- "--web.route-prefix=/"
- "--web.external-url=https://${site}.${domain}/prometheus"
# - "--web.route-prefix=/"
# - "--web.external-url=https://prometheus.${domain}"
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
networks:
- traefikNet
labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus-secure.entrypoints=websecure"
- "traefik.http.middlewares.prometheus-stripprefix.stripprefix.prefixes=/prometheus"
- "traefik.http.routers.prometheus-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/prometheus`)"
# - "traefik.http.routers.prometheus-secure.tls=true"
- "traefik.http.routers.prometheus-secure.middlewares=prometheus-stripprefix,test-adminiallowlist@file,traefik-auth"
- "traefik.http.routers.prometheus-secure.service=prometheus"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
- "traefik.docker.network=traefikNet"
# labels:
# - "traefik.enable=true"
# - "traefik.http.routers.prometheus-secure.entrypoints=websecure"
# - "traefik.http.middlewares.prometheus-stripprefix.stripprefix.prefixes=/prometheus"
# - "traefik.http.routers.prometheus-secure.rule=Host(`prometheus.${domain}`)"
# # - "traefik.http.routers.prometheus-secure.tls=true"
# - "traefik.http.routers.prometheus-secure.middlewares=prometheus-stripprefix,test-adminiallowlist@file,traefik-auth"
# - "traefik.http.routers.prometheus-secure.service=prometheus"
# - "traefik.http.services.prometheus.loadbalancer.server.port=9090"
# - "traefik.docker.network=traefikNet"
grafana:
image: grafana/grafana:6.6.1
image: grafana/grafana:11.6.0
restart: unless-stopped
container_name: ${grafanaServName}
volumes:
@@ -48,8 +48,8 @@ services:
- "traefik.enable=true"
- "traefik.http.routers.grafana-secure.entrypoints=websecure"
- "traefik.http.middlewares.grafana-stripprefix.stripprefix.prefixes=/grafana"
- "traefik.http.routers.grafana-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/grafana`)"
# - "traefik.http.routers.grafana-secure.tls=true"
- "traefik.http.routers.grafana-secure.rule=Host(`grafana.${domain}`)"
#- "traefik.http.routers.grafana-secure.tls=true"
- "traefik.http.routers.grafana-secure.service=grafana"
- "traefik.http.routers.grafana-secure.middlewares=grafana-stripprefix,test-adminipallowlist@file,traefik-auth"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,874 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "Prometheus",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__elements": {},
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "11.6.0"
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "stat",
"name": "Stat",
"version": ""
},
{
"type": "panel",
"id": "timeseries",
"name": "Time series",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Docker monitoring with Prometheus and cAdvisor",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 1,
"id": null,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [],
"targetBlank": true,
"title": "Portainer",
"tooltip": "",
"type": "link",
"url": "https://portainer.kaz.bzh/"
}
],
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 8,
"panels": [],
"repeat": "host",
"title": "$host",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 8,
"x": 0,
"y": 1
},
"id": 7,
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "count(container_last_seen{image!=\"\", host=\"$host\"})",
"intervalFactor": 2,
"legendFormat": "",
"metric": "container_last_seen",
"range": true,
"refId": "A",
"step": 240
}
],
"title": "Running containers",
"transparent": true,
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "mbytes"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 8,
"x": 8,
"y": 1
},
"id": 5,
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "sum(container_memory_usage_bytes{image!=\"\", host=\"$host\"})/1024/1024",
"intervalFactor": 2,
"legendFormat": "",
"metric": "container_memory_usage_bytes",
"range": true,
"refId": "A",
"step": 240
}
],
"title": "Total Memory Usage",
"transparent": true,
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 8,
"x": 16,
"y": 1
},
"id": 6,
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "sum(rate(container_cpu_user_seconds_total{image!=\"\", host=\"$host\"}[5m]) * 100)",
"intervalFactor": 2,
"legendFormat": "",
"metric": "container_memory_usage_bytes",
"range": true,
"refId": "A",
"step": 240
}
],
"title": "Total CPU Usage",
"transparent": true,
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"links": [
{
"oneClick": false,
"targetBlank": true,
"title": "Portainer host",
"url": "https://portainer.kaz.bzh/#!/${__field.labels.portainer_id}/docker/containers"
},
{
"targetBlank": true,
"title": "Portainer container",
"url": "https://portainer.kaz.bzh/#!/${__field.labels.portainer_id}/docker/containers/${__field.labels.id.21}${__field.labels.id.22}${__field.labels.id.23}${__field.labels.id.24}${__field.labels.id.25}${__field.labels.id.26}${__field.labels.id.27}${__field.labels.id.28}${__field.labels.id.29}${__field.labels.id.30}${__field.labels.id.31}${__field.labels.id.32}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": [
{
"__systemRef": "hideSeriesFrom",
"matcher": {
"id": "byNames",
"options": {
"mode": "exclude",
"names": [
"lagalette-orga/lagalette-wpServ"
],
"prefix": "All except:",
"readOnly": true
}
},
"properties": [
{
"id": "custom.hideFrom",
"value": {
"legend": false,
"tooltip": false,
"viz": true
}
}
]
}
]
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 4
},
"id": 2,
"options": {
"legend": {
"calcs": [
"mean",
"lastNotNull"
],
"displayMode": "table",
"placement": "right",
"showLegend": true,
"sortBy": "Mean",
"sortDesc": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "rate(container_cpu_user_seconds_total{image!=\"\", host=\"$host\"}[5m]) * 100",
"intervalFactor": 2,
"legendFormat": "{{container_label_com_docker_compose_project}}/{{name}}",
"metric": "cpu",
"range": true,
"refId": "A",
"step": 10
}
],
"title": "CPU Usage",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"links": [
{
"targetBlank": true,
"title": "Portainer host",
"url": "https://portainer.kaz.bzh/#!/${__field.labels.portainer_id}/docker/containers"
},
{
"targetBlank": true,
"title": "Portainer container",
"url": "https://portainer.kaz.bzh/#!/${__field.labels.portainer_id}/docker/containers/${__field.labels.id.21}${__field.labels.id.22}${__field.labels.id.23}${__field.labels.id.24}${__field.labels.id.25}${__field.labels.id.26}${__field.labels.id.27}${__field.labels.id.28}${__field.labels.id.29}${__field.labels.id.30}${__field.labels.id.31}${__field.labels.id.32}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 11
},
"id": 1,
"links": [
{
"targetBlank": true,
"title": "Portainer",
"url": "https://portainer.kaz.bzh"
}
],
"options": {
"legend": {
"calcs": [
"mean",
"lastNotNull"
],
"displayMode": "table",
"placement": "right",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "builder",
"expr": "container_memory_usage_bytes{image!=\"\", host=\"$host\"}",
"hide": false,
"intervalFactor": 2,
"legendFormat": "{{container_label_com_docker_compose_project}}/{{name}}",
"metric": "container_memory_usage_bytes",
"range": true,
"refId": "A",
"step": 10
}
],
"title": "Memory Usage",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "Bps"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 18
},
"id": 3,
"options": {
"legend": {
"calcs": [
"mean",
"lastNotNull"
],
"displayMode": "table",
"placement": "right",
"showLegend": true,
"sortBy": "Mean",
"sortDesc": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "irate(container_network_receive_bytes_total{image!=\"\", host=\"$host\"}[5m])",
"intervalFactor": 2,
"legendFormat": "{{container_label_com_docker_compose_project}}/{{name}}",
"metric": "container_network_receive_bytes_total",
"range": true,
"refId": "A",
"step": 20
}
],
"title": "Network Rx",
"transformations": [
{
"id": "renameByRegex",
"options": {
"regex": "(.*)",
"renamePattern": "$1"
}
}
],
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "Bps"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 18
},
"id": 9,
"options": {
"legend": {
"calcs": [
"mean",
"lastNotNull"
],
"displayMode": "table",
"placement": "right",
"showLegend": true,
"sortBy": "Mean",
"sortDesc": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"expr": "irate(container_network_transmit_bytes_total{image!=\"\", host=\"$host\"}[5m])",
"hide": false,
"intervalFactor": 2,
"legendFormat": "{{container_label_com_docker_compose_project}}/{{name}}",
"metric": "container_network_receive_bytes_total",
"range": true,
"refId": "B",
"step": 20
}
],
"title": "Network Tx",
"type": "timeseries"
}
],
"refresh": "30s",
"schemaVersion": 41,
"tags": [],
"templating": {
"list": [
{
"allowCustomValue": false,
"current": {},
"definition": "label_values(host)",
"includeAll": true,
"multi": true,
"name": "host",
"options": [],
"query": {
"qryType": 1,
"query": "label_values(host)",
"refId": "PrometheusVariableQueryEditor-VariableQuery"
},
"refresh": 1,
"regex": "",
"type": "query"
},
{
"baseFilters": [],
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"filters": [
{
"condition": "",
"key": "container_label_com_docker_compose_project",
"keyLabel": "container_label_com_docker_compose_project",
"operator": "=~",
"value": ".*",
"valueLabels": [
".*"
]
}
],
"hide": 1,
"name": "filter",
"type": "adhoc"
}
]
},
"time": {
"from": "now-3h",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Docker monitoring par host",
"uid": "eekgch7tdq8sgc",
"version": 29,
"weekStart": ""
}

View File

@@ -0,0 +1,442 @@
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "Bps"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 14
},
"id": 84,
"options": {
"legend": {
"calcs": [
"mean",
"lastNotNull",
"max",
"min"
],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus"
},
"editorMode": "code",
"expr": "rate(node_network_receive_bytes_total{host=\"$host\", device=~\"$device\"}[5m])",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{device}} - rx",
"range": true,
"refId": "A",
"step": 240
},
{
"datasource": {
"type": "prometheus"
},
"editorMode": "code",
"expr": "- rate(node_network_transmit_bytes_total{host=\"$host\", device=~\"$device\"}[5m])",
"hide": false,
"instant": false,
"legendFormat": "{{device}} - tx",
"range": true,
"refId": "B"
}
],
"title": "Network Traffic Rx",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"links": [],
"mappings": [],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 14
},
"id": 174,
"options": {
"alertThreshold": true,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"datasource": {
"type": "prometheus"
},
"editorMode": "code",
"expr": "(node_filesystem_size_bytes{host=\"$host\",fstype=~\"ext.*|xfs\",mountpoint !~\".*pod.*\"}-node_filesystem_free_bytes{host=\"$host\",fstype=~\"ext.*|xfs\",mountpoint !~\".*pod.*\"}) *100/(node_filesystem_avail_bytes{host=\"$host\",fstype=~\"ext.*|xfs\",mountpoint !~\".*pod.*\"}+(node_filesystem_size_bytes{host=\"$host\",fstype=~\"ext.*|xfs\",mountpoint !~\".*pod.*\"}-node_filesystem_free_bytes{host=\"$host\",fstype=~\"ext.*|xfs\",mountpoint !~\".*pod.*\"}))",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "{{mountpoint}}",
"refId": "A"
},
{
"datasource": {
"type": "prometheus"
},
"expr": "node_filesystem_files_free{host=\"$host\",fstype=~\"ext.?|xfs\"} / node_filesystem_files{host=\"$host\",fstype=~\"ext.?|xfs\"}",
"hide": true,
"interval": "",
"legendFormat": "Inodes{{instance}}{{mountpoint}}",
"refId": "B"
}
],
"title": "Disk",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus"
},
"description": "Physical machines only",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "celsius"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 21
},
"id": 175,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"editorMode": "code",
"expr": "node_thermal_zone_temp{host=\"$host\"}",
"legendFormat": "{{type}}-zone{{zone}}",
"range": true,
"refId": "A"
}
],
"title": "Temperature",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 21
},
"id": 176,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "11.6.0",
"targets": [
{
"editorMode": "code",
"expr": "rate(node_disk_reads_completed_total{host=\"$host\"}[2m])",
"legendFormat": "{{device}} reads",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus"
},
"editorMode": "code",
"expr": " rate(node_disk_writes_completed_total{host=~\"$host\"}[2m])",
"hide": false,
"instant": false,
"legendFormat": "{{device}} writes",
"range": true,
"refId": "B"
}
],
"title": "Disks IOs",
"type": "timeseries"
}
],
"preload": false,
"refresh": "5s",
"schemaVersion": 41,
"tags": [],
"templating": {
"list": [
{
"allowCustomValue": false,
"current": {
"text": "kazguel",
"value": "kazguel"
},
"definition": "label_values(host)",
"includeAll": false,
"name": "host",
"options": [],
"query": {
"qryType": 1,
"query": "label_values(host)",
"refId": "PrometheusVariableQueryEditor-VariableQuery"
},
"refresh": 1,
"regex": "",
"type": "query"
},
{
"allowCustomValue": false,
"current": {
"text": [
"ens18"
],
"value": [
"ens18"
]
},
"definition": "label_values(node_network_info{device!~\"br.*|veth.*|lo.*|tap.*|docker.*|vibr.*\"},device)",
"includeAll": true,
"label": "NIC",
"multi": true,
"name": "device",
"options": [],
"query": {
"qryType": 1,
"query": "label_values(node_network_info{device!~\"br.*|veth.*|lo.*|tap.*|docker.*|vibr.*\"},device)",
"refId": "PrometheusVariableQueryEditor-VariableQuery"
},
"refresh": 1,
"regex": "",
"type": "query"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Vue Serveur",
"uid": "deki6c3qvihhcd",
"version": 22
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,108 @@
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_interval: 60s
evaluation_interval: 60s
scrape_timeout: 55s
rule_files:
- 'alert.rules'
scrape_configs:
- job_name: 'traefik'
scrape_interval: 5s
# unused for now
#- job_name: 'traefik'
# scrape_interval: 5s
# static_configs:
# - targets: ['reverse-proxy:8080']
- job_name: prometheus
static_configs:
- targets: ['dashboard.kaz.sns:8289','dashboard2.kaz.sns:8289']
- targets: ["prometheus:9090"]
- job_name: cadvisor-prod1
scheme: "https"
static_configs:
- targets: ["cadvisor-prod1.kaz.bzh:443"]
labels:
host: 'prod1'
portainer_id: 2
- job_name: cadvisor-prod2
scheme: "https"
static_configs:
- targets: ["cadvisor-prod2.kaz.bzh:443"]
labels:
host: 'prod2'
portainer_id: 4
- job_name: cadvisor-kazoulet
scheme: "https"
static_configs:
- targets: ["cadvisor-kazoulet.kaz.bzh:443"]
labels:
host: 'kazoulet'
portainer_id: 3
- job_name: cadvisor-tykaz
scheme: "https"
static_configs:
- targets: ["cadvisor-tykaz.kaz.bzh:443"]
labels:
host: 'tykaz'
portainer_id: 10
- job_name: cadvisor-kazguel
scheme: "https"
static_configs:
- targets: ["cadvisor-kazguel.kaz.bzh:443"]
labels:
host: 'kazguel'
portainer_id: 11
- job_name: cadvisor-kazkouil
scheme: "https"
static_configs:
- targets: ["cadvisor-dev.kazkouil.fr:443"]
labels:
host: 'kazkouil'
portainer_id: 5
- job_name: node-exporter-prod1
static_configs:
# - targets: ["prod1.kaz.bzh:9100","prod2.kaz.bzh:9100","kazoulet.kaz.bzh:9100","tykaz.kaz.bzh:9100","kazguel.kaz.bzh:9100","kazkouil.fr:9100"]
- targets: ["prod1.kaz.bzh:9100"]
labels:
host: 'prod1'
- job_name: node-exporter-prod2
static_configs:
# - targets: ["prod1.kaz.bzh:9100","prod2.kaz.bzh:9100","kazoulet.kaz.bzh:9100","tykaz.kaz.bzh:9100","kazguel.kaz.bzh:9100","kazkouil.fr:9100"]
- targets: ["prod2.kaz.bzh:9100"]
labels:
host: 'prod2'
- job_name: node-exporter-kazoulet
static_configs:
- targets: ["kazoulet.kaz.bzh:9100"]
labels:
host: 'kazoulet'
- job_name: node-exporter-tykaz
static_configs:
- targets: ["tykaz.kaz.bzh:9100"]
labels:
host: 'tykaz'
- job_name: node-exporter-kazguel
static_configs:
- targets: ["kazguel.kaz.bzh:9100"]
labels:
host: 'kazguel'
- job_name: node-exporter-kazkouil
static_configs:
- targets: ["kazkouil.fr:9100"]
labels:
host: 'kazkouil'

View File

@@ -38,7 +38,8 @@ RUN docker-php-ext-install zip
RUN mkdir /var/jirafeau/ /var/jirafeauData/
WORKDIR /var/jirafeau
COPY --chown=www-data git/Jirafeau/ .
COPY --chown=www-data git/depollueur/src/Jirafeau/[aft].php ./
COPY --chown=www-data git/depollueur/src/Jirafeau/ ./
COPY --chown=www-data dockers/jirafeau/media/kaz media/kaz
RUN sed -i -e '1i\<p>La limite des t&eacute;l&eacute;versements est actuellement de <?php echo ini_get("post_max_size"); ?></p>' lib/template/footer.php
RUN sed -i -e '/<div id="jyraphe">/i\<div id="kaz">' lib/template/footer.php

View File

@@ -23,11 +23,15 @@ services:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.${jirafeauServName}-admin.rule=Host(`${fileHost}.${domain}`) && PathPrefix(`/admin.php`)"
- "traefik.http.routers.${jirafeauServName}-admin.middlewares=test-adminipallowlist@file"
- "traefik.http.routers.${jirafeauServName}.rule=Host(`${fileHost}.${domain}`) && ! PathPrefix(`/admin.php`)"
- "traefik.docker.network=jirafeauNet"
- "traefik.enable=true"
# pour ouvrir juste /f.php !!
# - "traefik.http.routers.${jirafeauServName}-download.rule=Host(`${fileHost}.${domain}`) && ( PathPrefix(`/f.php`) || PathPrefix(`/index.php`)"
# Le service est ouvert aux ip autorisées
# - "traefik.http.routers.${jirafeauServName}-admin.rule=Host(`${fileHost}.${domain}`)"
- "traefik.http.routers.${jirafeauServName}-admin.rule=Host(`${fileHost}.${domain}`) && ( PathPrefix(`/a-send.php`) || PathPrefix(`/s.php`) || PathPrefix(`/admin.php`) || PathPrefix(`/script.php`) )"
- "traefik.http.routers.${jirafeauServName}-admin.middlewares=test-adminipallowlist@file"
- "traefik.http.routers.${jirafeauServName}.rule=Host(`${fileHost}.${domain}`) && ! ( PathPrefix(`/a-send.php`) || PathPrefix(`/s.php`) || PathPrefix(`/admin.php`) || PathPrefix(`/script.php`) )"
- "traefik.docker.network=jirafeauNet"
volumes:
fileData:

7
dockers/jirafeau/reload.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# limitation du filter.sh
docker exec jirafeauServ bash -c "cp /var/jirafeauData/*/20241109/*.json /var/jirafeau/lib/locales/"
docker exec jirafeauServ bash -c "cp /var/jirafeauData/*/20241109/*.php /var/jirafeau/"
docker exec jirafeauServ bash -c "mv /var/jirafeau/settings.php /var/jirafeau/lib/"
docker exec jirafeauServ bash -c "mv /var/jirafeau/functions.js.php /var/jirafeau/lib/"

View File

@@ -11,6 +11,7 @@ services:
web:
image: ltbproject/self-service-password
container_name: ${ldapUIName}
restart: ${restartPolicy}
depends_on:
- ldap
networks:
@@ -45,7 +46,7 @@ services:
ldap:
image: docker.io/bitnami/openldap:2.6
container_name: ${ldapServName}
restart: always
restart: ${restartPolicy}
env_file:
- ../../secret/env-${ldapServName}

View File

@@ -84,5 +84,5 @@ updateVarInConf "pwd_show_policy" "always" "${CONFIG_IHM}"
updateVarInConf "posthook" "/var/www/kaz/post-hook.sh" "${CONFIG_IHM}"
updateVarInConf "posthook_password_encodebase64" "true" "${CONFIG_IHM}"
docker cp "${KAZ_BIN_DIR}/look/kaz/kaz-tete.png" "${ldapUIName}:/var/www/html/images/ltb-logo.png"
# does not work
# docker cp "${KAZ_BIN_DIR}/look/kaz/kaz-tete.png" "${ldapUIName}:/var/www/html/images/ltb-logo.png"

1
dockers/mastodon/.env Symbolic link
View File

@@ -0,0 +1 @@
../../config/dockers.env

View File

@@ -0,0 +1,6 @@
Initialiser la DB :
docker-compose run --rm web bundle exec rails db:setup
Créer un compte admin :
tootctl accounts create adminkaz --email admin@kaz.bzh --confirmed --role Owner
tootctl accounts approve adminkaz

View File

@@ -0,0 +1,184 @@
# This file is designed for production server deployment, not local development work
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/docs/DEVELOPMENT.md#docker
services:
db:
container_name: ${mastodonDBName}
restart: ${restartPolicy}
image: postgres:14-alpine
shm_size: 256mb
networks:
- mastodonNet
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
volumes:
- postgres:/var/lib/postgresql/data
# environment:
# - 'POSTGRES_HOST_AUTH_METHOD=trust'
env_file:
- ../../secret/env-mastodonDB
redis:
container_name: ${mastodonRedisName}
restart: ${restartPolicy}
image: redis:7-alpine
networks:
- mastodonNet
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
volumes:
- redis:/data
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
# - "xpack.license.self_generated.type=basic"
# - "xpack.security.enabled=false"
# - "xpack.watcher.enabled=false"
# - "xpack.graph.enabled=false"
# - "xpack.ml.enabled=false"
# - "bootstrap.memory_lock=true"
# - "cluster.name=es-mastodon"
# - "discovery.type=single-node"
# - "thread_pool.write.queue_size=1000"
# networks:
# - external_network
# - internal_network
# healthcheck:
# test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
# ulimits:
# memlock:
# soft: -1
# hard: -1
# nofile:
# soft: 65536
# hard: 65536
# ports:
# - '127.0.0.1:9200:9200'
web:
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
# build: .
container_name: ${mastodonServName}
image: ghcr.io/mastodon/mastodon:v4.3.6
restart: ${restartPolicy}
environment:
- LOCAL_DOMAIN=${mastodonHost}.${domain}
- SMTP_SERVER=smtp.${domain}
- SMTP_LOGIN=admin@${domain}
- SMTP_FROM_ADDRESS=admin@${domain}
env_file:
- env-config
- ../../secret/env-mastodonServ
- ../../secret/env-mastodonDB
command: bundle exec puma -C config/puma.rb
networks:
- mastodonNet
healthcheck:
# prettier-ignore
test: ['CMD-SHELL',"curl -s --noproxy localhost localhost:3000/health | grep -q 'OK' || exit 1"]
ports:
- '127.0.0.1:3000:3000'
depends_on:
- db
- redis
# - es
volumes:
- public_system:/mastodon/public/system
- images:/mastodon/app/javascript/images
labels:
- "traefik.enable=true"
- "traefik.http.routers.koz.rule=Host(`${mastodonHost}.${domain}`)"
- "traefik.http.services.koz.loadbalancer.server.port=3000"
- "traefik.docker.network=mastodonNet"
streaming:
# You can uncomment the following lines if you want to not use the prebuilt image, for example if you have local code changes
# build:
# dockerfile: ./streaming/Dockerfile
# context: .
container_name: ${mastodonStreamingName}
image: ghcr.io/mastodon/mastodon-streaming:v4.3.6
restart: ${restartPolicy}
environment:
- LOCAL_DOMAIN=${mastodonHost}.${domain}
- SMTP_SERVER=smtp.${domain}
- SMTP_LOGIN=admin@${domain}
- SMTP_FROM_ADDRESS=admin@${domain}
env_file:
- env-config
- ../../secret/env-mastodonServ
command: node ./streaming/index.js
networks:
- mastodonNet
healthcheck:
# prettier-ignore
test: ['CMD-SHELL', "curl -s --noproxy localhost localhost:4000/api/v1/streaming/health | grep -q 'OK' || exit 1"]
ports:
- '127.0.0.1:4000:4000'
depends_on:
- db
- redis
labels:
- "traefik.enable=true"
- "traefik.http.routers.kozs.rule=(Host(`${mastodonHost}.${domain}`) && PathPrefix(`/api/v1/streaming`))"
- "traefik.http.services.kozs.loadbalancer.server.port=4000"
- "traefik.docker.network=mastodonNet"
sidekiq:
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
# build: .
container_name: ${mastodonSidekiqName}
image: ghcr.io/mastodon/mastodon:v4.3.6
restart: ${restartPolicy}
environment:
- LOCAL_DOMAIN=${mastodonHost}.${domain}
- SMTP_SERVER=smtp.${domain}
- SMTP_LOGIN=admin@${domain}
- SMTP_FROM_ADDRESS=admin@${domain}
env_file:
- env-config
- ../../secret/env-mastodonServ
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- mastodonNet
volumes:
- public_system:/mastodon/public/system
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
## Uncomment to enable federation with tor instances along with adding the following ENV variables
## http_hidden_proxy=http://privoxy:8118
## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# tor:
# image: sirboops/tor
# networks:
# - external_network
# - internal_network
#
# privoxy:
# image: sirboops/privoxy
# volumes:
# - ./priv-config:/opt/config
# networks:
# - external_network
# - internal_network
volumes:
postgres:
redis:
public_system:
images:
networks:
mastodonNet:
external: true
name: mastodonNet

113
dockers/mastodon/env-config Normal file
View File

@@ -0,0 +1,113 @@
# This is a sample configuration file. You can generate your configuration
# with the `bundle exec rails mastodon:setup` interactive setup wizard, but to customize
# your setup even further, you'll need to edit it manually. This sample does
# not demonstrate all available configuration options. Please look at
# https://docs.joinmastodon.org/admin/config/ for the full documentation.
# Note that this file accepts slightly different syntax depending on whether
# you are using `docker-compose` or not. In particular, if you use
# `docker-compose`, the value of each declared variable will be taken verbatim,
# including surrounding quotes.
# See: https://github.com/mastodon/mastodon/issues/16895
# Federation
# ----------
# This identifies your server and cannot be changed safely later
# ----------
# LOCAL_DOMAIN=
# Redis
# -----
REDIS_HOST=redis
REDIS_PORT=
# PostgreSQL
# ----------
DB_HOST=db
#DB_USER=postgres
#DB_NAME=postgres
#DB_PASS=
DB_PORT=5432
# Elasticsearch (optional)
# ------------------------
ES_ENABLED=false
ES_HOST=localhost
ES_PORT=9200
# Authentication for ES (optional)
ES_USER=elastic
ES_PASS=password
# Secrets
# -------
# Make sure to use `bundle exec rails secret` to generate secrets
# -------
#SECRET_KEY_BASE=
#OTP_SECRET=
# Encryption secrets
# ------------------
# Must be available (and set to same values) for all server processes
# These are private/secret values, do not share outside hosting environment
# Use `bin/rails db:encryption:init` to generate fresh secrets
# Do NOT change these secrets once in use, as this would cause data loss and other issues
# ------------------
#ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
#ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
#ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
# Web Push
# --------
# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key`
# --------
#VAPID_PRIVATE_KEY=
#VAPID_PUBLIC_KEY=
# Sending mail
# ------------
#SMTP_SERVER=
SMTP_PORT=587
#SMTP_LOGIN=
#SMTP_PASSWORD=
#SMTP_FROM_ADDRESS=
# File storage (optional)
# -----------------------
S3_ENABLED=false
S3_BUCKET=files.example.com
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
S3_ALIAS_HOST=files.example.com
# IP and session retention
# -----------------------
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).
# -----------------------
IP_RETENTION_PERIOD=31556952
SESSION_RETENTION_PERIOD=31556952
# Fetch All Replies Behavior
# --------------------------
# When a user expands a post (DetailedStatus view), fetch all of its replies
# (default: false)
FETCH_REPLIES_ENABLED=false
# Period to wait between fetching replies (in minutes)
FETCH_REPLIES_COOLDOWN_MINUTES=15
# Period to wait after a post is first created before fetching its replies (in minutes)
FETCH_REPLIES_INITIAL_WAIT_MINUTES=5
# Max number of replies to fetch - total, recursively through a whole reply tree
FETCH_REPLIES_MAX_GLOBAL=1000
# Max number of replies to fetch - for a single post
FETCH_REPLIES_MAX_SINGLE=500
# Max number of replies Collection pages to fetch - total
FETCH_REPLIES_MAX_PAGES=500
SINGLE_USER_MODE=false
#EMAIL_DOMAIN_ALLOWLIST=

View File

@@ -1,21 +1,15 @@
services:
app:
image: mattermost/mattermost-team-edition:9.10
image: mattermost/mattermost-team-edition:10.9.1
container_name: ${mattermostServName}
restart: ${restartPolicy}
# memory: 1G
# disk_quota: 256M
volumes:
- matterConfig:/mattermost/config:rw
# - matterConfigLangSrv:/mattermost/i18n:rw
# - matterConfigLangClt:/mattermost/client/i18n:rw
- matterData:/mattermost/data:rw
- matterLogs:/mattermost/logs:rw
- matterPlugins:/mattermost/plugins:rw
- matterClientPlugins:/mattermost/client/plugins:rw
# - matterIcons:/mattermost/client/images/
# - matterI18n:/mattermost/i18n:rw
- /etc/ssl:/etc/ssl:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
@@ -29,17 +23,12 @@ services:
- MM_PASSWORDSETTINGS_UPPERCASE=false
- MM_PASSWORDSETTINGS_NUMBER=false
- MM_PASSWORDSETTINGS_SYMBOL=true
# in case your config is not in default location
#- MM_CONFIG=/mattermost/config/config.json
depends_on:
- db
- postgres
links:
- db
- postgres
expose:
- ${matterPort}
# ports:
# - 8089:80
networks:
- mattermostNet
- postfixNet
@@ -57,22 +46,30 @@ services:
start_period: 20s
timeout: 10s
db:
image: mariadb:10.5
container_name: ${mattermostDBName}
postgres:
image: postgres:17-alpine
container_name: matterPG
restart: ${restartPolicy}
networks:
- mattermostNet
security_opt:
- no-new-privileges:true
pids_limit: 100
read_only: true
tmpfs:
- /tmp
- /var/run/postgresql
volumes:
- matterPG:/var/lib/postgresql/data
# environment:
# timezone inside container
# - TZ
env_file:
- ../../secret/env-${mattermostDBName}
volumes:
- matterDB:/var/lib/mysql
- /home/sauve/:/svg/
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
volumes:
matterDB:
matterPG:
matterConfig:
matterData:
matterLogs:
@@ -80,8 +77,6 @@ volumes:
matterClientPlugins:
matterConfigLangSrv:
matterConfigLangClt:
# matterI18n:
# matterIcons:
networks:
mattermostNet:

View File

@@ -11,3 +11,7 @@ cd $(dirname $0)
"${KAZ_BIN_DIR}/gestContainers.sh" --install -M -agora
docker exec ${mattermostServName} mmctl auth login https://${matterHost}.${domain} --name local-server --username ${mattermost_MM_ADMIN_USER} --password ${mattermost_MM_ADMIN_PASSWORD}
docker exec ${mattermostServName} mmctl channel create --team kaz --name "une-question--un-soucis" --display-name "Une question ? Un souci ?"
docker exec ${mattermostServName} mmctl channel create --team kaz --name "cafe-du-commerce--ouvert-2424h" --display-name "Café du commerce"
docker exec ${mattermostServName} mmctl channel create --team kaz --name "creation-comptes" --display-name "Création comptes"

View File

@@ -44,7 +44,7 @@ config :mobilizon, Mobilizon.Storage.Repo,
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Swoosh.Adapters.SMTP,
relay: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"),
relay: System.get_env("MOBILIZON_SMTP_SERVER", "smtp"),
port: System.get_env("MOBILIZON_SMTP_PORT", "25"),
username: System.get_env("MOBILIZON_SMTP_USERNAME", nil),
password: System.get_env("MOBILIZON_SMTP_PASSWORD", nil),

View File

@@ -1,6 +1,5 @@
FROM paheko/paheko:1.3.12
FROM paheko/paheko:1.3.15
#ENV PAHEKO_DIR /usr/share/paheko
ENV PAHEKO_DIR /var/www/paheko
COPY dockers/paheko/config/factory_cron.sh ${PAHEKO_DIR}/
@@ -8,12 +7,25 @@ COPY dockers/paheko/config/factory_cron_emails.sh ${PAHEKO_DIR}/
COPY dockers/paheko/config/setupWebRights.sh ${PAHEKO_DIR}/
RUN mkdir ${PAHEKO_DIR}/users
#pour corriger le bug "export excel"
RUN docker-php-ext-install calendar
RUN apt-get update
RUN apt-get install -y libwebp-dev
RUN docker-php-ext-configure gd --with-jpeg --with-freetype --with-webp
RUN docker-php-ext-install gd
#Plugin facturation (le seul qui ne fasse pas parti de la distribution de base
COPY "dockers/paheko/config/facturation.tar.gz" ${PAHEKO_DIR}/data/plugins/
RUN mkdir ${PAHEKO_DIR}/data/plugins/facturation && tar zxvf ${PAHEKO_DIR}/data/plugins/facturation.tar.gz -C ${PAHEKO_DIR}/data/plugins/facturation && rm ${PAHEKO_DIR}/data/plugins/facturation.tar.gz
RUN apt-get install unzip
COPY "dockers/paheko/config/facturation.zip" ${PAHEKO_DIR}/data/plugins/
WORKDIR ${PAHEKO_DIR}/data/plugins/
RUN unzip ${PAHEKO_DIR}/data/plugins/facturation.zip
WORKDIR /
#RUN mkdir ${PAHEKO_DIR}/data/plugins/facturation && tar zxvf ${PAHEKO_DIR}/data/plugins/facturation.tar.gz -C ${PAHEKO_DIR}/data/plugins/facturation && rm ${PAHEKO_DIR}/data/plugins/facturation.tar.gz
#install cron pour factory_cron.sh
RUN apt-get update && apt-get install cron joe rsyslog -y
RUN apt-get install cron joe rsyslog -y
RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf
RUN echo "0 1 * * * cd ${PAHEKO_DIR} && ${PAHEKO_DIR}/factory_cron.sh 1> /dev/null 2> /dev/null" >> /var/spool/cron/crontabs/root
RUN echo "* * * * * cd ${PAHEKO_DIR} && ${PAHEKO_DIR}/factory_cron_emails.sh 1> /dev/null 2> /dev/null" >> /var/spool/cron/crontabs/root

View File

@@ -127,4 +127,4 @@ define('Paheko\SHOW_ERRORS', true);
#add by fab le 21/04/2022
//const PDF_COMMAND = 'prince';
# const PDF_COMMAND = 'auto';
const PDF_COMMAND = 'chromium --no-sandbox --headless --disable-dev-shm-usage --autoplay-policy=no-user-gesture-required --no-first-run --disable-gpu --disable-features=DefaultPassthroughCommandDecoder --use-fake-ui-for-media-stream --use-fake-device-for-media-stream --disable-sync --print-to-pdf=%2$s %1$s';
const PDF_COMMAND = 'chromium --no-sandbox --headless --no-pdf-header-footer --disable-dev-shm-usage --autoplay-policy=no-user-gesture-required --no-first-run --disable-gpu --disable-features=DefaultPassthroughCommandDecoder --use-fake-ui-for-media-stream --use-fake-device-for-media-stream --disable-sync --print-to-pdf=%2$s %1$s';

Binary file not shown.

View File

@@ -4,6 +4,7 @@ services:
image: pahekokaz
build: .
container_name: ${pahekoServName}
restart: ${restartPolicy}
volumes:
- ./config/config.local.php:/var/www/paheko/config.local.php
- ./config/factory_cron.sh:/var/www/paheko/factory_cron.sh

View File

@@ -0,0 +1,84 @@
services:
webserver:
image: chocobozzz/peertube-webserver:latest
restart: ${restartPolicy}
depends_on:
- peertube
networks:
- peertubeNet
#ports:
#- "80:80"
#- "443:443"
volumes:
- assets:/var/www/peertube/peertube-latest/client/dist:ro
- data:/var/www/peertube/storage
env_file:
- ../../secret/env-${peertubeServName}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${peertubeServName}.rule=Host(`${peertubeHost}.${domain}`)"
- "traefik.docker.network=peertubeNet"
peertube:
image: chocobozzz/peertube:production-bookworm
container_name: ${peertubeServName}
restart: ${restartPolicy}
depends_on:
- postgres
- redis
networks:
- peertubeNet
volumes:
# Remove the following line if you want to use another webserver/proxy or test PeerTube in local
- assets:/app/client/dist
- data:/data
- config:/config
env_file:
- ../../secret/env-${peertubeServName}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${peertubeServName}.rule=Host(`${peertubeHost}.${domain}`)"
- "traefik.docker.network=peertubeNet"
- "traefik.http.services.${peertubeServName}.loadbalancer.server.port=9000"
#traefik.frontend.rule: "Host:videos.kaz.bzh"
#traefik.port: "9000"
# traefik.frontend.redirect.entryPoint: https
postgres:
image: postgres:13-alpine
container_name: ${peertubeDBName}
restart: ${restartPolicy}
networks:
- peertubeNet
volumes:
- db:/var/lib/postgresql/data
env_file:
- ../../secret/env-${peertubeDBName}
labels:
traefik.enable: "false"
redis:
image: redis:6-alpine
container_name: peertubeCache
restart: ${restartPolicy}
networks:
- peertubeNet
env_file:
- ../../secret/env-${peertubeServName}
volumes:
- redis:/data
labels:
traefik.enable: "false"
volumes:
assets:
data:
config:
db:
redis:
networks:
peertubeNet:
external: true
name: peertubeNet

View File

@@ -16,8 +16,8 @@ services:
- "traefik.enable=true"
# Frontend
- "traefik.http.routers.frontend.middlewares=test-adminipallowlist@file"
- "traefik.http.routers.frontend.rule=Host(`portainer.${domain}`)"
# - "traefik.docker.network=portainerNet"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.services.frontend.loadbalancer.server.port=9000"
- "traefik.http.routers.frontend.service=frontend"

View File

@@ -1,4 +1,4 @@
FROM docker.io/mailserver/docker-mailserver:13.3.1
FROM docker.io/mailserver/docker-mailserver:15.0.2
########################################
# APT local cache

View File

@@ -4,6 +4,7 @@ services:
hostname: ${smtpHost}
domainname: ${domain}
container_name: ${smtpServName}
restart: ${restartPolicy}
networks:
- postfixNet
- jirafeauNet
@@ -25,7 +26,7 @@ services:
- filterConfig:/home/filter/config/
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
- /etc/ssl:/etc/ssl:ro
# - /etc/ssl:/etc/ssl:ro
# - /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro
environment:
@@ -40,7 +41,14 @@ services:
cap_add:
- NET_ADMIN
- SYS_PTRACE
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.mail.rule=Host(`mail.${domain}`) || Host(`smtp.${domain}`)"
- "traefik.http.routers.webmails.rule=Host(`webmail.${domain}`)"
- "traefik.http.middlewares.reg-webmails.redirectregex.regex=^https://webmail.${domain}(.*)"
- "traefik.http.middlewares.reg-webmails.redirectregex.replacement=https://kaz.bzh/relever-ses-mails-chez-kaz-via-un-webmail"
- "traefik.http.middlewares.reg-webmails.redirectregex.permanent=true"
- "traefik.http.routers.webmails.middlewares=reg-webmails"
volumes:
mailData:

View File

@@ -94,10 +94,10 @@ SMTP_ONLY=
# custom => Enables custom certificates
# manual => Let's you manually specify locations of your SSL certificates for non-standard cases
# self-signed => Enables self-signed certificates
#SSL_TYPE=self-signed
SSL_TYPE=letsencrypt
#SSL_CERT_PATH=
#SSL_KEY_PATH=
SSL_TYPE=manual
#SSL_TYPE=letsencrypt
SSL_CERT_PATH=/etc/ssl/certs/mail.pem
SSL_KEY_PATH=/etc/ssl/private/mail.key
# Set how many days a virusmail will stay on the server before being deleted
# empty => 7 days
@@ -210,7 +210,7 @@ SA_TAG2=6.31
SA_KILL=6.31
# add tag to subject if spam detected
SA_SPAM_SUBJECT=***SPAM*****
SPAM_SUBJECT=***SPAM*****
# KAM is a 3rd party SpamAssassin ruleset, provided by the McGrail Foundation. If SpamAssassin is enabled, KAM can be used in addition to the default ruleset.
@@ -298,8 +298,8 @@ DOVECOT_AUTH_BIND=yes
DOVECOT_PASS_ATTRS=cn=user,userPassword=password
# DOVECOT_USER_ATTRS=mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail,mailQuota=quota_rule=*:bytes=%$
DOVECOT_USER_ATTRS=mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail,mailQuota=quota_rule=*:bytes=20G
DOVECOT_USER_ATTRS=mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail,mailQuota=quota_rule=*:bytes=%$
# DOVECOT_USER_ATTRS=mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail,mailQuota=quota_rule=*:bytes=20G
ENABLE_QUOTAS=1
@@ -428,3 +428,6 @@ RELAY_USER=
# empty => no default
# password for default relay user
RELAY_PASSWORD=
LOGROTATE_INTERVAL=weekly
LOGROTATE_COUNT=4

View File

@@ -28,6 +28,6 @@ EOF
chmod +x /var/lib/docker/volumes/postfix_mailConfig/_data/user-patches.sh
fi
if [ "${mode}" == "local" ] || exit
[ "${mode}" == "local" ] || exit
# echo "virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf, ldap:/etc/postfix/ldap-groups.cf, texthash:/etc/postfix/virtual" >> config/postfix-main.cf

View File

@@ -1,7 +1,7 @@
services:
app:
image: roundcube/roundcubemail
image: roundcube/roundcubemail:1.6.9-apache
container_name: ${roundcubeServName}
restart: ${restartPolicy}
depends_on:
@@ -26,7 +26,7 @@ services:
- ../../secret/env-${roundcubeServName}
labels:
- "traefik.enable=true"
- "traefik.http.routers.${roundcubeServName}.rule=Host(`${webmailHost}.${domain}`)"
- "traefik.http.routers.${roundcubeServName}.rule=host(`roundcube.${domain}`)"
- "traefik.docker.network=roundcubeNet"
db:

1
dockers/snappymail/.env Symbolic link
View File

@@ -0,0 +1 @@
../../config/dockers.env

View File

@@ -0,0 +1,42 @@
services:
db:
image: mariadb:11.4
container_name: ${spipDBName}
restart: ${restartPolicy}
env_file:
- ../../secret/env-${spipDBName}
volumes:
- spipDB:/var/lib/mysql
networks:
- spipNet
spip:
image: ipeos/spip:4.4
restart: ${restartPolicy}
container_name: ${spipServName}
env_file:
- ../../secret/env-${spipServName}
links:
- db:mysql
environment:
- SPIP_AUTO_INSTALL=1
- SPIP_DB_HOST=${spipDBName}
- SPIP_SITE_ADDRESS=https://${spipHost}.${domain}
expose:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.${spipServName}.rule=Host(`${spipHost}.${domain}`)"
networks:
- spipNet
volumes:
- spipData:/usr/src/spip
volumes:
spipDB:
spipData:
networks:
spipNet:
external: true
name: spipNet

View File

@@ -99,7 +99,7 @@ RUN echo "root: ADMIN_EMAIL" >> /etc/aliases \
RUN echo aliases_program postalias >>/etc/sympa/sympa/sympa.conf \
&& echo sendmail /usr/sbin/sendmail >>/etc/sympa/sympa/sympa.conf \
&& echo soap_url /sympasoap >>/etc/sympa/sympa/sympa.conf \
&& echo dmarc_protection.mode dmarc_reject >>/etc/sympa/sympa/sympa.conf \
&& echo dmarc_protection.mode dmarc_reject,dmarc_quarantine >>/etc/sympa/sympa/sympa.conf \
&& cp /usr/share/doc/sympa/examples/script/sympa_soap_client.pl.gz /usr/lib/sympa/bin/ \
&& gunzip /usr/lib/sympa/bin/sympa_soap_client.pl.gz \
&& chmod +x /usr/lib/sympa/bin/sympa_soap_client.pl \

View File

@@ -3,6 +3,7 @@ orange.com veryslow:
wanadoo.com veryslow:
wanadoo.fr veryslow:
gmail.com slow:
laposte.net slow:
yahoo.com slow:
yahoo.fr slow:
outlook.com veryslow:

View File

@@ -16,7 +16,6 @@ services:
- ${jirafeauServName}:${fileHost}
ports:
- ${SYMPA_IP}:25:25
- ${SYMPA_IP}:80:80
- ${SYMPA_IP}:443:443
env_file:
- ../../secret/env-${sympaServName}
@@ -33,7 +32,12 @@ services:
- ./config/transport:/etc/postfix/transport:rw
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
- /etc/ssl:/etc/ssl:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.sympa.rule=host(`listes.${domain}`)"
- "traefik.docker.network=sympaNet"
db:
image: mariadb:10.5

View File

@@ -1,10 +0,0 @@
#!/bin/bash
# mis à jour du filtre (si pas de ./build)
cd $(dirname $0)/..
for i in eMailShrinker filter.sh filterTest.sh; do
docker cp "postfix/filter/$i" sympaServ:/home/filter/
done
#Correction des droits sur le filter.sh
docker exec sympaServ chmod a+rx /home/filter/filter.sh /home/filter/filterTest.sh

View File

@@ -11,6 +11,8 @@ iptables -t nat -N ipbis
iptables -t nat -F ipbis
iptables -t nat -I ipbis -o ens18 -p tcp --source `docker inspect -f '{{.NetworkSettings.Networks.sympaNet.IPAddress}}' sympaServ` -j SNAT --to `ifconfig ens18:0 | grep "inet" | awk '{print $2}'`
iptables -t nat -I ipbis -o ens18 -p tcp --source `docker inspect -f '{{.NetworkSettings.Networks.jirafeauNet.IPAddress}}' sympaServ` -j SNAT --to `ifconfig ens18:0 | grep "inet" | awk '{print $2}'`
#add by fab mais non testé 'assque chu pas fou !
#iptables -t nat -I ipbis -o ens18 -p tcp --source `docker inspect -f '{{.NetworkSettings.Networks.apikazNet.IPAddress}}' sympaServ` -j SNAT --to `ifconfig ens18:0 | grep "inet" | awk '{print $2}'`
iptables -t nat -A ipbis -j RETURN
iptables -t nat -D POSTROUTING -o ens18 -j ipbis
iptables -t nat -I POSTROUTING -o ens18 -j ipbis

View File

@@ -0,0 +1,11 @@
http:
middlewares:
test-ipallowlist:
ipallowlist:
sourceRange:
# tlm est autorisé
- "0.0.0.0/0"
test-adminipallowlist:
ipallowlist:
sourceRange:
- "127.0.0.1"

View File

@@ -1,18 +0,0 @@
http:
middlewares:
ipwhitelist:
ipWhiteList:
sourceRange:
- "192.168.0.0/16"
- "172.16.0.0/12"
- "127.0.0.0/8"
- "10.0.0.0/8"
- "0.0.0.0/0"
adminipwhitelist:
ipWhiteList:
sourceRange:
- "192.168.0.0/16"
- "172.16.0.0/12"
- "127.0.0.0/8"
- "10.0.0.0/8"
- "0.0.0.0/0"

Some files were not shown because too many files have changed in this diff Show More