From f7d7c0e822501d52932acc8d76dc77110d7e9917 Mon Sep 17 00:00:00 2001 From: Mauro Torrez Date: Sat, 25 May 2019 17:36:24 -0300 Subject: [PATCH] compatibilidad python3 --- action_plugins/ldap.py | 7 +- templates/ldap_backup.sh.j2 | 40 +++++++++ templates/ldap_restore.sh.j2 | 169 +++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 templates/ldap_backup.sh.j2 create mode 100644 templates/ldap_restore.sh.j2 diff --git a/action_plugins/ldap.py b/action_plugins/ldap.py index c5707c0..f94f7d5 100644 --- a/action_plugins/ldap.py +++ b/action_plugins/ldap.py @@ -11,6 +11,7 @@ import sys import re import base64 import io +from six import string_types try: import ldap import ldif @@ -265,7 +266,7 @@ class ActionModule(ActionBase): qfilter = '(objectClass=*)' # armar el filtro de búsqueda agregando los filtros adicionales - if isinstance(self.search_filter, basestring): + if isinstance(self.search_filter, string_types): qfilter = self.search_filter else: for f in self.search_filter: @@ -380,7 +381,7 @@ class ActionModule(ActionBase): '''Verificar/actualizar valor para un atributo''' if attribute in self.ATTR_PASSWORD: - if not isinstance(value, basestring): + if not isinstance(value, string_types): value = value[0] if checkPassword(self.attrs.get(attribute,[None])[0], value): # si la clave matchea, salir @@ -395,7 +396,7 @@ class ActionModule(ActionBase): value = [makeSecret(value)] # convertir el valor a una lista - if isinstance(value, basestring): + if isinstance(value, string_types): value = [value] changed = False diff --git a/templates/ldap_backup.sh.j2 b/templates/ldap_backup.sh.j2 new file mode 100644 index 0000000..2438349 --- /dev/null +++ b/templates/ldap_backup.sh.j2 @@ -0,0 +1,40 @@ +#!/bin/bash +# Ansible-generated LDAP backup script +# +# usage: ldap_backup.sh DN DIRECTORY KEEP +# where: +# DN is the base DN to backup +# DIRECTORY is where to save the backup +# KEEP number of backups to keep + +# utility functions +msg(){ ${VERBOSE:-true} && echo ${@} ; } +assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && msg ${@} ; exit 1 ; } } + +# Base DN to backup +DN=${1} +# Directory where backups are saved +BACKUP_DIR="${2:-{{ openldap_backup_dir }}}" +# Number of backups to keep +KEEP=${3:-{{openldap_backup_keep}}} + +# validate arguments +[[ -n "${DN}" ]] ; assert "ERROR: El primer argumento debe ser un DN." +[[ -n "${BACKUP_DIR}" ]] ; assert "ERROR: el segundo argumento (dir de backup) no puede estar vacío." +[[ "${KEEP}" -eq "${KEEP}" ]] 2> /dev/null ; assert "ERROR: el tercer argumento debe ser numérico." + +# create backup dir +mkdir -p "${BACKUP_DIR}" + +# check for commands +command -v /usr/sbin/slapcat > /dev/null +assert "ERROR: no se encuentra 'slapcat', por favor instale ldap-utils." + +# perform backup +/usr/sbin/slapcat -H "ldap:///${DN}" | \ + gzip -9 > "${BACKUP_DIR}/${DN}_$(date '+%F%H%M').ldif.gz" +assert "ERROR al hacer backup de ${DN}" + +# remove old files +find "${BACKUP_DIR}" -maxdepth 1 -type f -name "cn=config_*.ldif.gz" -print0 \ + | sort -z | tail -zn +${KEEP} | xargs -0 rm -f diff --git a/templates/ldap_restore.sh.j2 b/templates/ldap_restore.sh.j2 new file mode 100644 index 0000000..bdfadae --- /dev/null +++ b/templates/ldap_restore.sh.j2 @@ -0,0 +1,169 @@ +#!/bin/bash +# Ansible-generated LDAP backup script +# +# usage: ldap_backup.sh DN DIRECTORY KEEP +# where: +# DN is the base DN to backup +# DIRECTORY is where to save the backup +# KEEP number of backups to keep + +# utility functions +msg(){ ${VERBOSE:-true} && echo ${@} ; } +assert(){ [[ ${?} -eq 0 ]] || { [[ -n ${1} ]] && { msg ; msg ${@} ; } ; exit 1 ; } } +warn(){ [[ ${?} -eq 0 ]] || { [[ -n ${1} ]] && msg ${@} ; return 1 ; } } + +# All DNs configured on this server +ALL_DNs="{{ backup_domains | default([]) | union(['cn=config']) | join(' ')}}" +BACKUP_DIR="{{ openldap_backup_dir }}" + +# Restaurar backup dado por argumento, puede ser un DN o un archivo de backup +restaurar(){ + local ARG=${1} + local DN="" + local LDIF="" + + if [[ -f "${ARG}" ]] + then + # el argumento es un archivo, se debe adivinar el DN + DN="$(zcat -f ${ARG}| head -n1 | egrep '^dn:' | awk '{print $2}')" + LDIF="$(realpath ${ARG})" + else + # se toma el argumento como un DN, se debe encontrar el archivo + DN="${ARG}" + LDIF=$(find ${BACKUP_DIR} -type f -iname "*.ldif*" -print0 | xargs -0 zegrep -l "^dn: ${DN}\$" | sort | tail -n1) + fi + + [[ -n "${LDIF}" ]] + assert "ERROR: no se encontró un backup para restaurar ${DN}. " \ + "Por favor indíquelo como argumento." + + [[ "$(systemctl is-active slapd.service)" == "inactive" ]] + assert "FATAL: El servicio slapd.service está activo." + + # # validar que el DN es el correcto + # zcat -f "${LDIF}" | head -n1 | egrep -q "^dn: ${DN}\$" + # assert -e "FATAL: El archivo ${LDIF} no corresponde al DN ${DN}.\n\n" \ + # "Se esperaba como primer línea... dn: ${DN} \n" \ + # "Sin embargo, se encontró........ $( zcat -f "${LDIF}" | head -n1 )\n" + + # Determinar directorio de la base de datos y opciones de slapadd + # Caso general (datos) + DATA_DIR="/var/lib/ldap/${DN}" + SLAPADD_SW="{{ '-w' if openldap_provider else '' }}" + # Caso especial cn=config + [[ "${DN}" == "cn=config" ]] && { + DATA_DIR="/etc/ldap/slapd.d" + SLAPADD_SW="-F /etc/ldap/slapd.d/" + } + + # Nombre de la carpeta de backup + DATA_DIR_BAK="${DATA_DIR}.backup-$(date +%Y%m%d%H%M%S)" + + msg "Guardando backup en ${BACKUP_DIR}" + mv "${DATA_DIR}" "${DATA_DIR_BAK}" + mkdir "${DATA_DIR}" + msg "Cargando datos de ${DN} desde ${LDIF}" + zcat -f "${LDIF}" | slapadd -b "${DN}" ${SLAPADD_SW} + assert -e "FATAL: Error durante la restauración.\n" \ + "Puede volver al estado anterior renombrando ${DATA_DIR_BAK} -> ${DATA_DIR} " \ + "antes de volver a iniciar slapd." + + msg "Cambiando owner de ${DATA_DIR}" + chown -R openldap:openldap "${DATA_DIR}" + + msg "Se ha restaurado correctamente ${DN}." + return 0 +} + +ayuda() { + cat< /dev/null +assert "ERROR: no se encuentra 'slapadd', por favor instale ldap-utils." + +${INTERACTIVO} && { + msg -e "Se restaurarán los siguientes DNs/archivos:\n ${ARGS}" + msg "Esto causará la PÉRDIDA DE LOS DATOS ACTUALES en el directorio." + msg -n "¿Confirma que está seguro? (s/n) " + read TECLA + [[ "${TECLA,,}" == "s" ]] || { + msg "Abortando operación: no se realiza ningún cambio." + exit 3; + } +} + +# Detener servidor antes de restaurar +msg "Deteniendo servicio slapd..." +systemctl stop slapd.service + +# restaurar todo +for ARG in ${ARGS} +do restaurar ${ARG} +done + +msg "Reiniciando servicio slapd..." +systemctl start slapd.service