Compare commits

..

11 Commits

Author SHA1 Message Date
8c700f00d4 collabora 2025-10-15 08:37:37 +02:00
53d26e2f22 supp indicateurs.sh 2025-10-15 08:34:26 +02:00
d7b8d61da5 init checkPahekoLdap.py 2025-10-14 18:30:46 +02:00
a93d19423f gestion des mails suite 2025-10-13 17:43:28 +02:00
df894ec84a modif des envois de mails 2025-10-13 16:40:54 +02:00
bf391b816a ajout de mail si problème 2025-10-12 18:37:02 +02:00
e1e5afd1ff cosmétique 2025-10-12 18:08:12 +02:00
nom
62b60a36b3 upgrade MM 2025-09-18 15:07:33 +02:00
nom
80b1ec7eec upgrade MM 10.11.3 2025-09-17 19:50:05 +02:00
nom
3cd07f1082 upgrade mailsrv en 15.1.0 2025-09-15 22:34:25 +02:00
2e5d3b656e fix per_host_docker_monitoring
Signed-off-by: Samuel Gauthier <samuel.gauthier@gmail.com>
2025-09-09 12:12:33 +02:00
10 changed files with 106 additions and 161 deletions

48
bin/checkPahekoLdap.py Executable file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/python3
import sys
from lib.paheko import Paheko
from lib.ldap import Ldap
paheko = Paheko()
categorie_membres = paheko.get_categorie_id("Membres")
membres = paheko.get_users_in_categorie(categorie_membres)
def test_quota(paheko_entry, ldap_entry):
ok = True
quota_disque = paheko_entry["quota_disque"].strip("'")
if f"{quota_disque}G".encode() != ldap_entry[1]['mailQuota'][0]:
ok = False
return ok
def test_mail_secours(paheko_entry, ldap_entry):
try:
if paheko_entry["email_secours"]:
return paheko_entry["email_secours"].strip("'").encode() == ldap_entry[1]['mailDeSecours'][0]
else:
return False
except e:
print(paheko_entry)
print(ldap_entry)
raise e
with Ldap() as ldap:
try:
for membre in membres:
ldap_entry = ldap.get_email(membre["email"])[0]
ok = True
#ok &= test_quota(membre, ldap_entry)
ok &= test_mail_secours(membre, ldap_entry)
if not ok:
print(membre)
print(ldap_entry)
print()
except Exception as e:
print(membre)
print(ldap.get_email(membre["email"]))
raise e

View File

@@ -13,7 +13,7 @@ setKazVars
. $KAZ_KEY_DIR/env-sympaServ
. $KAZ_KEY_DIR/env-paheko
VERSION="18-05-2025"
VERSION="13-10-2025"
PRG=$(basename $0)
RACINE=$(echo $PRG | awk '{print $1}')
IFS=' '
@@ -55,10 +55,6 @@ ExpMail() {
MAIL_DEST=$1
MAIL_SUJET=$2
MAIL_TEXTE=$3
# a mettre ailleurs
mailexp=${service_mail}
mailpassword=${service_password}
mailserveur=${smtpHost}.${domain}
printf "Subject:${MAIL_SUJET}\n${MAIL_TEXTE}" | msmtp ${MAIL_DEST}
}
@@ -351,6 +347,10 @@ searchDestroy() {
echo -e "${RED} suppression de ${REP_SEARCH_DESTROY} dans le ldap"
echo -e "${NC}"
echo ""
MAIL_SECOURS=$(ldapsearch -H ldap://${LDAP_IP} \
-x -D "cn=${LDAP_ADMIN_USERNAME},${ldap_root}" \
-w "${LDAP_ADMIN_PASSWORD}" \
-b "${ldap_root}" "(&(objectclass=inetOrgPerson)(cn=*${REP_SEARCH_DESTROY}*))" | grep ^mailDeSecours | sed -e 's/^mailDeSecours: //')
ldapdelete -H ldap://${LDAP_IP} -D "cn=${LDAP_ADMIN_USERNAME},${ldap_root}" -x -w "${LDAP_ADMIN_PASSWORD}" "cn=${REP_SEARCH_DESTROY},ou=users,${ldap_root}"
if [ "$?" -eq "0" ]
then
@@ -360,11 +360,12 @@ searchDestroy() {
fi
printKazMsg "Envoi d'un message dans mattermost pour la suppression du compte"
docker exec -ti mattermostServ bin/mmctl post create kaz:Creation-Comptes --message "Le compte ${REP_SEARCH_DESTROY} est supprimé" >/dev/null 2>&1
MAIL_SUPPR="Suppression du compte ${REP_SEARCH_DESTROY}"
docker exec -i mailServ mailx -a 'Content-Type: text/plain; charset="UTF-8"' -r contact@${domain} -s "Suppression de mail" contact@${domain} << EOF
${MAIL_SUPPR}
EOF
MAIL_SUPPR="Le compte ${REP_SEARCH_DESTROY} est supprimé"
OLDIFS=${IFS}
IFS=''
ExpMail ${MAIL_SECOURS} "Suppression de Compte" ${MAIL_SUPPR}
echo -e "${NC}"
IFS=${OLDIFS}
read -p " ---------------------- Appuyer sur une touche pour continuer -------------------------"
searchDestroy
fi
@@ -418,7 +419,7 @@ gestPassword() {
echo -e "$GREEN Compte $RED $(searchMattermost $COMPTE_A_MODIFIER) ${NC}"
echo -e "$GREEN Compte Nextcloud $RED ${USER_NEXTCLOUD_MODIF} ${NC}"
echo -e "$GREEN Le mot de passe sera = $RED ${PASSWORD} ${NC}"
docker exec -ti mattermostServ bin/mmctl user change-password $(searchMattermost $COMPTE_A_MODIFIER) -p $PASSWORD >/dev/null 2>&1
docker exec -ti mattermostServ bin/mmctl user change-password $(searchMattermost ${COMPTE_A_MODIFIER}) -p ${PASSWORD} >/dev/null 2>&1
curl -H 'OCS-APIREQUEST: true' -X PUT $httpProto://admin:$NEXTCLOUD_ADMIN_PASSWORD@$URL_NC/ocs/v1.php/cloud/users/${USER_NEXTCLOUD_MODIF} -d key=password -d value=${PASSWORD} >/dev/null 2>&1
pass=$(mkpasswd -m sha512crypt ${PASSWORD})
echo -e "\n\ndn: cn=${COMPTE_A_MODIFIER},ou=users,${ldap_root}\n\
@@ -427,7 +428,7 @@ replace: userPassword\n\
userPassword: {CRYPT}${pass}\n\n" | ldapmodify -c -H ldap://${LDAP_IP} -D "cn=${LDAP_ADMIN_USERNAME},${ldap_root}" -x -w "${LDAP_ADMIN_PASSWORD}"
echo -e "Envoi d'un message dans mattermost pour la modification du mot de passe"
docker exec -ti mattermostServ bin/mmctl post create kaz:Creation-Comptes --message "Le mot de passe du compte ${COMPTE_A_MODIFIER} a été modifié" >/dev/null 2>&1
if [ $ADRESSE_SEC == "OUI" ]
if [ ${ADRESSE_SEC} == "OUI" ]
then
echo -e "Envoi d'un message à l' adresse de secours : $GREEN${MAIL_SECOURS}${NC}"
MAIL_CHANG="
@@ -441,11 +442,9 @@ Le site Web de Kaz : https://kaz.bzh
Le mail de la collégiale : contact@kaz.bzh
A bientôt"
docker exec -i mailServ mailx -a 'Content-Type: text/plain; charset="UTF-8"' -r admin@${domain} -s "Modification du compte" $MAIL_SECOURS << EOF
${MAIL_CHANG}
EOF
ExpMail ${MAIL_SECOURS} "Modification du compte" ${MAIL_CHANG}
fi
if [ $ADRESSE_SEC == "NON" ]
if [ ${ADRESSE_SEC} == "NON" ]
then
echo -e "${RED} Pas d adresse de secours ${NC}"
fi

View File

@@ -1,77 +0,0 @@
#!/bin/bash
# 23/04/2021
# script de mise a jour du fichier de collecte pour future intégration dans la base de donneyyy
# did
KAZ_ROOT=$(cd $(dirname $0)/..; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars
FIC_COLLECTE=${KAZ_STATE_DIR}/collecte.csv
FIC_ACTIVITE_MAILBOX=${KAZ_STATE_DIR}/activites_mailbox.csv
mkdir -p ${KAZ_STATE_DIR}
mkdir -p ${KAZ_STATE_DIR}/metro
#Jirafeau
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"depot-count;" \
"$(find ${DOCK_VOL}/jirafeau_fileData/_data/files/ -name \*count| wc -l)" >> "${FIC_COLLECTE}"
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"depot-size;" \
"$(du -ks ${DOCK_VOL}/jirafeau_fileData/_data/files/ | awk -F " " '{print $1}')" >> "${FIC_COLLECTE}"
#PLACE DISQUE sur serveur
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"disk-system-size-used;" \
"$(df | grep sda | awk -F " " '{print $3}')" >> "${FIC_COLLECTE}"
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"disk-system-size-used-human;" \
"$(df -h | grep sda | awk -F " " '{print $3}')" >> "${FIC_COLLECTE}"
#nombre de mails kaz:
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"mailboxes;" \
"$(cat ${KAZ_COMP_DIR}/postfix/config/postfix-accounts.cf | wc -l)" >> "${FIC_COLLECTE}"
#nombre d'alias kaz:
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"mail_alias;" \
"$(cat ${KAZ_COMP_DIR}/postfix/config/postfix-virtual.cf | wc -l)" >> "${FIC_COLLECTE}"
#Nombre d' orgas
echo "$(date +%Y-%m-%d-%H-%M-%S);" \
"Orgas;" \
"$(ls -l /kaz/dockers/ | grep orga | wc -l)" >> "${FIC_COLLECTE}"
#stats des 2 postfix (mail+sympa)
EXP=$(/usr/bin/hostname -s)
STATS1=$(cat ${DOCK_VOL}/sympa_sympaLog/_data/mail.log.1 | /usr/sbin/pflogsumm)
#docker exec -i mailServ mailx -r $EXP -s "stats Sympa" root <<DEB_MESS
#$STATS1
#DEB_MESS
STATS2=$(cat ${DOCK_VOL}/postfix_mailLog/_data/mail.log | /usr/sbin/pflogsumm)
#docker exec -i mailServ mailx -r $EXP -s "stats Postfix" root <<DEB_MESS
#$STATS2
#DEB_MESS
IFS=''
for line in $(ls -lt --time-style=long-iso "${DOCK_VOL}/postfix_mailData/_data/kaz.bzh/"); do
echo "${line}" | awk '{print $6";"$7";"$8";"$9}' > "${FIC_ACTIVITE_MAILBOX}"
done
#pour pister les fuites mémoires
docker stats --no-stream --format "table {{.Name}}\t{{.Container}}\t{{.MemUsage}}" | sort -k 3 -h > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_docker_memory_kaz.log"
ps aux --sort -rss > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_ps_kaz.log"
free -hlt > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_mem_kaz.log"
systemd-cgls --no-pager > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_cgls_kaz.log"
for i in $(docker container ls --format "{{.ID}}"); do docker inspect -f '{{.State.Pid}} {{.Name}}' $i; done > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_dockerpid_kaz.log"
#on piste cette saloperie d'ethercalc
#echo $(date +"%Y%m%d") >> "${KAZ_STATE_DIR}/metro/docker_stats_ethercalc.log"
#docker stats --no-stream ethercalcServ ethercalcDB >> "${KAZ_STATE_DIR}/metro/docker_stats_ethercalc.log"
#fab le 04/10/2022
#taille des dockers
docker system df -v > "${KAZ_STATE_DIR}/metro/$(date +"%Y%m%d")_docker_size_kaz.log"

View File

@@ -8,6 +8,7 @@ setKazVars
. $DOCKERS_ENV
. $KAZ_KEY_DIR/env-paheko
. $KAZ_KEY_DIR/env-kaz
URL_PAHEKO="$httpProto://${API_USER}:${API_PASSWORD}@kaz-paheko.$(echo $domain)"
@@ -51,14 +52,20 @@ TEXTE="
# exemple pour un compte asso de l'orga gogol avec le service dédié NC uniquement + une équipe dans l'agora
# dupont ; jean-louis; jean-louis.dupont@kaz.bzh ; gregomondo@kaz.bzh; gogol ; O; O; N; N; N; N;N;;gogol_team; 10
"
ExpMail() {
MAIL_DEST=$1
MAIL_SUJET=$2
MAIL_TEXTE=$3
printf "Subject:${MAIL_SUJET}\n${MAIL_TEXTE}" | msmtp ${MAIL_DEST}
}
Int_paheko_Action() {
# $1 est une action;
ACTION=$1
OPTION=$2
# on envoie la requête sur le serveur paheko avec la clause à créer
# problème de gestion de remontée de données dans la table services_users quand le compte a plus de 2 activités
#curl -s ${URL_PAHEKO}/api/sql -d "SELECT * from users cross join services_users on users.id = services_users.id_user where users.action_auto='${ACTION}';" >>${TFILE_INT_PAHEKO_ACTION}
curl -s ${URL_PAHEKO}/api/sql -d "SELECT * from users where action_auto='${ACTION}';" >>${TFILE_INT_PAHEKO_ACTION}
[ ! -z ${TFILE_INT_PAHEKO_ACTION} ] || { echo "probleme de fichier ${TFILE_INT_PAHEKO_ACTION}" ; exit 1;}
REP_ID=$(jq -c '.results[].id ' ${TFILE_INT_PAHEKO_ACTION} 2>/dev/null)
@@ -80,7 +87,7 @@ Int_paheko_Action() {
done
################################
# test du mail valide en $domain
echo ${email} | grep -i "${domain}" || { echo "le mail ${email} n'est pas en ${domain}"; exit ;}
echo ${email} | grep -i "${domain}" || { echo "Erreur : 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
@@ -118,8 +125,8 @@ Int_paheko_Action() {
nom_ok="${nom_ok#${sep}}"
prenom_ok="${prenom_ok#${sep}}"
if [ -z "${nom_ok}" ] || [ -z "${prenom_ok}" ]; then
echo "Il faut corriger le champ nom (peut être un nom de famille avec une particule ?) de paheko"
echo "je quitte et supprime le fichier ${FILE_CREATEUSER}"
ERRMSG="Erreur : Il faut corriger le champ nom qui contient plus de 2 infos dans paheko"
[ "${IP_MAIL}" = "true" ] && ExpMail ${IP_MAILDEST} "Erreur interrogation Paheko" "${ERRMSG}" || echo ${ERRMSG}
rm -f $FILE_CREATEUSER
exit
fi
@@ -141,8 +148,9 @@ Int_paheko_Action() {
nom_ok=$nom_orga
# test des caractères autorisés dans le nom d' orga: lettres, chiffres et/ou le tiret
if ! [[ "${nom_ok}" =~ ^[[:alnum:]-]+$ ]]; then
echo "Erreur : l' orga doit être avec des lettres et/ou des chiffres. Le séparateur doit être le tiret"
rm -f $FILE_CREATEUSER<EFBFBD>
ERRMSG="Erreur : l' orga doit être avec des lettres et/ou des chiffres. Le séparateur doit être le tiret"
[ "${IP_MAIL}" = "true" ] && ExpMail ${IP_MAILDEST} "Erreur interrogation Paheko" "${ERRMSG}" || echo ${ERRMSG}
rm -f $FILE_CREATEUSER
exit 2
fi
prenom_ok=organisation

View File

@@ -6,10 +6,12 @@ def getDockersConfig(key):
for line in config:
if line.startswith(f"{key}="):
return line.split("=", 1)[1].split("#")[0].strip()
raise Exception(f"getDockersConfig(): No config for {key}")
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()
raise Exception(f"getSecretConfig(): No config for {serv}/{key}")

View File

@@ -3,8 +3,8 @@ import requests
from .config import getDockersConfig, getSecretConfig
paheko_ident = getDockersConfig("paheko_API_USER")
paheko_pass = getDockersConfig("paheko_API_PASSWORD")
paheko_ident = getSecretConfig("paheko", "API_USER")
paheko_pass = getSecretConfig("paheko", "API_PASSWORD")
paheko_auth = (paheko_ident, paheko_pass)
paheko_url = f"https://kaz-paheko.{getDockersConfig('domain')}"
@@ -24,14 +24,22 @@ class Paheko:
return None
def get_categorie_id(self, categorie_name):
categories = self.get_categories()
for categorie in categories.values():
if categorie["name"] == categorie_name:
return categorie["id"]
return None
def get_users_in_categorie(self,categorie):
"""
Afficher les membres d'une catégorie Paheko
"""
if not categorie.isdigit():
if not (isinstance(categorie, int) or categorie.isdigit()):
return 'Id de category non valide', 400
api_url = paheko_url + '/api/user/category/'+categorie+'.json'
api_url = f"{paheko_url}/api/user/category/{categorie}.json"
response = requests.get(api_url, auth=paheko_auth)

View File

@@ -28,10 +28,10 @@ docker restart ethercalcDB ethercalcServ
#docker exec sympaServ sendmail -q
#pour restart cette s.... de collabora
/kaz/bin/gestContainers.sh -office -m -r
#/kaz/bin/gestContainers.sh -office -m -r
#postfix
docker exec -it mailServ supervisorctl restart changedetector
#proxy
docker exec -i proxyServ bash -c "/etc/init.d/nginx reload"
#docker exec -i proxyServ bash -c "/etc/init.d/nginx reload"

View File

@@ -1,41 +1,4 @@
{
"__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": [
{
@@ -89,7 +52,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -169,7 +132,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -249,7 +212,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -331,7 +294,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -474,7 +437,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -597,7 +560,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -711,7 +674,7 @@
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
@@ -869,6 +832,5 @@
"timezone": "browser",
"title": "Docker monitoring par host",
"uid": "eekgch7tdq8sgc",
"version": 29,
"weekStart": ""
"version": 30
}

View File

@@ -1,7 +1,7 @@
services:
app:
image: mattermost/mattermost-team-edition:10.11.1
image: mattermost/mattermost-team-edition:10.12
container_name: ${mattermostServName}
restart: ${restartPolicy}
volumes:
@@ -39,12 +39,6 @@ services:
- "traefik.http.routers.${mattermostServName}.rule=Host(`${matterHost}.${domain}`)"
- "traefik.http.services.${mattermostServName}.loadbalancer.server.port=${matterPort}"
- "traefik.docker.network=mattermostNet"
# healthcheck:
# test: ["CMD", "curl", "-f", "http://app:${matterPort}"]
# interval: 20s
# retries: 10
# start_period: 20s
# timeout: 10s
postgres:
image: postgres:17-alpine

View File

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