
There are some flake8 issues in each component that are not based on coding style rules . And There are some unittest issues in some component that need to be fixed Change-Id: Ic9a3f2c3b779ced225a42f69a495a606cb62517e Closes-Bug: #1350160
279 lines
7.6 KiB
Python
279 lines
7.6 KiB
Python
# Copyright 2013 IBM Corp.
|
|
|
|
'''
|
|
Created on Aug 2, 2013
|
|
|
|
@author: John Kasperski
|
|
'''
|
|
import fnmatch
|
|
|
|
from powervc.common.constants import LOCAL_OS
|
|
from powervc.common.constants import POWERVC_OS
|
|
from powervc.neutron.common import constants
|
|
from oslo.config import cfg
|
|
import json
|
|
|
|
from neutron.openstack.common import log as logging
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
CONF = cfg.CONF
|
|
|
|
|
|
def _compare_objects(local_obj, pvc_obj, db_obj,
|
|
update_fields, default_target):
|
|
for field in update_fields:
|
|
if pvc_obj.get(field) != local_obj.get(field):
|
|
update_data = db_obj.get('update_data')
|
|
if not update_data or len(update_data) == 0:
|
|
return default_target
|
|
try:
|
|
update_dict = json.loads(update_data)
|
|
except ValueError:
|
|
pass
|
|
update_dict = None
|
|
if not update_dict:
|
|
return default_target
|
|
db_field = update_dict.get(field)
|
|
if db_field != pvc_obj.get(field):
|
|
return LOCAL_OS
|
|
else:
|
|
return POWERVC_OS
|
|
return None
|
|
|
|
|
|
def compare_networks(local_net, pvc_net, db_net, default_target):
|
|
return _compare_objects(local_net, pvc_net, db_net,
|
|
constants.NETWORK_UPDATE_FIELDS, default_target)
|
|
|
|
|
|
def compare_subnets(local_sub, pvc_sub, db_sub, default_target):
|
|
return _compare_objects(local_sub, pvc_sub, db_sub,
|
|
constants.SUBNET_UPDATE_FIELDS, default_target)
|
|
|
|
|
|
def compare_ports(local_port, pvc_port, db_port, default_target):
|
|
return _compare_objects(local_port, pvc_port, db_port,
|
|
constants.PORT_UPDATE_FIELDS, default_target)
|
|
|
|
|
|
def _equal_objects(obj1, obj2, update_fields):
|
|
for field in update_fields:
|
|
if obj1.get(field) != obj2.get(field):
|
|
return False
|
|
return True
|
|
|
|
|
|
def equal_networks(net1, net2):
|
|
return _equal_objects(net1, net2, constants.NETWORK_UPDATE_FIELDS)
|
|
|
|
|
|
def equal_subnets(sub1, sub2):
|
|
return _equal_objects(sub1, sub2, constants.SUBNET_UPDATE_FIELDS)
|
|
|
|
|
|
def equal_ports(port1, port2):
|
|
return _equal_objects(port1, port2, constants.PORT_UPDATE_FIELDS)
|
|
|
|
|
|
def extract_ids_from_entry(obj):
|
|
pvc_id = obj.get('pvc_id')
|
|
local_id = obj.get('local_id')
|
|
return (pvc_id, local_id)
|
|
|
|
|
|
def extract_subnets_from_port(port):
|
|
subnets = []
|
|
fixed_ips = port.get('fixed_ips')
|
|
if not fixed_ips:
|
|
return []
|
|
for ip in fixed_ips:
|
|
subnet = ip.get('subnet_id')
|
|
if subnet and len(subnet) > 0:
|
|
subnets.append(subnet)
|
|
return subnets
|
|
|
|
|
|
def gen_network_sync_key(net):
|
|
result = ''
|
|
if 'provider:network_type' in net:
|
|
result += net['provider:network_type']
|
|
if 'provider:segmentation_id' in net:
|
|
if net['provider:segmentation_id']:
|
|
result += '_' + str(net['provider:segmentation_id'])
|
|
if 'provider:physical_network' in net:
|
|
if net['provider:physical_network']:
|
|
result += '_' + net['provider:physical_network']
|
|
return result
|
|
|
|
|
|
def gen_subnet_sync_key(sub, db_net):
|
|
return sub['cidr'] + '_' + db_net['pvc_id']
|
|
|
|
|
|
def gen_port_sync_key(port, db_net):
|
|
result = ''
|
|
fixed_ips = port.get('fixed_ips')
|
|
if not fixed_ips:
|
|
return False
|
|
for ip in fixed_ips:
|
|
ipaddr = ip.get('ip_address')
|
|
if ipaddr and '.' in ipaddr:
|
|
if len(result) == 0:
|
|
result += ipaddr
|
|
else:
|
|
result += '_' + ipaddr
|
|
return result + '_' + db_net['pvc_id']
|
|
|
|
|
|
def _gen_object_update_data(obj, update_fields):
|
|
data = {}
|
|
for field in update_fields:
|
|
data[field] = obj.get(field)
|
|
result = json.dumps(data)
|
|
if len(result) > constants.MAX_UPDATE_DATA_LENGTH:
|
|
return None
|
|
return result
|
|
|
|
|
|
def gen_network_update_data(net):
|
|
return _gen_object_update_data(net, constants.NETWORK_UPDATE_FIELDS)
|
|
|
|
|
|
def gen_subnet_update_data(sub):
|
|
return _gen_object_update_data(sub, constants.SUBNET_UPDATE_FIELDS)
|
|
|
|
|
|
def gen_port_update_data(port):
|
|
return _gen_object_update_data(port, constants.PORT_UPDATE_FIELDS)
|
|
|
|
|
|
def _get_map_white_list():
|
|
"""
|
|
Get pvc network white list. Easy to mock in a function.
|
|
"""
|
|
return CONF.AGENT.map_powervc_networks
|
|
|
|
|
|
def network_has_subnet(net):
|
|
"""
|
|
Check if a network has a subnet. PowerVC networks that do not have
|
|
a subnet are considerd DHCP networks. We don't support DHCP
|
|
"""
|
|
subnets = net.get('subnets')
|
|
if not subnets or len(subnets) == 0:
|
|
return False
|
|
return True
|
|
|
|
|
|
def is_network_mappable(net):
|
|
"""
|
|
Check if network can be sync
|
|
"""
|
|
if 'provider:network_type' in net:
|
|
network_type = net['provider:network_type']
|
|
if network_type != 'vlan':
|
|
return False
|
|
if 'provider:physical_network' in net:
|
|
physical_network = net['provider:physical_network']
|
|
if physical_network != 'default':
|
|
return False
|
|
return True
|
|
|
|
|
|
def network_has_mappable_subnet(client, net):
|
|
"""
|
|
Check if a network has mappable subnet, mappable subnet is defined in
|
|
method is is_subnet_mappable()
|
|
"""
|
|
subnets_id = net.get('subnets')
|
|
if subnets_id:
|
|
for sub_id in subnets_id:
|
|
subnet = client.get_subnet(sub_id)
|
|
if subnet and is_subnet_mappable(subnet):
|
|
return True
|
|
return False
|
|
|
|
|
|
def is_network_in_white_list(net):
|
|
"""
|
|
Check if a network's name is in the white list.
|
|
"""
|
|
whitelist = _get_map_white_list()
|
|
if whitelist:
|
|
"""
|
|
The following wildcards are allowed when
|
|
the network name matches a pattern in the white list.
|
|
(see the documentation for fnmatch):
|
|
* matches everything
|
|
? matches any single character
|
|
[seq] matches any character in seq
|
|
[!seq] matches any character not in seq
|
|
"""
|
|
for pat in whitelist:
|
|
if pat == '*':
|
|
return True
|
|
elif net.get('name') and fnmatch.fnmatch(net.get('name'), pat):
|
|
return True
|
|
# No match found.
|
|
return False
|
|
else:
|
|
# No network is allowed to sync.
|
|
return False
|
|
|
|
|
|
def is_subnet_mappable(sub):
|
|
if 'ip_version' in sub:
|
|
if sub['ip_version'] == 6:
|
|
return False
|
|
if 'enable_dhcp' in sub:
|
|
if sub['enable_dhcp']:
|
|
return False
|
|
return True
|
|
|
|
|
|
def is_port_mappable(port):
|
|
fixed_ips = port.get('fixed_ips')
|
|
if not fixed_ips:
|
|
return False
|
|
for ip in fixed_ips:
|
|
ipaddr = ip.get('ip_address')
|
|
if ipaddr and '.' in ipaddr:
|
|
return True
|
|
return False
|
|
|
|
|
|
def translate_net_id(db, net_id, target_os):
|
|
if target_os == LOCAL_OS:
|
|
db_net = db.get_network(pvc_id=net_id)
|
|
if db_net:
|
|
return db_net.get('local_id')
|
|
else:
|
|
db_net = db.get_network(local_id=net_id)
|
|
if db_net:
|
|
return db_net.get('pvc_id')
|
|
return None
|
|
|
|
|
|
def translate_subnet_id(db, sub_id, target_os):
|
|
if target_os == LOCAL_OS:
|
|
db_sub = db.get_subnet(pvc_id=sub_id)
|
|
if db_sub:
|
|
return db_sub.get('local_id')
|
|
else:
|
|
db_sub = db.get_subnet(local_id=sub_id)
|
|
if db_sub:
|
|
return db_sub.get('pvc_id')
|
|
return None
|
|
|
|
|
|
def translate_port_id(db, port_id, target_os):
|
|
if target_os == LOCAL_OS:
|
|
db_port = db.get_port(pvc_id=port_id)
|
|
if db_port:
|
|
return db_port.get('local_id')
|
|
else:
|
|
db_port = db.get_port(local_id=port_id)
|
|
if db_port:
|
|
return db_port.get('pvc_id')
|
|
return None
|