#!/usr/bin/env python
import
sys
import
nmap
import
multiprocessing
import
time
import
socket, struct, fcntl
import
etcd
import
re
from docker
import
Client
import
subprocess
def get_local_ip(iface =
'em1'
):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockfd = sock.fileno()
SIOCGIFADDR = 0x8915
ifreq = struct.pack(
'16sH14s'
, iface, socket.AF_INET,
'\x00'
*14)
try:
res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
except:
return
None
ip = struct.unpack(
'16sH2x4s8x'
, res)[2]
return
socket.inet_ntoa(ip)
def get_etcd_info(key):
etcd_result=[]
r = etcd_client.
read
(
'%s%s'
%(docker_etcd_key,local_ip), recursive=True, sorted=True)
for
child
in
r.children:
if
child.
dir
is not True and
"Container_name"
in
child.value:
etcd_result.append(child.value)
return
etcd_result
def check_by_nmap(ip,port):
check_result=len(nm.scan(
'%s'
%ip,
'%s'
%port)[
'scan'
])
if
check_result == 0:
msg=
'%s'
%(ip)
return
msg
def docker_container_stop():
docker_container=docker_client.containers(all=True)
container_name=[]
container_stop_name=[]
for
i
in
docker_container:
if
re.match(
'Exited'
,i[
'Status'
]):
container_name.append(i[
'Names'
])
for
b
in
container_name:
for
c
in
b:
container_stop_name.append(c)
return
container_stop_name
def docker_container_all():
docker_container=docker_client.containers(all=True)
container_name=[]
container_stop_name=[]
for
i
in
docker_container:
container_name.append(i[
'Names'
])
for
b
in
container_name:
for
c
in
b:
container_stop_name.append(c)
return
container_stop_name
if
__name__ ==
"__main__"
:
nm = nmap.PortScanner()
etcd_client=etcd.Client(host=
'127.0.0.1'
, port=4001)
docker_client = Client(base_url=
'unix://var/run/docker.sock'
, version=
'1.15'
, timeout=10)
local_ip=get_local_ip(
'ovs1'
)
bridge=
'ovs2'
docker_etcd_key=
'/app/docker/'
port=
'22'
ip_list=[]
now_etcd_result=get_etcd_info(docker_etcd_key)
docker_container_stop_name=docker_container_stop()
docker_container_all_name=docker_container_all()
for
i
in
range(len(now_etcd_result)):
now_info=
eval
(now_etcd_result[i])
key=
'%s%s/vlan%s/container/%s'
%(docker_etcd_key,local_ip,now_info[
'Container_vlan'
],now_info[
'Container_name'
])
if
'/'
+now_info[
'Container_name'
] not
in
docker_container_stop_name and now_info[
'Container_status'
] !=
'delete'
:
ip_list.append(
eval
(now_etcd_result[i])[
'Container_ip'
].
split
(
'/'
)[0])
if
now_info[
'Container_status'
] ==
'stop'
:
now_info[
'Container_status'
]=
'running'
etcd_client.write(key,now_info)
else
:
now_info[
'Container_status'
]=
'stop'
etcd_client.write(key,now_info)
if
'/'
+now_info[
'Container_name'
] not
in
docker_container_all_name:
print
'%s %s will delete,because docker client had deleted!'
%(
time
.strftime(
'%Y-%m-%d %T'
),key)
now_info[
'Container_status'
]=
'delete'
etcd_client.write(key,now_info)
ip_list=list(
set
(ip_list))
if
len(ip_list) == 1:
num=1
elif
len(ip_list)>=4 and len(ip_list)<=8:
num=4
elif
len(ip_list) >8 and len(ip_list)<=20:
num=8
else
:
num=15
pool = multiprocessing.Pool(processes=num)
scan_result=[]
for
i
in
ip_list:
pool.apply_async(check_by_nmap, (i,port, ))
scan_result.append(pool.apply_async(check_by_nmap, (i,port, )))
pool.close()
pool.
join
()
result=[]
for
res
in
scan_result:
if
res.get() is not None:
result.append(res.get())
result=list(
set
(result))
if
len(result) <= 0:
print
'%s Everything is all right!'
%
time
.strftime(
'%Y-%m-%d %T'
)
sys.
exit
(1)
else
:
print
'%s container need modify container static ip is:%s'
%(
time
.strftime(
'%Y-%m-%d %T'
),result)
for
i
in
range(len(now_etcd_result)):
now_info=
eval
(now_etcd_result[i])
if
(now_info[
'Container_ip'
]).
split
(
'/'
)[0]
in
result:
modify_container=subprocess.Popen(
"`which pipework` %s %s %s@%s @%s &>>/dev/null && echo 0 || echo 1"
%(bridge,now_info[
'Container_name'
],now_info[
'Container_ip'
],now_info[
'Container_vlan_gateway'
].
split
(
'/'
)[0],now_info[
'Container_vlan'
]),shell=True,stdout=subprocess.PIPE)
if
(modify_container.stdout.readlines()[0]).strip(
'\n'
) == 0:
print
'container_name:%s container_ip:%s modify static ip is fail!'
%(now_info[
'Container_name'
],now_info[
'Container_ip'
])
else
:
print
'container_name:%s container_ip:%s modify static ip is success!'
%(now_info[
'Container_name'
],now_info[
'Container_ip'
])