Philippe Caseiro
fcf243ae46
Correction du test qui cherche le header de la réponse des commandes ONE. Dans le cas qui nous occupe on cherche l'ID du cluster a partir du nom, si le nom contiens "ID" le test qui cherche les headers de la commande trouve que la ligne est également un header et donc ne retourne pas le résultat. Pour corriger j'utilise "re" et j'essaye de matcher "^.*ID " ce qui est beaucoup plus propre que de cherche juste "ID" dans la ligne. ref #13050 @2h
354 lines
12 KiB
Python
Executable File
354 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from pyeole import ihm
|
|
from pyeole import process
|
|
from creole.client import CreoleClient
|
|
from tempfile import mkstemp
|
|
|
|
import sys
|
|
import os
|
|
import csv
|
|
import logging
|
|
import re
|
|
|
|
LOG_FILE = '/var/log/one/eole-one-node.log'
|
|
|
|
#= Configure Logger ===
|
|
logger = logging.getLogger(__name__)
|
|
#std_handler = logging.StreamHandler(sys.stdout)
|
|
file_handler = logging.FileHandler(LOG_FILE)
|
|
|
|
logger.setLevel(logging.INFO)
|
|
#std_handler.setLevel(logging.INFO)
|
|
file_handler.setLevel(logging.DEBUG)
|
|
|
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
#std_handler.setFormatter(formatter)
|
|
file_handler.setFormatter(formatter)
|
|
|
|
#logger.addHandler(std_handler)
|
|
logger.addHandler(file_handler)
|
|
#= End Logger ===
|
|
|
|
|
|
class RunCmdError(Exception):
|
|
pass
|
|
|
|
|
|
class OneClient():
|
|
|
|
def __init__(self, user):
|
|
self.user = None
|
|
self.auth = None
|
|
self.root = '/var/lib/one'
|
|
|
|
if user:
|
|
self.user = user
|
|
else:
|
|
self.user = 'oneadmin'
|
|
|
|
user_info = process.system_out(['getent', 'passwd', user])[1]
|
|
if user_info:
|
|
self.root = user_info.split(':')[5]
|
|
|
|
command = ['cat', u'{0}/.one/one_auth'.format(self.root)]
|
|
res = process.system_out(command)
|
|
if res[0] == 0:
|
|
self.auth = res[1].split(':')
|
|
|
|
def __run_cmd__(self, cmd):
|
|
command = list(cmd)
|
|
command.extend(['--user', self.auth[0]])
|
|
command.extend(['--password', self.auth[1]])
|
|
|
|
res = process.system_out(command)
|
|
if res[0] == 0:
|
|
if 'list' in cmd:
|
|
out_lines = []
|
|
if res:
|
|
for line in res[1].split('\n'):
|
|
if len(line) == 0:
|
|
next
|
|
elif re.match('^.*ID ', line):
|
|
next
|
|
else:
|
|
out_lines.append(line.split())
|
|
return out_lines
|
|
else:
|
|
return res
|
|
else:
|
|
return False
|
|
|
|
def get_hosts(self):
|
|
""" get the list of hosts
|
|
"""
|
|
cmd = ['onehost', 'list']
|
|
cmd.extend(['-l', 'ID,NAME'])
|
|
res = self.__run_cmd__(cmd)
|
|
return(res)
|
|
|
|
def get_clusters(self):
|
|
""" get the cluster list
|
|
"""
|
|
cmd = ['onecluster', 'list']
|
|
cmd.extend(['-l', 'ID,NAME'])
|
|
return self.__run_cmd__(cmd)
|
|
|
|
def get_networks(self):
|
|
""" get the virtual network list
|
|
"""
|
|
cmd = ['onevnet', 'list']
|
|
cmd.extend(['-l', 'ID,NAME'])
|
|
return self.__run_cmd__(cmd)
|
|
|
|
def get_cluster_id_by_name(self, name):
|
|
cmd = ['onecluster', 'list']
|
|
cmd.extend(['-f', 'NAME={0}'.format(name)])
|
|
res = self.__run_cmd__(cmd)
|
|
ID = res[0][0]
|
|
return ID
|
|
|
|
def get_vnet_id_by_name(self, name):
|
|
cmd = ['onevnet', 'list']
|
|
cmd.extend(['-f', 'NAME={0}'.format(name)])
|
|
res = self.__run_cmd__(cmd)
|
|
ID = res[0][0]
|
|
return ID
|
|
|
|
def create_network(self, templatefile, cluster, vnet_name):
|
|
""" Create a network
|
|
"""
|
|
cmd = ['onevnet', 'create']
|
|
cmd.extend(['--user', self.auth[0]])
|
|
cmd.extend(['--password', self.auth[1][:-1]])
|
|
#cmd.extend(['-c', cluster])
|
|
cmd.append(templatefile)
|
|
res = process.system_out(cmd)
|
|
if res[0] == 0:
|
|
clt_id = self.get_cluster_id_by_name(cluster)
|
|
vnet_id = self.get_vnet_id_by_name(vnet_name)
|
|
res = self.__run_cmd__(['onecluster', 'addvnet', clt_id, vnet_id])
|
|
os.remove(templatefile)
|
|
if not res:
|
|
print("Error attaching {0} vnet to {1} cluster".format(vnet_name, cluster))
|
|
return False
|
|
else:
|
|
return True
|
|
else:
|
|
logger.error("Creation of virtual network with template {0} failed".format(templatefile))
|
|
return False
|
|
|
|
def update_network(self, templatefile, cluster, vnet_name):
|
|
""" Update a network
|
|
"""
|
|
vnet_id = self.get_vnet_id_by_name(vnet_name)
|
|
cmd = ['onevnet', 'update']
|
|
cmd.extend(['--user', self.auth[0]])
|
|
cmd.extend(['--password', self.auth[1][:-1]])
|
|
cmd.extend([vnet_id, templatefile])
|
|
|
|
res = process.system_out(cmd)
|
|
if res[0] == 0:
|
|
os.remove(templatefile)
|
|
return True
|
|
else:
|
|
logger.error("Update of virtual network with template {0} failed".format(templatefile))
|
|
return False
|
|
|
|
def delete_network(self, vnet_id):
|
|
cmd = ['onevnet', 'delete']
|
|
cmd.extend(['--user', self.auth[0]])
|
|
cmd.extend(['--password', self.auth[1][:-1]])
|
|
cmd.append(vnet_id)
|
|
|
|
res = process.system_out(cmd)
|
|
if res[0] == 0:
|
|
ihm.print_line("Network {0} deleted".format(vnet_id))
|
|
return True
|
|
else:
|
|
logger.error("Error deleting network {0}".format(vnet_id))
|
|
ihm.print_line("Error deleting network {0}".format(vnet_id))
|
|
return False
|
|
|
|
|
|
class OneNetwork():
|
|
def create(self, one_client):
|
|
tmpl_file = self.create_template()
|
|
if one_client.create_network(tmpl_file, self.cluster, self.zone):
|
|
ihm.print_line("Virtual network {0} created".format(self.zone))
|
|
return True
|
|
else:
|
|
ihm.print_line("Error Creating virtual network {0}".format(self.zone))
|
|
return False
|
|
|
|
def update(self, one_client):
|
|
tmpl_file = self.create_template(True)
|
|
if one_client.update_network(tmpl_file, self.cluster, self.zone):
|
|
ihm.print_line("Virtual network {0} updated".format(self.zone))
|
|
return True
|
|
else:
|
|
ihm.print_line("Error Updating virtual network {0}".format(self.zone))
|
|
return False
|
|
|
|
def manage(self, one_client):
|
|
found = False
|
|
vnet = one_client.get_networks()
|
|
network_name = self.zone
|
|
for net in vnet:
|
|
if network_name in net:
|
|
found = True
|
|
break
|
|
|
|
if not found:
|
|
return self.create(one_client)
|
|
else:
|
|
return self.update(one_client)
|
|
|
|
class OneNetworkL3(OneNetwork):
|
|
def __init__(self, net_info, cluster):
|
|
self.swname = net_info[0]
|
|
self.zone = u'{0}{1}'.format(net_info[10], net_info[1])
|
|
self.vlan = net_info[2]
|
|
self.vnet_addr = net_info[3]
|
|
self.vnet_mask = net_info[4]
|
|
self.vnet_gw = net_info[5]
|
|
self.vnet_rg_start = net_info[6]
|
|
self.vnet_rg_size = net_info[7]
|
|
self.vnet_dns = net_info[8]
|
|
self.vnet_trunk = net_info[9]
|
|
self.cluster = cluster
|
|
|
|
def create_template(self, update=False):
|
|
fd, tmp_path = mkstemp(prefix='oneVnet-')
|
|
template = open(tmp_path, 'w')
|
|
template.write('NAME = "{0}"\n'.format(self.zone))
|
|
if (update is False):
|
|
if self.vnet_rg_start and self.vnet_rg_size:
|
|
template.write('AR=[\n')
|
|
template.write('TYPE = "IP4",\n')
|
|
template.write('IP = "{0}",\n'.format(self.vnet_rg_start))
|
|
template.write('SIZE = "{0}"\n'.format(self.vnet_rg_size))
|
|
template.write(']\n')
|
|
else:
|
|
template.write('TYPE = FIXED\n')
|
|
|
|
if self.vlan:
|
|
template.write('VLAN = yes\n')
|
|
template.write('VLAN_ID = {0}\n'.format(self.vlan))
|
|
|
|
if self.vnet_trunk:
|
|
template.write('VLAN_TAGGED_ID = {0}\n'.format(self.vnet_trunk))
|
|
|
|
template.write('BRIDGE = {0}\n'.format(self.swname))
|
|
template.write('NETWORK_ADDRESS = {0}\n'.format(self.vnet_addr))
|
|
template.write('NETWORK_MASK = {0}\n'.format(self.vnet_mask))
|
|
template.write('GATEWAY = {0}\n'.format(self.vnet_gw))
|
|
template.write('DNS = {0}\n'.format(self.vnet_dns))
|
|
template.close()
|
|
return tmp_path
|
|
|
|
|
|
class OneNetworkL2(OneNetwork):
|
|
def __init__(self, net_info, cluster):
|
|
self.swname = net_info[0]
|
|
self.zone = u'{0}{1}'.format(net_info[6], net_info[1])
|
|
self.net_size = net_info[2]
|
|
self.first_mac = net_info[3]
|
|
self.tag = net_info[4]
|
|
self.trunk = net_info[5]
|
|
self.cluster = cluster
|
|
|
|
def create_template(self,update=False):
|
|
fd, tmp_path = mkstemp(prefix='oneVnet-')
|
|
template = open(tmp_path, 'w')
|
|
template.write('NAME = "{0}"\n'.format(self.zone))
|
|
|
|
if self.tag:
|
|
template.write('VLAN = yes\n')
|
|
template.write('VLAN_ID = "{0}"\n'.format(self.tag))
|
|
|
|
if self.trunk:
|
|
template.write('VLAN_TAGGED_ID = "{0}""\n'.format(self.trunk))
|
|
|
|
template.write('BRIDGE = {0}\n'.format(self.swname))
|
|
if self.net_size:
|
|
template.write("AR=[\n")
|
|
template.write(' TYPE = "ETHER",\n')
|
|
template.write(' SIZE = "{0}"\n'.format(self.net_size))
|
|
template.write("]\n")
|
|
template.close()
|
|
return tmp_path
|
|
|
|
def main():
|
|
client = CreoleClient()
|
|
one_client = OneClient('oneadmin')
|
|
networks = []
|
|
cluster = client.get_creole('one_cluster_name')
|
|
swname = client.get_creole('ovs_sw_name')
|
|
zones = client.get_creole('vnets')
|
|
vlans = client.get_creole('vnet_vlan_tag')
|
|
vnet_addr = client.get_creole('vnet_network_addr')
|
|
vnet_mask = client.get_creole('vnet_network_mask')
|
|
vnet_dns = client.get_creole('vnet_network_dns')
|
|
vnet_gw = client.get_creole('vnet_network_gw')
|
|
vnet_rg_start = client.get_creole('vnet_range_start')
|
|
vnet_rg_size = client.get_creole('vnet_range_size')
|
|
vnet_trunk = client.get_creole('vnet_vlan_trunk')
|
|
|
|
l2_vnet = client.get_creole('l2_vnets')
|
|
l2_vnet_size = client.get_creole('l2_vnet_size')
|
|
l2_vnet_vlan_tag = client.get_creole('l2_vnet_vlan_tag')
|
|
l2_vnet_vlan_trunk = client.get_creole('l2_vnet_vlan_trunk')
|
|
l2_vnet_first_mac = client.get_creole('l2_vnet_first_mac')
|
|
|
|
net_prefix = "CR_"
|
|
|
|
processed = []
|
|
for cpt in range(len(zones)):
|
|
if zones[cpt] not in processed:
|
|
info = []
|
|
info.append(swname)
|
|
info.append(zones[cpt])
|
|
info.append(vlans[cpt])
|
|
info.append(vnet_addr[cpt])
|
|
info.append(vnet_mask[cpt])
|
|
info.append(vnet_gw[cpt])
|
|
info.append(vnet_rg_start[cpt])
|
|
info.append(vnet_rg_size[cpt])
|
|
info.append(vnet_dns[cpt])
|
|
info.append(vnet_trunk[cpt])
|
|
info.append(net_prefix)
|
|
networks.append(OneNetworkL3(info, cluster))
|
|
processed.append(zones[cpt])
|
|
|
|
for i in range(len(l2_vnet)):
|
|
if l2_vnet[i] not in processed:
|
|
net_info = []
|
|
net_info.append(swname)
|
|
net_info.append(l2_vnet[i])
|
|
net_info.append(l2_vnet_size[i])
|
|
net_info.append(l2_vnet_first_mac[i])
|
|
net_info.append(l2_vnet_vlan_tag[i])
|
|
net_info.append(l2_vnet_vlan_trunk[i])
|
|
net_info.append(net_prefix)
|
|
networks.append(OneNetworkL2(net_info, cluster))
|
|
processed.append(l2_vnet[i])
|
|
|
|
if client.get_creole('activer_openvswitch'):
|
|
for network in networks:
|
|
if not network.manage(one_client):
|
|
exit(1)
|
|
else:
|
|
ihm.print_line(u'Open vSwitch disabled no need to configure virtual networks')
|
|
|
|
networks = one_client.get_networks()
|
|
for net in networks:
|
|
name = net[1]
|
|
if name.startswith(net_prefix):
|
|
if not name[3:] in zones and not name[3:] in l2_vnet:
|
|
one_client.delete_network(net[0])
|
|
|
|
exit(0)
|
|
|
|
main()
|