eole-one-master/postservice/31-one-netmng

384 lines
13 KiB
Python
Executable File

#!/usr/bin/env python
from pyeole import process
from pyeole.log import init_logging
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'
logger = None
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(':')
else:
msg = u"OneClient: unable to authenticate: '{stdout}', '{stderr}'"
logger.error(msg.format(stdout=res[1], stderr=res[2]))
def __run_cmd__(self, cmd):
logger.debug(u"OneClient: execute command '{cmd}'".format(cmd=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:
msg = u"OneClient: error executing '{cmd}': '{stdout}', '{stderr}'"
logger.error(msg.format(cmd=cmd, stdout=res[1], stderr=res[2]))
return False
def get_hosts(self):
""" get the list of hosts
"""
logger.debug(u"OneClient: list all hosts")
cmd = ['onehost', 'list']
cmd.extend(['-l', 'ID,NAME'])
res = self.__run_cmd__(cmd)
return(res)
def get_clusters(self):
""" get the cluster list
"""
logger.debug(u"OneClient: list all clusters")
cmd = ['onecluster', 'list']
cmd.extend(['-l', 'ID,NAME'])
return self.__run_cmd__(cmd)
def get_networks(self):
""" get the virtual network list
"""
logger.debug(u"OneClient: list all networks")
cmd = ['onevnet', 'list']
cmd.extend(['-l', 'ID,NAME'])
return self.__run_cmd__(cmd)
def get_cluster_id_by_name(self, name):
logger.debug(u"OneClient: get cluster named '{name}'".format(name=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):
logger.debug(u"OneClient: get network named '{name}'".format(name=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
"""
logger.info(u"OneClient: create network named '{name}'".format(name=vnet_name))
cmd = ['onevnet', 'create', templatefile]
res = self.__run_cmd__(cmd)
if res and res[0] == 0:
msg = u"OneClient: attach vnet '{vnet}' to cluster '{cluster}'"
logger.info(msg.format(vnet=vnet_name, cluster=cluster))
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])
if not res:
print("Error attaching {0} vnet to {1} cluster".format(vnet_name, cluster))
return False
else:
os.remove(templatefile)
return True
else:
logger.error(u"Creation of virtual network with template {0} failed".format(templatefile))
return False
def update_network(self, templatefile, cluster, vnet_name):
""" Update a network
"""
logger.info(u"OneClient: update network named '{name}'".format(name=vnet_name))
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(u"Update of virtual network with template {0} failed".format(templatefile))
return False
def delete_network(self, vnet_id):
logger.info(u"OneClient: delete network with ID '{id}'".format(id=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:
logger.info(u"Network {0} deleted".format(vnet_id))
return True
else:
logger.error(u"Error deleting network {0}".format(vnet_id))
return False
class OneNetwork():
def create(self, one_client):
logger.debug(u"OneNetwork: create network named '{name}'".format(name=self.zone))
tmpl_file = self.create_template()
if one_client.create_network(tmpl_file, self.cluster, self.zone):
logger.info(u"Virtual network {0} created".format(self.zone))
return True
else:
logger.error(u"Error Creating virtual network {0}".format(self.zone))
return False
def update(self, one_client):
logger.debug(u"OneNetwork: update network named '{name}'".format(name=self.zone))
tmpl_file = self.create_template(True)
if one_client.update_network(tmpl_file, self.cluster, self.zone):
logger.info(u"Virtual network {0} updated".format(self.zone))
return True
else:
logger.error(u"Error Updating virtual network {0}".format(self.zone))
return False
def manage(self, one_client):
logger.debug(u"OneNetwork: manage network named '{name}'".format(name=self.zone))
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):
logger.debug(u"OneNetworkL3: create template for network named '{name}'".format(name=self.zone))
fd, tmp_path = mkstemp(prefix='oneVnet-')
template = open(tmp_path, 'w')
template.write('NAME = "{0}"\n'.format(self.zone))
template.write('VN_MAD = ovswitch\n')
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):
logger.debug(u"OneNetworkL2: create template for network named '{name}'".format(name=self.zone))
fd, tmp_path = mkstemp(prefix='oneVnet-')
template = open(tmp_path, 'w')
template.write('NAME = "{0}"\n'.format(self.zone))
template.write('VN_MAD = ovswitch\n')
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 update is False and self.net_size:
template.write("AR=[\n")
template.write(' TYPE = "ETHER",\n')
if self.first_mac:
template.write(' MAC = "{0}",\n'.format(self.first_mac))
template.write(' SIZE = "{0}"\n'.format(self.net_size))
template.write("]\n")
template.close()
return tmp_path
def main():
global logger
logger = init_logging(name='postservice.opennebula.network',
level=u'INFO',
as_root=True,
console=True,
syslog=True)
logger.debug(u"Configure OpenNebula networks")
client = CreoleClient()
mode_ha = client.get_creole('activer_one_ha')
if mode_ha == "oui":
indx = client.get_creole('one_ha_server_index')
if indx != 0:
# Mode HA is on and we are not in the Leader
exit(0)
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:
logger.info(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()