trunk merge, getting fierce..

This commit is contained in:
Trey Morris
2011-06-27 16:48:03 -05:00
17 changed files with 134 additions and 42 deletions

View File

@@ -56,11 +56,11 @@
import gettext import gettext
import glob import glob
import json import json
import netaddr
import os import os
import sys import sys
import time import time
import IPy
# If ../nova/__init__.py exists, add ../ to Python search path, so that # If ../nova/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python... # it will override what happens to be installed in /usr/(local/)lib/python...
@@ -525,14 +525,14 @@ class FloatingIpCommands(object):
def create(self, range): def create(self, range):
"""Creates floating ips for zone by range """Creates floating ips for zone by range
arguments: ip_range""" arguments: ip_range"""
for address in IPy.IP(range): for address in netaddr.IPNetwork(range):
db.floating_ip_create(context.get_admin_context(), db.floating_ip_create(context.get_admin_context(),
{'address': str(address)}) {'address': str(address)})
def delete(self, ip_range): def delete(self, ip_range):
"""Deletes floating ips by range """Deletes floating ips by range
arguments: range""" arguments: range"""
for address in IPy.IP(ip_range): for address in netaddr.IPNetwork(ip_range):
db.floating_ip_destroy(context.get_admin_context(), db.floating_ip_destroy(context.get_admin_context(),
str(address)) str(address))

View File

@@ -369,3 +369,23 @@ class AdminController(object):
raise exception.ApiError(_('Duplicate rule')) raise exception.ApiError(_('Duplicate rule'))
self.compute_api.trigger_provider_fw_rules_refresh(context) self.compute_api.trigger_provider_fw_rules_refresh(context)
return {'status': 'OK', 'message': 'Added %s rules' % rules_added} return {'status': 'OK', 'message': 'Added %s rules' % rules_added}
def describe_external_address_blocks(self, context):
blocks = db.provider_fw_rule_get_all(context)
# NOTE(todd): use a set since we have icmp/udp/tcp rules with same cidr
blocks = set([b.cidr for b in blocks])
blocks = [{'cidr': b} for b in blocks]
return {'externalIpBlockInfo':
list(sorted(blocks, key=lambda k: k['cidr']))}
def remove_external_address_block(self, context, cidr):
LOG.audit(_('Removing ip block from %s'), cidr, context=context)
cidr = urllib.unquote(cidr).decode()
# raise if invalid
netaddr.IPNetwork(cidr)
rules = db.provider_fw_rule_get_all_by_cidr(context, cidr)
for rule in rules:
db.provider_fw_rule_destroy(context, rule['id'])
if rules:
self.compute_api.trigger_provider_fw_rules_refresh(context)
return {'status': 'OK', 'message': 'Deleted %s rules' % len(rules)}

View File

@@ -23,7 +23,7 @@ datastore.
""" """
import base64 import base64
import IPy import netaddr
import os import os
import urllib import urllib
import tempfile import tempfile
@@ -452,7 +452,7 @@ class CloudController(object):
elif cidr_ip: elif cidr_ip:
# If this fails, it throws an exception. This is what we want. # If this fails, it throws an exception. This is what we want.
cidr_ip = urllib.unquote(cidr_ip).decode() cidr_ip = urllib.unquote(cidr_ip).decode()
IPy.IP(cidr_ip) netaddr.IPNetwork(cidr_ip)
values['cidr'] = cidr_ip values['cidr'] = cidr_ip
else: else:
values['cidr'] = '0.0.0.0/0' values['cidr'] = '0.0.0.0/0'

View File

@@ -1094,6 +1094,16 @@ def provider_fw_rule_get_all(context):
return IMPL.provider_fw_rule_get_all(context) return IMPL.provider_fw_rule_get_all(context)
def provider_fw_rule_get_all_by_cidr(context, cidr):
"""Get all provider-level firewall rules."""
return IMPL.provider_fw_rule_get_all_by_cidr(context, cidr)
def provider_fw_rule_destroy(context, rule_id):
"""Delete a provider firewall rule from the database."""
return IMPL.provider_fw_rule_destroy(context, rule_id)
################### ###################

View File

@@ -2421,6 +2421,7 @@ def provider_fw_rule_create(context, rule):
return fw_rule_ref return fw_rule_ref
@require_admin_context
def provider_fw_rule_get_all(context): def provider_fw_rule_get_all(context):
session = get_session() session = get_session()
return session.query(models.ProviderFirewallRule).\ return session.query(models.ProviderFirewallRule).\
@@ -2428,6 +2429,26 @@ def provider_fw_rule_get_all(context):
all() all()
@require_admin_context
def provider_fw_rule_get_all_by_cidr(context, cidr):
session = get_session()
return session.query(models.ProviderFirewallRule).\
filter_by(deleted=can_read_deleted(context)).\
filter_by(cidr=cidr).\
all()
@require_admin_context
def provider_fw_rule_destroy(context, rule_id):
session = get_session()
with session.begin():
session.query(models.ProviderFirewallRule).\
filter_by(id=rule_id).\
update({'deleted': True,
'deleted_at': utils.utcnow(),
'updated_at': literal_column('updated_at')})
################### ###################

View File

@@ -59,7 +59,7 @@ class GlanceImageService(service.BaseImageService):
"""Provides storage and retrieval of disk image objects within Glance.""" """Provides storage and retrieval of disk image objects within Glance."""
GLANCE_ONLY_ATTRS = ['size', 'location', 'disk_format', GLANCE_ONLY_ATTRS = ['size', 'location', 'disk_format',
'container_format'] 'container_format', 'checksum']
# NOTE(sirp): Overriding to use _translate_to_service provided by # NOTE(sirp): Overriding to use _translate_to_service provided by
# BaseImageService # BaseImageService

View File

@@ -20,6 +20,7 @@
import calendar import calendar
import inspect import inspect
import netaddr
import os import os
from nova import db from nova import db
@@ -27,7 +28,6 @@ from nova import exception
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova import utils from nova import utils
from IPy import IP
LOG = logging.getLogger("nova.linux_net") LOG = logging.getLogger("nova.linux_net")
@@ -707,7 +707,7 @@ def _dnsmasq_cmd(net):
'--listen-address=%s' % net['gateway'], '--listen-address=%s' % net['gateway'],
'--except-interface=lo', '--except-interface=lo',
'--dhcp-range=%s,static,120s' % net['dhcp_start'], '--dhcp-range=%s,static,120s' % net['dhcp_start'],
'--dhcp-lease-max=%s' % IP(net['cidr']).len(), '--dhcp-lease-max=%s' % len(netaddr.IPNetwork(net['cidr'])),
'--dhcp-hostsfile=%s' % _dhcp_file(net['bridge'], 'conf'), '--dhcp-hostsfile=%s' % _dhcp_file(net['bridge'], 'conf'),
'--dhcp-script=%s' % FLAGS.dhcpbridge, '--dhcp-script=%s' % FLAGS.dhcpbridge,
'--leasefile-ro'] '--leasefile-ro']

View File

@@ -47,12 +47,11 @@ topologies. All of the network commands are issued to a subclass of
import datetime import datetime
import math import math
import netaddr
import socket import socket
import pickle import pickle
from eventlet import greenpool from eventlet import greenpool
import IPy
from nova import context from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
@@ -550,8 +549,8 @@ class NetworkManager(manager.SchedulerDependentManager):
network_size, cidr_v6, gateway_v6, bridge, network_size, cidr_v6, gateway_v6, bridge,
bridge_interface, **kwargs): bridge_interface, **kwargs):
"""Create networks based on parameters.""" """Create networks based on parameters."""
fixed_net = IPy.IP(cidr) fixed_net = netaddr.IPNetwork(cidr)
fixed_net_v6 = IPy.IP(cidr_v6) fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
significant_bits_v6 = 64 significant_bits_v6 = 64
network_size_v6 = 1 << 64 network_size_v6 = 1 << 64
for index in range(num_networks): for index in range(num_networks):
@@ -559,16 +558,16 @@ class NetworkManager(manager.SchedulerDependentManager):
start_v6 = index * network_size_v6 start_v6 = index * network_size_v6
significant_bits = 32 - int(math.log(network_size, 2)) significant_bits = 32 - int(math.log(network_size, 2))
cidr = '%s/%s' % (fixed_net[start], significant_bits) cidr = '%s/%s' % (fixed_net[start], significant_bits)
project_net = IPy.IP(cidr) project_net = netaddr.IPNetwork(cidr)
net = {} net = {}
net['bridge'] = bridge net['bridge'] = bridge
net['bridge_interface'] = bridge_interface net['bridge_interface'] = bridge_interface
net['dns'] = FLAGS.flat_network_dns net['dns'] = FLAGS.flat_network_dns
net['cidr'] = cidr net['cidr'] = cidr
net['netmask'] = str(project_net.netmask()) net['netmask'] = str(project_net.netmask)
net['gateway'] = str(project_net[1]) net['gateway'] = str(list(project_net)[1])
net['broadcast'] = str(project_net.broadcast()) net['broadcast'] = str(project_net.broadcast)
net['dhcp_start'] = str(project_net[2]) net['dhcp_start'] = str(list(project_net)[2])
if num_networks > 1: if num_networks > 1:
net['label'] = '%s_%d' % (label, index) net['label'] = '%s_%d' % (label, index)
else: else:
@@ -578,15 +577,16 @@ class NetworkManager(manager.SchedulerDependentManager):
cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6], cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6],
significant_bits_v6) significant_bits_v6)
net['cidr_v6'] = cidr_v6 net['cidr_v6'] = cidr_v6
project_net_v6 = IPy.IP(cidr_v6)
project_net_v6 = netaddr.IPNetwork(cidr_v6)
if gateway_v6: if gateway_v6:
# use a pre-defined gateway if one is provided # use a pre-defined gateway if one is provided
net['gateway_v6'] = str(gateway_v6) net['gateway_v6'] = str(list(gateway_v6)[1])
else: else:
net['gateway_v6'] = str(project_net_v6[1]) net['gateway_v6'] = str(list(project_net_v6)[1])
net['netmask_v6'] = str(project_net_v6.prefixlen()) net['netmask_v6'] = str(project_net_v6._prefixlen)
if kwargs.get('vpn', False): if kwargs.get('vpn', False):
# this bit here is for vlan-manager # this bit here is for vlan-manager
@@ -627,7 +627,7 @@ class NetworkManager(manager.SchedulerDependentManager):
# to properties of the manager class? # to properties of the manager class?
bottom_reserved = self._bottom_reserved_ips bottom_reserved = self._bottom_reserved_ips
top_reserved = self._top_reserved_ips top_reserved = self._top_reserved_ips
project_net = IPy.IP(network['cidr']) project_net = netaddr.IPNetwork(network['cidr'])
num_ips = len(project_net) num_ips = len(project_net)
for index in range(num_ips): for index in range(num_ips):
address = str(project_net[index]) address = str(project_net[index])
@@ -845,8 +845,8 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
' than 4094')) ' than 4094'))
# check that num networks and network size fits in fixed_net # check that num networks and network size fits in fixed_net
fixed_net = IPy.IP(kwargs['cidr']) fixed_net = netaddr.IPNetwork(kwargs['cidr'])
if fixed_net.len() < kwargs['num_networks'] * kwargs['network_size']: if len(fixed_net) < kwargs['num_networks'] * kwargs['network_size']:
raise ValueError(_('The network range is not big enough to fit ' raise ValueError(_('The network range is not big enough to fit '
'%(num_networks)s. Network size is %(network_size)s') % '%(num_networks)s. Network size is %(network_size)s') %
kwargs) kwargs)

View File

@@ -56,8 +56,10 @@ def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None):
'other_config': {}} 'other_config': {}}
network_ref = session.call_xenapi('network.create', network_rec) network_ref = session.call_xenapi('network.create', network_rec)
# 2 - find PIF for VLAN # 2 - find PIF for VLAN
expr = "field 'device' = '%s' and \ # NOTE(salvatore-orlando): using double quotes inside single quotes
field 'VLAN' = '-1'" % bridge_interface # as xapi filter only support tokens in double quotes
expr = 'field "device" = "%s" and \
field "VLAN" = "-1"' % bridge_interface
pifs = session.call_xenapi('PIF.get_all_records_where', expr) pifs = session.call_xenapi('PIF.get_all_records_where', expr)
pif_ref = None pif_ref = None
# Multiple PIF are ok: we are dealing with a pool # Multiple PIF are ok: we are dealing with a pool

View File

@@ -38,6 +38,7 @@ class ImageMetaDataTest(unittest.TestCase):
'name': 'image1', 'name': 'image1',
'deleted': False, 'deleted': False,
'container_format': None, 'container_format': None,
'checksum': None,
'created_at': '2011-03-22T17:40:15', 'created_at': '2011-03-22T17:40:15',
'disk_format': None, 'disk_format': None,
'updated_at': '2011-03-22T17:40:15', 'updated_at': '2011-03-22T17:40:15',
@@ -53,6 +54,7 @@ class ImageMetaDataTest(unittest.TestCase):
'name': 'image2', 'name': 'image2',
'deleted': False, 'deleted': False,
'container_format': None, 'container_format': None,
'checksum': None,
'created_at': '2011-03-22T17:40:15', 'created_at': '2011-03-22T17:40:15',
'disk_format': None, 'disk_format': None,
'updated_at': '2011-03-22T17:40:15', 'updated_at': '2011-03-22T17:40:15',
@@ -68,6 +70,7 @@ class ImageMetaDataTest(unittest.TestCase):
'name': 'image3', 'name': 'image3',
'deleted': False, 'deleted': False,
'container_format': None, 'container_format': None,
'checksum': None,
'created_at': '2011-03-22T17:40:15', 'created_at': '2011-03-22T17:40:15',
'disk_format': None, 'disk_format': None,
'updated_at': '2011-03-22T17:40:15', 'updated_at': '2011-03-22T17:40:15',
@@ -104,7 +107,10 @@ class ImageMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app()) res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
self.assertEqual(200, res.status_int) self.assertEqual(200, res.status_int)
self.assertEqual('value1', res_dict['metadata']['key1']) expected = self.IMAGE_FIXTURES[0]['properties']
self.assertEqual(len(expected), len(res_dict['metadata']))
for (key, value) in res_dict['metadata'].items():
self.assertEqual(value, res_dict['metadata'][key])
def test_index_xml(self): def test_index_xml(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer() serializer = openstack.image_metadata.ImageMetadataXMLSerializer()

View File

@@ -81,5 +81,27 @@ class AdminApiTestCase(test.TestCase):
def test_block_external_ips(self): def test_block_external_ips(self):
"""Make sure provider firewall rules are created.""" """Make sure provider firewall rules are created."""
result = self.api.block_external_addresses(self.context, '1.1.1.1/32') result = self.api.block_external_addresses(self.context, '1.1.1.1/32')
self.api.remove_external_address_block(self.context, '1.1.1.1/32')
self.assertEqual('OK', result['status']) self.assertEqual('OK', result['status'])
self.assertEqual('Added 3 rules', result['message']) self.assertEqual('Added 3 rules', result['message'])
def test_list_blocked_ips(self):
"""Make sure we can see the external blocks that exist."""
self.api.block_external_addresses(self.context, '1.1.1.2/32')
result = self.api.describe_external_address_blocks(self.context)
num = len(db.provider_fw_rule_get_all(self.context))
self.api.remove_external_address_block(self.context, '1.1.1.2/32')
# we only list IP, not tcp/udp/icmp rules
self.assertEqual(num / 3, len(result['externalIpBlockInfo']))
def test_remove_ip_block(self):
"""Remove ip blocks."""
result = self.api.block_external_addresses(self.context, '1.1.1.3/32')
self.assertEqual('OK', result['status'])
num0 = len(db.provider_fw_rule_get_all(self.context))
result = self.api.remove_external_address_block(self.context,
'1.1.1.3/32')
self.assertEqual('OK', result['status'])
self.assertEqual('Deleted 3 rules', result['message'])
num1 = len(db.provider_fw_rule_get_all(self.context))
self.assert_(num1 < num0)

View File

@@ -1145,6 +1145,13 @@ class IptablesFirewallTestCase(test.TestCase):
provjump_rules.append(rule) provjump_rules.append(rule)
self.assertEqual(1, len(provjump_rules)) self.assertEqual(1, len(provjump_rules))
# remove a rule from the db, cast to compute to refresh rule
db.provider_fw_rule_destroy(admin_ctxt, provider_fw1['id'])
self.fw.refresh_provider_fw_rules()
rules = [rule for rule in self.fw.iptables.ipv4['filter'].rules
if rule.chain == 'provider']
self.assertEqual(1, len(rules))
class NWFilterTestCase(test.TestCase): class NWFilterTestCase(test.TestCase):
def setUp(self): def setUp(self):

View File

@@ -518,6 +518,16 @@ def loads(s):
return json.loads(s) return json.loads(s)
try:
import anyjson
except ImportError:
pass
else:
anyjson._modules.append(("nova.utils", "dumps", TypeError,
"loads", ValueError))
anyjson.force_implementation("nova.utils")
_semaphores = {} _semaphores = {}

View File

@@ -38,6 +38,7 @@ Supports KVM, LXC, QEMU, UML, and XEN.
import hashlib import hashlib
import multiprocessing import multiprocessing
import netaddr
import os import os
import random import random
import re import re
@@ -53,8 +54,6 @@ from xml.etree import ElementTree
from eventlet import greenthread from eventlet import greenthread
from eventlet import tpool from eventlet import tpool
import IPy
from nova import context from nova import context
from nova import db from nova import db
from nova import exception from nova import exception

View File

@@ -21,7 +21,7 @@
"""Network-releated utilities for supporting libvirt connection code.""" """Network-releated utilities for supporting libvirt connection code."""
import IPy import netaddr
from nova import context from nova import context
from nova import db from nova import db
@@ -34,18 +34,18 @@ FLAGS = flags.FLAGS
def get_net_and_mask(cidr): def get_net_and_mask(cidr):
net = IPy.IP(cidr) net = netaddr.IPNetwork(cidr)
return str(net.net()), str(net.netmask()) return str(net.ip), str(net.netmask)
def get_net_and_prefixlen(cidr): def get_net_and_prefixlen(cidr):
net = IPy.IP(cidr) net = netaddr.IPNetwork(cidr)
return str(net.net()), str(net.prefixlen()) return str(net.ip), str(net._prefixlen)
def get_ip_version(cidr): def get_ip_version(cidr):
net = IPy.IP(cidr) net = netaddr.IPNetwork(cidr)
return int(net.version()) return int(net.version)
def get_network_info(instance): def get_network_info(instance):

View File

@@ -8,7 +8,7 @@
fi fi
;; ;;
@@ -224,9 +225,11 @@ @@ -224,6 +225,7 @@
remove) remove)
if [ "${TYPE}" = "vif" ] ;then if [ "${TYPE}" = "vif" ] ;then
@@ -16,7 +16,3 @@
xenstore-rm "${HOTPLUG}/hotplug" xenstore-rm "${HOTPLUG}/hotplug"
fi fi
logger -t scripts-vif "${dev} has been removed" logger -t scripts-vif "${dev} has been removed"
remove_from_bridge
;;
esac
+

View File

@@ -1,7 +1,6 @@
SQLAlchemy==0.6.3 SQLAlchemy==0.6.3
pep8==0.5.0 pep8==0.5.0
pylint==0.19 pylint==0.19
IPy==0.70
Cheetah==2.4.4 Cheetah==2.4.4
M2Crypto==0.20.2 M2Crypto==0.20.2
amqplib==0.6.1 amqplib==0.6.1