Intégration de la branche release-6.3.0

This commit is contained in:
Jephté Clain 2017-04-04 04:05:36 +04:00
commit 8de590fb65
13 changed files with 385 additions and 46 deletions

View File

@ -1,3 +1,17 @@
## Version 6.3.0 du 04/04/2017-04:04
* `2fb17f7` implémenter dumpcsv --awk-map
* `42c6fa6` ne pas activer git-ssh.userconf par défaut
* `5061d4b` bug dans les règles par défaut de mssh
* `14c5667` mssh: portage générique de mfssh pour choisir l'exécutable ssh en fonction du réseau source et destination
* `a2480ec` apacheconfig: *.conf matche aussi *.ssl.conf et *-certs.conf
* `95aa12f` Intégration de la branche update-apacheconfig
* `f233ae1` support de l'option -p pour traiter les ligne de la forme <VirtualBox *:PORT>#*ip:IP
* `f908e1c` support de SITE_IP
* `999fb7f` bug
* `37a2dce` apacheconfig -K: support de plus de patterns pour le fichier modèle
* `ab4148c` cgilsxml.py: nouvelles options --first-spec et all-specs
## Version 6.2.0 du 13/03/2017-11:27
* `4a7b14b` ajouter un argument force à testupdated et testnewer

View File

@ -1 +1 @@
6.2.0
6.3.0

View File

@ -59,6 +59,11 @@ OPTIONS
Lors du déploiement de la configuration, les valeurs des variables
dynamiques sont remplacées dans les fichiers destination.
Les arguments qui restent sont passés tels quels à apache_autoconf
-p, --fix-ip
Corriger les lignes de la forme '<VirtualHost *:PORT>#*ip:IP' et les
remplacer par '<VirtualHost IP:PORT>'
Cela permet de déployer une version de production des fichiers de
configuration.
-N, --network-config
Mettre aussi à jour la configuration réseau.
-r, --certsdir CERTSDIR
@ -101,6 +106,7 @@ destdir=
nohideconfig=auto
templateopt=
FULLCONF=
fixip=
netconf=
aac_certsdir=
bits=
@ -133,6 +139,7 @@ args=(
-8,--jessie '$array_add TEMPLATECTL_VARS sysver=jessie'
--bits: bits=
-u,--update,--deploy action=deploy
-p,--fix-ip fixip=1
-N,--network-config netconf=1
-r:,--certsdir: aac_certsdir=
--localhosts action=localhosts
@ -188,6 +195,7 @@ elif [ "$action" == deploy -o "$action" == localhosts ]; then
args=(
-d "$destdir" --$action
${fixip:+--fix-ip}
${netconf:+--network-config}
${aac_certsdir:+-r "$aac_certsdir"}
${oneconf:+--one-conf "$oneconf"}
@ -208,11 +216,11 @@ elif [ "$action" == deploy -o "$action" == localhosts ]; then
"$destdir" "$aac_certsdir" \
"$config" "$oneconf" "$onemodule" "$onesite" \
"$custom_sysinfos" "$sysname" "$sysdist" "$sysver" "$bits" \
"$netconf" || die
"$netconf" "$fixip" || die
eend
elif [ "$action" == localhosts ]; then
etitle "Mise à jour de /etc/hosts"
apacheconfig_deploy_localhosts "$destdir" "$aac_certsdir" "$onesite" || die
apacheconfig_localhosts "$destdir" "$aac_certsdir" "$onesite" || die
eend
fi
@ -254,14 +262,17 @@ elif [ "$action" == new-site ]; then
ssltempl=
certstempl=
wwwtempl=
array_from_lines templs "$(list_files "$templdir" "*SITE.conf")"
[ ${#templs[*]} -gt 0 ] && clrtempl="${templs[0]}"
array_from_lines templs "$(list_files "$templdir" "*SITE.ssl.conf")"
[ ${#templs[*]} -gt 0 ] && ssltempl="${templs[0]}"
array_from_lines templs "$(list_files "$templdir" "*SITE-certs.conf")"
[ ${#templs[*]} -gt 0 ] && certstempl="${templs[0]}"
array_from_lines templs "$(list_dirs "$templdir" "*SITE")"
[ ${#templs[*]} -gt 0 ] && wwwtempl="${templs[0]}"
array_from_lines clrtempls "$(list_files "$templdir" "*SITE*.conf")"
array_from_lines ssltempls "$(list_files "$templdir" "*SITE*.ssl.conf")"
array_from_lines certstempls "$(list_files "$templdir" "*SITE*-certs.conf")"
for xtempl in "${ssltempls[@]}" "${certstempls[@]}"; do
array_del clrtempls "$xtempl"
done
[ ${#clrtempls[*]} -gt 0 ] && clrtempl="${clrtempls[0]}"
[ ${#ssltempls[*]} -gt 0 ] && ssltempl="${ssltempls[0]}"
[ ${#certstempls[*]} -gt 0 ] && certstempl="${certstempls[0]}"
array_from_lines wwwtempls "$(list_dirs "$templdir" "*SITE*")"
[ ${#wwwtempls[*]} -gt 0 ] && wwwtempl="${wwwtempls[0]}"
found=
for i in "$clrtempl" "$ssltempl" "$certstempl" "$wwwtempl"; do
@ -273,6 +284,44 @@ elif [ "$action" == new-site ]; then
die "$host n'est pas un nom d'hôte pleinement qualifié"
fi
hostip=
for i in "$clrtempl" "$ssltempl"; do
[ -n "$i" -a -f "$templdir/$i" ] || continue
quietgrep SITE_IP "$templdir/$i" && { hostip=1; break; }
done
if [ -n "$hostip" ]; then
# Il y a un champ SITE_IP, il faut demander à l'utilisateur l'adresse ip
# correspondante
[[ "$host" == *.* ]] && hostdomain="${host#*.}" || hostdomain=
pri=
hostip=
i=0
while [ $i -lt ${#PUBDOMAINS[*]} ]; do
if [ "${PUBDOMAINS[$i]}" == "$hostdomain" ]; then
pri="$VSPREFIX${host%$hostdomain}${PRIDOMAINS[$i]}"
resolv_ips ips "$pri"
if [ -n "$ips" ]; then
hostip="${ips[0]}"
break
fi
fi
i=$(($i + 1))
done
if [ -z "$hostip" ]; then
pri="$VSPREFIX$host"
resolv_ips ips "$pri"
[ -n "$ips" ] && hostip="${ips[0]}"
fi
if [ -n "$pri" -a -n "$hostip" ]; then
enote "Correspondance automatique $host --> $pri"
read_value "Veuillez confirmer l'adresse IP d'écoute" hostip "$hostip" N
else
enote "Vous devez saisir l'adresse IP privée correspondant à $host"
read_value "Veuillez entrer l'adresse IP *privée* d'écoute" hostip "" N
fi
[ -n "$hostip" ] || ewarn "Vous avez choisi de ne pas spécifier d'adresse IP d'écoute. Il faudra corriger manuellement les fichiers générés"
fi
etitle "$host"
hostname="${host%%.*}"
clrconf="${clrtempl/SITE/$hostname}"
@ -283,7 +332,10 @@ elif [ "$action" == new-site ]; then
mkdir -p "$destdir/certsconf"
mkdir -p "$destdir/sites"
sedscript="\
sedscript=
[ -n "$hostip" ] && sedscript="$sedscript
s/SITE_IP/$hostip/g"
sedscript="$sedscript
s/SITE.TLD/$host/g
s/SITE/$hostname/g"

View File

@ -11,7 +11,7 @@ complete -F __nutools_host_completion -o default uinst ruinst runs rruns
if __bash_completion_module_enabled ssh; then
shopt -u hostcomplete
complete -F _ssh ussh cssh
complete -F _ssh ussh cssh mssh
fi
if __bash_completion_module_enabled umount; then

View File

@ -4,3 +4,12 @@
#DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr
#DEFAULT_CERTSDIR=1507-renater
#DEFAULT_CANAME=1507-DigiCertCA.crt
# Valeurs des domaines publics et privés ainsi que préfixe pour les adresses de
# service. Chaque élément du tableau PUBDOMAINS doit avoir un correspondant dans
# le tableau PRIDOMAINS.
# Avec la configuration par défaut suivante, on considère que l'adresse
# privée correspondant à HOST.univ-reunion.fr est vs-HOST.univ.run
#PUBDOMAINS=(univ-reunion.fr)
#PRIDOMAINS=(univ.run)
#VSPREFIX=vs-

23
lib/default/mssh Normal file
View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Réseaux
NETWORKS=(
ur # université de la réunion
ksct # ks.jclain.fr
)
ur_INCLUDES=(10/8)
ur_EXCLUDES=(10.42/16)
ur_DOMAINS=(univ.run univ-reunion.fr)
ksct_INCLUDES=(192.168.97/24)
ksct_EXCLUDES=()
ksct_DOMAINS=(ct)
# Règles de la forme FROM:TO:SSH
RULES=(
ksct:ksct:ssh
:ksct:kssh
ur::ssh
:ur:fssh
)

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Spécifier le client SSH à utiliser pour git
#export GIT_SSH=mssh

View File

@ -1 +1 @@
014002000
014003000

View File

@ -325,6 +325,7 @@ function apache_autoconf() {
local sitesdir onesite cgibindir wwwdir certsconfdir rrdir onecms
local sysname sysdist sysver bits
local netconf destconfsdir a2xconf
local fixip
local restart=1
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __display_apache_autoconf_help' \
@ -349,6 +350,7 @@ function apache_autoconf() {
-8,--jessie sysver=jessie \
--bits: bits= \
--network-config netconf=1 \
--fix-ip fixip=1 \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then
@ -400,6 +402,10 @@ function apache_autoconf() {
# valeur dans les fichiers
local -a FILLVARS; local FILLSCRIPT FILLTEMP
__apache_autoconf_fillxxx "$@"
if [ -n "$fixip" ]; then
FILLSCRIPT="$FILLSCRIPT
"'s/<VirtualHost \*:\([0-9][0-9]*\)>#\*ip:\(.*\)$/<VirtualHost \2:\1>/'
fi
# Installation des packages système
if [ -f "$confdir/syspkgs.conf" ]; then
@ -884,6 +890,9 @@ function apacheconfig_initvars() {
DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr
DEFAULT_CERTSDIR=1507-renater
DEFAULT_CANAME=1507-DigiCertCA.crt
PUBDOMAINS=(univ-reunion.fr)
PRIDOMAINS=(univ.run)
VSPREFIX=vs-
set_defaults apacheconfig
TEMPLATE_NOWRITE_VARS=("${APACHECONFIG_TEMPLATE_NOWRITE_VARS[@]}")
@ -951,7 +960,7 @@ function apacheconfig_deploy() {
local destdir="$1" certsdir="$2"; shift; shift
local config="$1" oneconf="$2" onemodule="$3"; onesite="$4"; shift; shift; shift; shift
local custom_sysinfos="$1" sysname="$2" sysdist="$3" sysver="$4" bits="$5"; shift; shift; shift; shift; shift
local netconf="$1"; shift
local netconf="$1" fixip="$2"; shift; shift
local -a args
args=(--ignore "$(basename -- "$config")")
@ -960,6 +969,7 @@ function apacheconfig_deploy() {
[ -n "$onesite" ] && array_add args --one-site "$(basename -- "$onesite")"
[ -n "$custom_sysinfos" ] && array_add args --sysname "$sysname" --sysdist "$sysdist" --sysver "$sysver" --bits "$bits"
[ -n "$netconf" ] && array_add args --network-config
[ -n "$fixip" ] && array_add args --fix-ip
array_add args "$destdir" "$certsdir"
for __name in "${TEMPLATE_DYNAMIC_VARS[@]}"; do
array_add args "$__name=${!__name}"
@ -970,8 +980,7 @@ function apacheconfig_deploy() {
function apacheconfig_qs() {
# fonction pour simplifier l'utilisation de apacheconfig_deploy pour un
# répertoire spécifique
# $1=destdir $2=certsdir $3=netconf
local destdir="$1" certsdir="$2" netconf="$3"
# $1=destdir $2=certsdir $3=netconf $4=fixip
local config modified destdir autocreate
apacheconfig_initvars
apacheconfig_loadconf "$1"
@ -979,7 +988,7 @@ function apacheconfig_qs() {
"$destdir" "$2" \
"$config" "" "" "" \
"" "" "" "" "" \
"$3"
"$3" "$4"
}
function apacheconfig_localhosts() {

View File

@ -1758,7 +1758,7 @@ function sortcsv() { LANG=C lsortcsv "$@"; }
################################################################################
__DUMPCSV_HELP="\
Afficher les champs spécifiés pour traitement par le shell
Afficher les champs spécifiés pour traitement par le shell ou par awk
-S, --skip-lines nblines
Sauter nblines au début du flux
@ -1785,7 +1785,7 @@ Afficher les champs spécifiés pour traitement par le shell
Spécifier le nom à utiliser pour afficher les en-têtes avec l'option -h
-n, --name NAME
Spécifier le nom à utiliser pour les options -f, -a, -b
Spécifier le nom à utiliser pour les options -f, -a, -b, -w
-f, --function
Afficher les champs comme l'appel d'une fonction, e.g:
dump value00 value01...
@ -1815,6 +1815,28 @@ Afficher les champs spécifiés pour traitement par le shell
Le nom du tableau est fixé à 'values'. L'option -n permet de spécifier le
nom de la fonction, qui vaut 'dump' par défaut. Avec -h le nom par défaut
est 'dumph'
-w, --awk-map
Afficher les champs comme une fonction awk qui permet de rechercher une
valeur et d'afficher la valeur correspondante. L'option -n permet de
spécifier le nom de la fonction, qui vaut 'mapval' par défaut.
--wtype TYPE
Spécifier le type de fonction à générer avec l'option --awk-map. Le type par
défaut est 'value'
Avec le type 'value', la fonction générée est de la forme dump(inval). Cette
fonction prend en argument la valeur de la colonne spécifiée avec --wscol,
et si cette valeur est trouvée dans les données, retourner la valeur de la
colonne spécifiée avec --wrcol
Avec le type 'array', la fonction générée est de la forme dump(inval, outvs)
Cette fonction prend en argument la valeur de la colonne spécifiée avec
--wscol, et si cette valeur est trouvée dans les données, le tableau outvs
est rempli avec les donnée de la ligne correspondante.
--wscol SFIELD
Nom du champ qui est cherché par la fonction générée avec l'option --awk-map
La valeur par défaut est '1', c'est à dire le premier champ.
--wrcol RFIELD
Nom du champ dont la valeur est retournée par la fonction générée avec
l'option '--awk-map --wtype value' en cas de correspondance.
La valeur par défaut est '2', c'est à dire le deuxième champ.
-v, --var
Affiche les champ en initialisant des variables, e.g:
names=(header0 header1)
@ -1838,6 +1860,7 @@ function ldumpcsv() {
eval "$(utools_local)"
local skip= parse_headers=1 keepf skipf show_headers
local dump=function reset=1 name hname
local wtype wscol wrcol
parse_opts "${PRETTYOPTS[@]}" \
-S:,--skip:,--skip-lines:,--skiplines: skip= \
-H,--parse-headers parse_headers=1 \
@ -1852,6 +1875,10 @@ function ldumpcsv() {
--reset reset=1 \
--no-reset reset= \
-b,--array-function dump=array-function \
-w,--awk-map dump=awk-map \
--wtype: wtype= \
--wscol: wscol= \
--wrcol: wrcol= \
-v,--var dump=var \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
@ -1876,13 +1903,64 @@ function ldumpcsv() {
case "$dump" in
function|array-function) name=dump;;
array) name=values;;
awk-map) name=mapval;;
esac
fi
case "${wtype:-value}" in
array|a) wtype=array;;
value|v) wtype=value;;
esac
[ -n "$wscol" ] || wscol=1
[ -n "$wrcol" ] || wrcol=2
local -a fields
fields=("$@")
awkcsv "${args[@]}" -v show_headers:int="$show_headers" -v hname="$hname" -v name="$name" -v dump="$dump" -v reset_values:int="$reset" -v fields[@] -e '
awkcsv "${args[@]}" -v show_headers:int="$show_headers" \
-v hname="$hname" -v name="$name" -v dump="$dump" \
-v reset_values:int="$reset" -v fields[@] \
-v wtype="$wtype" -v wscol="$wscol" -v wrcol="$wrcol" \
-e '
function init_fields() {
if (do_once("init_fields")) {
if (fields_count == 0) {
array_copy(fields, HEADERS)
fields_count = array_len(fields)
}
}
}
function before_awkmap(name, wtype) {
if (do_once("before_awkmap")) {
if (wtype == "value") {
print "function " name "(inval) {"
} else if (wtype == "array") {
print "function " name "(inval, outvs) {"
}
}
}
function awkmap(inval, outval, values, count, wtype, i) {
if (wtype == "value") {
print "if (inval == " qawk(inval) ") return " qawk(outval)
} else if (wtype == "array") {
print "if (inval == " qawk(inval) ") {"
print "delete outvs"
for (i = 1; i <= count; i++) {
print "outvs[" i "] = " qawk(values[i])
}
print "return 1"
print "}"
}
}
function after_awkmap() {
if (do_once("after_awkmap")) {
if (wtype == "value") {
print "return \"\""
} else if (wtype == "array") {
print "return 0"
}
print "}"
}
}
function dump_values(name, values, dump) {
if (dump == "function") {
print qarr(values, name)
@ -1899,12 +1977,8 @@ function dump_values(name, values, dump) {
}
}
}
function init_fields() {
if (do_once("init_fields")) {
if (fields_count == 0) {
array_copy(fields, HEADERS)
fields_count = array_len(fields)
}
function before_dump() {
if (do_once("before_dump")) {
if (show_headers) {
dump_values(hname, fields, dump == "var"? "array": dump)
}
@ -1922,10 +1996,26 @@ function init_fields() {
values[i] = get(fields[i])
i++
}
dump_values(name, values, dump)
if (dump == "awk-map") {
before_awkmap(name, wtype)
if (wscol ~ /^[0-9]+$/) inval = geti(wscol)
else inval = get(wscol)
if (wrcol ~ /^[0-9]+$/) outval = geti(wrcol)
else outval = get(wrcol)
awkmap(inval, outval, values, fields_count, wtype)
} else {
before_dump()
dump_values(name, values, dump)
}
}
END {
init_fields()
if (dump == "awk-map") {
before_awkmap(name, wtype)
after_awkmap()
} else {
before_dump()
}
}' -a ''
}

View File

@ -1780,6 +1780,12 @@ function unquote_html(s) {
gsub(/&amp;/, "\\&", s)
return s
}
function qawk(s) {
gsub(/\\/, "\\\\", s)
gsub(/"/, "\\\"", s)
gsub(/\n/, "\\n", s)
return "\"" s "\""
}
function qval(s) {'"
gsub(/'/, \"'\\\\''\", s)
return \"'\" s \"'\"

View File

@ -179,7 +179,7 @@ class File:
else: self.vars[name] = value
def __repr__(self): return 'File<%s>' % (self.pf)
def find_files(basedir, filters):
def find_files(basedir, filters, spec_method='all'):
basedir = path.abspath(basedir)
files = []
deep_filters = [filter for filter in filters if filter.re_spec is not None and filter.deep_scan]
@ -190,11 +190,21 @@ def find_files(basedir, filters):
# exception se produit
try: file = File(dirpath, filename)
except: continue
matched = False
allowed = False
matched1 = matched = False
allowed1 = allowed = False
for filter in deep_filters:
matched = filter.match_fill(file, basedir) or matched
allowed = filter.match_allow(file) or allowed
if spec_method == 'all' or \
(spec_method == 'first' and not matched):
matched1 = filter.match_fill(file, basedir)
else:
matched1 = False
matched = matched1 or matched
if spec_method == 'all' or \
(spec_method == 'first' and matched and not allowed):
allowed1 = filter.match_allow(file)
else:
allowed1 = False
allowed = allowed1 or allowed
if matched: pass
elif allowed: file.dontlist = True
else: continue
@ -207,11 +217,21 @@ def find_files(basedir, filters):
try: file = File(basedir, name)
except: continue
if not file.isfile(): continue
matched = False
allowed = False
matched1 = matched = False
allowed1 = allowed = False
for filter in simple_filters:
matched = filter.match_fill(file) or matched
allowed = filter.match_allow(file) or allowed
if spec_method == 'all' or \
(spec_method == 'first' and not matched):
matched1 = filter.match_fill(file, basedir)
else:
matched1 = False
matched = matched1 or matched
if spec_method == 'all' or \
(spec_method == 'first' and matched and not allowed):
allowed1 = filter.match_allow(file)
else:
allowed1 = False
allowed = allowed1 or allowed
if matched: pass
elif allowed: file.dontlist = True
else: continue
@ -411,6 +431,7 @@ def run_cgilsxml():
charset = 'utf-8'
default_content = ContentInfos()
default_filter = Filter(r'(.*)')
env = dict(filters=[], filter=None)
def add_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is not None: env['filters'].append(env['filter'])
env['filter'] = Filter(spec=value)
@ -420,16 +441,16 @@ def run_cgilsxml():
def allow_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter
env['filter'].allow_spec(value)
def add_var(option, opt_str, value, parser, *args, **kw):
def add_var(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter
env['filter'].add_var(value)
def set_group(option, opt_str, value, parser, *args, **kw):
def set_group(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter
env['filter'].set_group(value)
def set_break_on(option, opt_str, value, parser, *args, **kw):
def set_break_on(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter
env['filter'].set_break_on(value)
def set_content_disposition(option, opt_str, value, parser, *args, **kw):
def set_content_disposition(option, opt, value, parser, *args, **kw):
if value in ('attachment', 'inline'): pass
elif value == 'none': value = None
else:
@ -441,15 +462,16 @@ def run_cgilsxml():
sys.exit(1)
if env['filter'] is None: default_content.disposition = value
else: env['filter'].force_disposition = value
def set_content_type(option, opt_str, value, parser, *args, **kw):
def set_content_type(option, opt, value, parser, *args, **kw):
if env['filter'] is None: default_content.type = value
else: env['filter'].force_type = value
def set_content_charset(option, opt_str, value, parser, *args, **kw):
def set_content_charset(option, opt, value, parser, *args, **kw):
if env['filter'] is None: default_content.charset = value
else: env['filter'].force_charset = value
from optparse import OptionParser
OP = OptionParser(usage=u"\n\t%prog [options] /path/to/dir", description=__doc__)
OP.set_defaults(spec_method='all')
OP.add_option('-e', '--spec', dest='spec', action='callback', callback=add_spec, type='string',
help=u"Spécifier l'expression régulière permettant de sélectionner les fichiers à lister. "
+ u"La correspondance est tentée sur le nom du fichier avec la fonction match(). "
@ -460,6 +482,10 @@ def run_cgilsxml():
+ u"\n Il est possible de spécifier cette option plusieurs fois."
+ u"\n Note: TOUTES les expressions régulières sont testées par rapport au nom du fichier, et pour celles qui correspondent, les variables correspondantes sont définies. "
+ u"Il faut donc ordonner les expressions régulières de la plus générale à la plus spécifique, contrairement à ce qui se fait d'habitude.")
OP.add_option('--all-specs', dest='spec_method', action='store_const', const='all',
help=u"Avec l'option -e, tester toutes les expressions régulières dans l'ordre de définition. C'est le comportement par défaut.")
OP.add_option('--first-spec', dest='spec_method', action='store_const', const='first',
help=u"Avec l'option -e, arrêter à la première expression régulière qui correspond")
OP.add_option('--glob', dest='pattern', action='callback', callback=add_glob, type='string',
help=u"Comme --spec, mais en utilisant les patterns du shell *, ?, [seq], [!seq]. "
+ u"Si l'expression contient un caractère '/', la correspondance se fait sur le chemin complet du fichier avec le module glob. "
@ -533,7 +559,6 @@ def run_cgilsxml():
+ u"Il est possible de spécifier plusieurs paramètres en les séparant par des virgules.")
OP.add_option('-p', '--prefix', dest="prefix",
help=u"Ajouter les paramètres supplémentaires spécifiés à /result/env/query_string.")
env = dict(filters=[], filter=None)
o, args = OP.parse_args()
filters = env['filters']
filter = env['filter']
@ -577,7 +602,7 @@ def run_cgilsxml():
files = []
for basedir in args:
files.extend(find_files(basedir, filters))
files.extend(find_files(basedir, filters, o.spec_method))
sortfunc = build_sortfunc(sortby)
files = sort_files(files, sortfunc)
fgroups = build_fgroups(files)

107
mssh Executable file
View File

@ -0,0 +1,107 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib"
urequire DEFAULTS ipcalc
if [ $# -eq 1 -a "$1" == "--help" ]; then
exit_with uecho "$scriptname: Faire une connexion ssh en utilisant l'exécutable approprié au réseau source et destination
USAGE
$scriptname [user@]host"
fi
# fonctions de support
function match_network() {
local ip="$1" network="$2"
local -a includes excludes domains
local spec
array_copy includes "${network}_INCLUDES"
array_copy excludes "${network}_EXCLUDES"
array_copy domains "${network}_DOMAINS"
if ipcalc_checkip "$ip" >/dev/null; then
for spec in "${excludes[@]}"; do
if ipcalc_match "$ip" "$spec"; then
return 1
fi
done
for spec in "${includes[@]}"; do
if ipcalc_match "$ip" "$spec"; then
return 0
fi
done
else
for spec in "${domains[@]}"; do
[[ "$ip" == *."$spec" ]] && return 0
done
fi
return 1
}
# paramètres de l'environnement
DO=
if [ "$1" == --debug ]; then
# Activer le mode DEBUG
shift
set_verbosity -D
elif [ "$1" == --trace ]; then
# Activer le mode DEBUG
shift
set_verbosity -D
TRACE=1
DO=qvals
fi
NETWORKS=()
RULES=()
set_defaults mssh
# déterminer d'où l'on vient
from=
array_from_lines myips "$(ip addr | awk '$1 == "inet" { gsub(/\/.*/, "", $2); print $2 }')"
for network in "${NETWORKS[@]}"; do
for myip in "${myips[@]}"; do
if match_network "$myip" "$network"; then
from="$network"
break
fi
done
[ -n "$from" ] && break
done
edebug "FROM: ${from:-ANY} (${myips[*]})"
# analyser la ligne de commande
vars="$("$scriptdir/ussh" --parse "$@")" || exit 1
[ -n "$TRACE" ] && echo "$vars"
eval "$vars"
for userhost in "${hosts[@]}"; do
# déterminer où l'on veut aller
splituserhost "$userhost" user host
to=
for network in "${NETWORKS[@]}"; do
if match_network "$host" "$network"; then
to="$network"
break
fi
done
edebug "TO: ${to:-ANY} ($host)"
# Sélectionner la commande ssh à utiliser
found=
for rule in "${RULES[@]}"; do
splitfsep "$rule" : rfrom rule2
splitfsep "$rule2" : rto rssh
if [ \( -z "$rfrom" -o "$from" == "$rfrom" \) -a \
\( -z "$rto" -o "$to" == "$rto" \) ]; then
found=1
$DO ${exec:+exec} "$rssh" "${options[@]}" "$userhost" "${args[@]}"
break
fi
done
if [ -z "$found" ]; then
$DO ${exec:+exec} "$ssh" "${options[@]}" "$userhost" "${args[@]}"
fi
done