skapi85
Anmeldungsdatum: 19. August 2017
Beiträge: Zähle...
|
Hallo,
ich habe eine Liste (openvpn ipp) die folgendermaßen aussieht:
| foo,10.2.0.200
bar,10.2.0.204
baz,10.2.0.208
qux,10.2.0.212
|
Bis jetzt habe ich diese Liste immer manuell bearbeitet, d.h. "bla" kommt hinzu und bekommt die ip 10.2.0.216, "bar" fällt weg (10.2.0.204), "blub" kommt hinzu und bekommt die ip 10.2.0.204 - da Verfügbar weil bar weggefallen ist.
Das möchte ich jetzt gerne mittels script automatisieren.
Ich möchte gerne dass das script prüft ob eine ip adresse verfügbar ist, wenn ja, dann verwende diese, wenn nein füge eine neue hinzu.
Leider komme ich nicht dahinter wie die Überprüfung der verhandenen bzw Lücken ip's programmiert werden kann.
Hätte vielleicht jemand einen Rat für mich?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ich weiß nicht, ob Du ab 200-255 zählst oder von 200-255 oder wo - der knappen Darstellung wegen habe ich mal 200-210 gewählt | for i in 10.2.0.2{00..10}; do grep -L $i bar.ips >/dev/null || echo $i ; done
10.2.0.201
10.2.0.202
10.2.0.203
10.2.0.205
10.2.0.206
10.2.0.207
10.2.0.209
10.2.0.210
|
Das wäre doch schonmal ein Anfang - finden aller ungenutzten IPs in dem Bereich.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
1
2
3
4
5
6
7
8
9
10
11
12 | #!/bin/sh
if [ -z "$1" -o -z "$2" ]; then
echo "ERROR: needs key and value." >&2
exit 1
fi
awk -F , -v "key=$1" -v "value=$2" '
$1 == key {print key FS value; changed=1}
$1 != key {print}
END {if (!changed) print key FS value}
' data > data.tmp && mv data.tmp data
|
|
skapi85
(Themenstarter)
Anmeldungsdatum: 19. August 2017
Beiträge: 48
|
Die ip's beginnen ab 10.2.0.4 und sollen bis 252 gezählt werden. @user_unknown: Deine for Schleife funktioniert super aber openvpn verlang immer von der letzten ip +4.
Zwei Beispiele was passieren soll:
| foo,10.2.0.4
bar,10.2.0.8
baz,10.2.0.12
qux,10.2.0.16
|
Hier wäre die richtige zu vergebende ip 10.2.0.20
| foo,10.2.0.4
bar,10.2.0.8
qux,10.2.0.16
bla,10.2.0.20
|
Hier wäre die richtige zu vergebende ip 10.2.0.12 Es müsste also ab 10.2.0.4 und immer um +4 hochgezählt werden und überprüft werden ob die ip vorhanden ist oder nicht
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Mit Python3 >= 3.6 könnte man z.B. sowas machen (wenn man auf f-Strings verzichtet, reicht Python 3.3):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | #!/usr/bin/env python3
import argparse
from ipaddress import ip_address
import sys
parser = argparse.ArgumentParser(description="manipulate host-ip list for openvpn")
parser.add_argument("config_file", metavar="CONFIG", help="the config file to change")
parser.add_argument("-a", "--add-host", nargs='*', help="add host to config")
parser.add_argument("-r", "--remove-host", nargs='*', help="remove host from config")
args = parser.parse_args()
valid_ips = set(ip_address(f"10.2.0.{x}") for x in range(4, 255, 4))
data = {}
with open(args.config_file) as f:
for line in f:
try:
host, ip = line.strip().split(',')
except ValueError:
print(f"invalid line in file: '{line.strip()}'", file=sys.stderr)
else:
data[host] = ip_address(ip)
if args.remove_host:
for host in args.remove_host:
data.pop(host, None)
unused_ips = valid_ips - set(data.values())
if args.add_host:
for ip, host in zip(sorted(unused_ips), args.add_host):
data[host] = ip
with open(args.config_file, 'w') as f:
for host, ip in sorted(data.items(), key=lambda x: x[-1]):
print(f"{host},{ip}", file=f)
|
Das Skript unterstützt die folgenden Argumente:
$ ./openvpn_cfg.py -h
usage: openvpn_cfg.py [-h] [-a [ADD_HOST [ADD_HOST ...]]] [-r [REMOVE_HOST [REMOVE_HOST ...]]] CONFIG
manipulate host-ip list for openvpn
positional arguments:
CONFIG the config file to change
optional arguments:
-h, --help show this help message and exit
-a [ADD_HOST [ADD_HOST ...]], --add-host [ADD_HOST [ADD_HOST ...]]
add host to config
-r [REMOVE_HOST [REMOVE_HOST ...]], --remove-host [REMOVE_HOST [REMOVE_HOST ...]]
remove host from config $ cat openvpn.cfg
foo,10.2.0.4
bar,10.2.0.8
baz,10.2.0.12
qux,10.2.0.16
$ ./openvpn_cfg.py openvpn.cfg -a bla
$ cat openvpn.cfg
foo,10.2.0.4
bar,10.2.0.8
baz,10.2.0.12
qux,10.2.0.16
bla,10.2.0.20
$ ./openvpn_cfg.py openvpn.cfg -r baz -a ham
$ cat openvpn.cfg
foo,10.2.0.4
bar,10.2.0.8
ham,10.2.0.12
qux,10.2.0.16
bla,10.2.0.20
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
rklm schrieb:
[...]
Ich sehe gerade, ich habe die Problemstellung falsch verstanden. Also, der Code macht nicht, was Du willst. Bin gerade zu müde das umzubauen. Vielleicht morgen.
|
skapi85
(Themenstarter)
Anmeldungsdatum: 19. August 2017
Beiträge: 48
|
@seahawk1986 Das Script von dir macht eigentlich genau das was ich möchte!
Ich muss leider bei bash bleiben, da die IP Überprüfung bzw das "add user & IP" in ein bestehendes script als Funktion eingefügt werden soll.
Das eigentliche Thema ist eben die Überprüfung der "IP-Lücke" bzw. das hochrechnen. Die for Schleife von user_unknown wäre ideal wenn die Hochrechnung nicht +1 wäre sondern +4.
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
skapi85 schrieb: Die for Schleife von user_unknown wäre ideal wenn die Hochrechnung nicht +1 wäre sondern +4.
Dann schau’ dir mal an, was er da verwendet, nämlich Brace Expansion. Da kann man auch die Schrittgröße angeben.
|
skapi85
(Themenstarter)
Anmeldungsdatum: 19. August 2017
Beiträge: 48
|
@Vain Das war der Hinweis den ich noch gebraucht habe!! 👍
| for i in 10.2.0.{4..240..4}; do grep -L $i /etc/openvpn/ipp.txt >/dev/null || echo $i ; done | head -1
|
So findet er den kleinsten Zähler!
Vielen lieben Dank für euere Hilfe!! 😀 👍
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
skapi85 schrieb: @seahawk1986 Das Script von dir macht eigentlich genau das was ich möchte!
Ich muss leider bei bash bleiben, da die IP Überprüfung bzw das "add user & IP" in ein bestehendes script als Funktion eingefügt werden soll.
Solange man Python3 verwenden darf, reicht ein here document 😉
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | function openvpn_cfg {
python3 - "$@" << EOF
import argparse
from ipaddress import ip_address
import sys
parser = argparse.ArgumentParser(description="manipulate host-ip list for openvpn")
parser.add_argument("config_file", metavar="CONFIG", help="the config file to change")
parser.add_argument("-a", "--add-host", nargs='*', help="add host to config")
parser.add_argument("-r", "--remove-host", nargs='*', help="remove host from config")
args = parser.parse_args()
valid_ips = set(ip_address(f"10.2.0.{x}") for x in range(4, 255, 4))
data = {}
with open(args.config_file) as f:
for line in f:
try:
host, ip = line.strip().split(',')
except ValueError:
print(f"invalid line in file: '{line.strip()}'", file=sys.stderr)
else:
data[host] = ip_address(ip)
if args.remove_host:
for host in args.remove_host:
data.pop(host, None)
unused_ips = valid_ips - set(data.values())
if args.add_host:
for ip, host in zip(sorted(unused_ips), args.add_host):
data[host] = ip
with open(args.config_file, 'w') as f:
for host, ip in sorted(data.items(), key=lambda x: x[-1]):
print(f"{host},{ip}", file=f)
EOF
}
openvpn_cfg openvpn.cfg -a bla
openvpn_cfg openvpn.cfg -r baz -a ham
|
Ansonsten mit der Bash ohne zigmal mit grep über die selbe Datei zu laufen (Python ist IMHO deutlich lesbarer):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 | #!/bin/bash
function openvpn_cfg {
cfg_file="$1"
if [ -z "$cfg_file" ]
then
echo "usage: $0 CFGFILE [add HOSTNAME [HOSTNAME..]] [remove HOSTNAME [HOSTNAME..]]"
exit 1
fi
declare -A hosts
declare -a hosts_to_add
declare -a hosts_to_remove
declare -a valid_ips
for i in {4..255..4}
do
valid_ips+=("10.2.0.${i}")
done
while IFS=',' read -r hostname ip
do
hosts["$hostname"]="$ip"
done < <( sort -n -k 2 -t ',' "$cfg_file")
while [ "$#" -gt 0 ]
shift
do
case "$1" in
--add)
state='add'
;;
--remove)
state='remove'
;;
*)
[ -z "$1" ] && continue
case "$state" in
add)
hosts_to_add+=("$1")
;;
remove)
hosts_to_remove+=("$1")
;;
*)
echo "usage: $0 CFGFILE [add HOSTNAME [HOSTNAME..]] [remove HOSTNAME [HOSTNAME..]]"
exit 1
;;
esac
;;
esac
done
for hostname in "${hosts_to_remove[@]}"
do
unset hosts["$hostname"]
done
for hostname in "${hosts_to_add[@]}"
do
if [ -n "${hosts["$hostname"]}" ]
then
continue
else
# add the hostname with the first free ip address
for ip in "${valid_ips[@]}"
do
for host in "${!hosts[@]}"
do
found=''
if [ "${hosts["$host"]}" = "$ip" ]
then
found="$ip"
continue 2
fi
done
if [ -z "$found" ]
then
hosts["$hostname"]="$ip"
continue 2
fi
done
fi
done
for host in "${!hosts[@]}"
do
echo "${host},${hosts["$host"]}"
done | sort -n -k2 -t ',' > "$cfg_file"
}
openvpn_cfg /etc/openvpn/ipp.txt --add ham bla --remove foo qux
|
|