From f7beae47ca505443eb86ea1a4fba6b47c1658755 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 24 Feb 2011 17:07:59 -0800 Subject: IPV6 FlatManager changes --- nova/db/sqlalchemy/api.py | 11 ++-- .../versions/007_add_ipv6_flatmanager.py | 75 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 3 + nova/network/manager.py | 35 +++++++++- nova/virt/interfaces.template | 16 +++-- nova/virt/libvirt_conn.py | 27 +++++--- 6 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d8751bef4..9bc59de60 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -833,10 +833,13 @@ def instance_get_fixed_address_v6(context, instance_id): session = get_session() with session.begin(): instance_ref = instance_get(context, instance_id, session=session) - network_ref = network_get_by_instance(context, instance_id) - prefix = network_ref.cidr_v6 - mac = instance_ref.mac_address - return utils.to_global_ipv6(prefix, mac) + if 'nova.network.manager.FlatManager' == FLAGS.network_manager: + return instance_ref.fixed_ip['addressv6'] + else: + network_ref = network_get_by_instance(context, instance_id) + prefix = network_ref.cidr_v6 + mac = instance_ref.mac_address + return utils.to_global_ipv6(prefix, mac) @require_context diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py new file mode 100644 index 000000000..2951cbc0a --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py @@ -0,0 +1,75 @@ +# Copyright 2010 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import * +from migrate import * + +from nova import log as logging + + +meta = MetaData() + + +# Table stub-definitions +# Just for the ForeignKey and column creation to succeed, these are not the +# actual definitions of instances or services. +# +networks = Table('networks', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +fixed_ips = Table('fixed_ips', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +# +# New Tables +# +# None + +# +# Tables to alter +# +# None + +# +# Columns to add to existing tables +# + +networks_gatewayv6 = Column( + 'gatewayv6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)) + +networks_netmaskv6 = Column( + 'netmaskv6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)) + +fixed_ips_addressv6 = Column( + 'addressv6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + # Add columns to existing tables + networks.create_column(networks_gatewayv6) + networks.create_column(networks_netmaskv6) + fixed_ips.create_column(fixed_ips_addressv6) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 1882efeba..4fa4d443c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -385,6 +385,8 @@ class Network(BASE, NovaBase): ra_server = Column(String(255)) + gatewayv6 = Column(String(255)) + netmaskv6 = Column(String(255)) netmask = Column(String(255)) bridge = Column(String(255)) gateway = Column(String(255)) @@ -425,6 +427,7 @@ class FixedIp(BASE, NovaBase): __tablename__ = 'fixed_ips' id = Column(Integer, primary_key=True) address = Column(String(255)) + addressv6 = Column(String(255)) network_id = Column(Integer, ForeignKey('networks.id'), nullable=True) network = relationship(Network, backref=backref('fixed_ips')) instance_id = Column(Integer, ForeignKey('instances.id'), nullable=True) diff --git a/nova/network/manager.py b/nova/network/manager.py index 12a0c5018..61b5dc07f 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -361,9 +361,11 @@ class FlatManager(NetworkManager): fixed_net = IPy.IP(cidr) fixed_net_v6 = IPy.IP(cidr_v6) significant_bits_v6 = 64 + network_size_v6 = 1 << 64 count = 1 for index in range(num_networks): start = index * network_size + start_v6 = index * network_size_v6 significant_bits = 32 - int(math.log(network_size, 2)) cidr = "%s/%s" % (fixed_net[start], significant_bits) project_net = IPy.IP(cidr) @@ -382,14 +384,45 @@ class FlatManager(NetworkManager): count += 1 if(FLAGS.use_ipv6): - cidr_v6 = "%s/%s" % (fixed_net_v6[0], significant_bits_v6) + cidr_v6 = "%s/%s" % (fixed_net_v6[start_v6], + significant_bits_v6) net['cidr_v6'] = cidr_v6 + project_net_v6 = IPy.IP(cidr_v6) + net['gatewayv6'] = str(project_net_v6[1]) + net['netmaskv6'] = str(project_net_v6.prefixlen()) network_ref = self.db.network_create_safe(context, net) if network_ref: self._create_fixed_ips(context, network_ref['id']) + def _create_fixed_ips(self, context, network_id): + """Create all fixed ips for network.""" + network_ref = self.db.network_get(context, network_id) + # NOTE(vish): Should these be properties of the network as opposed + # to properties of the manager class? + bottom_reserved = self._bottom_reserved_ips + top_reserved = self._top_reserved_ips + project_net = IPy.IP(network_ref['cidr']) + + if(FLAGS.use_ipv6): + project_net_v6 = IPy.IP(network_ref['cidr_v6']) + + num_ips = len(project_net) + addressv6 = None + for index in range(num_ips): + address = str(project_net[index]) + if(FLAGS.use_ipv6): + addressv6 = str(project_net_v6[index]) + if index < bottom_reserved or num_ips - index < top_reserved: + reserved = True + else: + reserved = False + self.db.fixed_ip_create(context, {'network_id': network_id, + 'address': address, + 'addressv6': addressv6, + 'reserved': reserved}) + def get_network_host(self, context): """Get the network host for the current context.""" network_ref = self.db.network_get_by_bridge(context, diff --git a/nova/virt/interfaces.template b/nova/virt/interfaces.template index 87b92b84a..1db745f9f 100644 --- a/nova/virt/interfaces.template +++ b/nova/virt/interfaces.template @@ -8,10 +8,16 @@ iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static - address %(address)s - netmask %(netmask)s - broadcast %(broadcast)s - gateway %(gateway)s - dns-nameservers %(dns)s + address ${address} + netmask ${netmask} + broadcast ${broadcast} + gateway ${gateway} + dns-nameservers ${dns} +#if $use_ipv6 +iface eth0 inet6 static + address ${addressv6} + netmask ${netmaskv6} + gateway ${gatewayv6} +#end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4e0fd106f..b7712f76e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -146,6 +146,7 @@ class LibvirtConnection(object): self.libvirt_uri = self.get_uri() self.libvirt_xml = open(FLAGS.libvirt_xml_template).read() + self.interfaces_xml = open(FLAGS.injected_network_template).read() self._wrapped_conn = None self.read_only = read_only @@ -628,17 +629,27 @@ class LibvirtConnection(object): inst['id']) if network_ref['injected']: admin_context = context.get_admin_context() - address = db.instance_get_fixed_address(admin_context, inst['id']) + address = db.instance_get_fixed_address(admin_context, + inst['id']) + addressv6 = db.instance_get_fixed_address_v6(admin_context, + inst['id']) ra_server = network_ref['ra_server'] if not ra_server: ra_server = "fd00::" - with open(FLAGS.injected_network_template) as f: - net = f.read() % {'address': address, - 'netmask': network_ref['netmask'], - 'gateway': network_ref['gateway'], - 'broadcast': network_ref['broadcast'], - 'dns': network_ref['dns'], - 'ra_server': ra_server} + + interfaces_info = {'address': address, + 'netmask': network_ref['netmask'], + 'gateway': network_ref['gateway'], + 'broadcast': network_ref['broadcast'], + 'dns': network_ref['dns'], + 'ra_server': ra_server, + 'addressv6': addressv6, + 'gatewayv6': network_ref['gatewayv6'], + 'netmaskv6': network_ref['netmaskv6'], + 'use_ipv6': FLAGS.use_ipv6} + + net = str(Template(self.interfaces_xml, + searchList=[interfaces_info])) if key or net: inst_name = inst['name'] img_id = inst.image_id -- cgit From 20e9df05acdb89382023af1ac98cf040c827e18d Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Fri, 25 Feb 2011 14:49:33 -0800 Subject: DescribeInstances modified to return ipv6 fixed ip address in case of flatmanager --- nova/api/ec2/cloud.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 7458d307a..15799670c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -701,9 +701,13 @@ class CloudController(object): fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] if instance['fixed_ip']['network'] and 'use_v6' in kwargs: - i['dnsNameV6'] = utils.to_global_ipv6( - instance['fixed_ip']['network']['cidr_v6'], - instance['mac_address']) + if FLAGS.network_manager == \ + 'nova.network.manager.FlatManager': + i['dnsNameV6'] = instance['fixed_ip']['addressv6'] + else: + i['dnsNameV6'] = utils.to_global_ipv6( + instance['fixed_ip']['network']['cidr_v6'], + instance['mac_address']) i['privateDnsName'] = fixed_addr i['publicDnsName'] = floating_addr -- cgit From df0a4d66f7059db94e1de365fed8b8d244e16534 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 1 Mar 2011 17:12:47 -0800 Subject: Changed ra_server to gateway_v6 and removed addressv6 column from fixed_ips db table --- nova/api/ec2/cloud.py | 4 --- nova/db/sqlalchemy/api.py | 11 +++--- .../versions/007_add_ipv6_flatmanager.py | 24 ++++--------- nova/db/sqlalchemy/models.py | 5 ++- nova/network/linux_net.py | 2 +- nova/network/manager.py | 37 +++++--------------- nova/virt/interfaces.template | 6 ++-- nova/virt/libvirt.xml.template | 4 +-- nova/virt/libvirt_conn.py | 40 +++++++++++----------- 9 files changed, 47 insertions(+), 86 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 15799670c..b3779a4da 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -701,10 +701,6 @@ class CloudController(object): fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] if instance['fixed_ip']['network'] and 'use_v6' in kwargs: - if FLAGS.network_manager == \ - 'nova.network.manager.FlatManager': - i['dnsNameV6'] = instance['fixed_ip']['addressv6'] - else: i['dnsNameV6'] = utils.to_global_ipv6( instance['fixed_ip']['network']['cidr_v6'], instance['mac_address']) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9bc59de60..d8751bef4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -833,13 +833,10 @@ def instance_get_fixed_address_v6(context, instance_id): session = get_session() with session.begin(): instance_ref = instance_get(context, instance_id, session=session) - if 'nova.network.manager.FlatManager' == FLAGS.network_manager: - return instance_ref.fixed_ip['addressv6'] - else: - network_ref = network_get_by_instance(context, instance_id) - prefix = network_ref.cidr_v6 - mac = instance_ref.mac_address - return utils.to_global_ipv6(prefix, mac) + network_ref = network_get_by_instance(context, instance_id) + prefix = network_ref.cidr_v6 + mac = instance_ref.mac_address + return utils.to_global_ipv6(prefix, mac) @require_context diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py index 2951cbc0a..e09f46652 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py @@ -30,10 +30,6 @@ networks = Table('networks', meta, Column('id', Integer(), primary_key=True, nullable=False), ) -fixed_ips = Table('fixed_ips', meta, - Column('id', Integer(), primary_key=True, nullable=False), - ) - # # New Tables # @@ -42,24 +38,19 @@ fixed_ips = Table('fixed_ips', meta, # # Tables to alter # -# None + # # Columns to add to existing tables # -networks_gatewayv6 = Column( - 'gatewayv6', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)) - -networks_netmaskv6 = Column( - 'netmaskv6', +networks_gateway_v6 = Column( + 'gateway_v6', String(length=255, convert_unicode=False, assert_unicode=None, unicode_error=None, _warn_on_bytestring=False)) -fixed_ips_addressv6 = Column( - 'addressv6', +networks_netmask_v6 = Column( + 'netmask_v6', String(length=255, convert_unicode=False, assert_unicode=None, unicode_error=None, _warn_on_bytestring=False)) @@ -70,6 +61,5 @@ def upgrade(migrate_engine): meta.bind = migrate_engine # Add columns to existing tables - networks.create_column(networks_gatewayv6) - networks.create_column(networks_netmaskv6) - fixed_ips.create_column(fixed_ips_addressv6) + networks.create_column(networks_gateway_v6) + networks.create_column(networks_netmask_v6) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 4fa4d443c..f235054d2 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -385,8 +385,8 @@ class Network(BASE, NovaBase): ra_server = Column(String(255)) - gatewayv6 = Column(String(255)) - netmaskv6 = Column(String(255)) + gateway_v6 = Column(String(255)) + netmask_v6 = Column(String(255)) netmask = Column(String(255)) bridge = Column(String(255)) gateway = Column(String(255)) @@ -427,7 +427,6 @@ class FixedIp(BASE, NovaBase): __tablename__ = 'fixed_ips' id = Column(Integer, primary_key=True) address = Column(String(255)) - addressv6 = Column(String(255)) network_id = Column(Integer, ForeignKey('networks.id'), nullable=True) network = relationship(Network, backref=backref('fixed_ips')) instance_id = Column(Integer, ForeignKey('instances.id'), nullable=True) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 535ce87bc..e375568f1 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -361,7 +361,7 @@ interface %s command = _ra_cmd(network_ref) _execute(command) db.network_update(context, network_id, - {"ra_server": + {"gateway_v6": utils.get_my_linklocal(network_ref['bridge'])}) diff --git a/nova/network/manager.py b/nova/network/manager.py index 61b5dc07f..bdeeae293 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -388,41 +388,14 @@ class FlatManager(NetworkManager): significant_bits_v6) net['cidr_v6'] = cidr_v6 project_net_v6 = IPy.IP(cidr_v6) - net['gatewayv6'] = str(project_net_v6[1]) - net['netmaskv6'] = str(project_net_v6.prefixlen()) + net['gateway_v6'] = str(project_net_v6[1]) + net['netmask_v6'] = str(project_net_v6.prefixlen()) network_ref = self.db.network_create_safe(context, net) if network_ref: self._create_fixed_ips(context, network_ref['id']) - def _create_fixed_ips(self, context, network_id): - """Create all fixed ips for network.""" - network_ref = self.db.network_get(context, network_id) - # NOTE(vish): Should these be properties of the network as opposed - # to properties of the manager class? - bottom_reserved = self._bottom_reserved_ips - top_reserved = self._top_reserved_ips - project_net = IPy.IP(network_ref['cidr']) - - if(FLAGS.use_ipv6): - project_net_v6 = IPy.IP(network_ref['cidr_v6']) - - num_ips = len(project_net) - addressv6 = None - for index in range(num_ips): - address = str(project_net[index]) - if(FLAGS.use_ipv6): - addressv6 = str(project_net_v6[index]) - if index < bottom_reserved or num_ips - index < top_reserved: - reserved = True - else: - reserved = False - self.db.fixed_ip_create(context, {'network_id': network_id, - 'address': address, - 'addressv6': addressv6, - 'reserved': reserved}) - def get_network_host(self, context): """Get the network host for the current context.""" network_ref = self.db.network_get_by_bridge(context, @@ -448,6 +421,12 @@ class FlatManager(NetworkManager): net = {} net['injected'] = FLAGS.flat_injected net['dns'] = FLAGS.flat_network_dns + + if not FLAGS.fake_network: + if(FLAGS.use_ipv6): + net['gateway_v6'] = \ + utils.get_my_linklocal(FLAGS.flat_network_bridge) + self.db.network_update(context, network_id, net) def allocate_floating_ip(self, context, project_id): diff --git a/nova/virt/interfaces.template b/nova/virt/interfaces.template index 1db745f9f..3b34e54f4 100644 --- a/nova/virt/interfaces.template +++ b/nova/virt/interfaces.template @@ -16,8 +16,8 @@ iface eth0 inet static #if $use_ipv6 iface eth0 inet6 static - address ${addressv6} - netmask ${netmaskv6} - gateway ${gatewayv6} + address ${address_v6} + netmask ${netmask_v6} + gateway ${gateway_v6} #end if diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 88bfbc668..ef2d2cd6b 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -79,8 +79,8 @@ #if $getVar('extra_params', False) ${extra_params} #end if -#if $getVar('ra_server', False) - +#if $getVar('gateway_v6', False) + #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index b7712f76e..38fa2338e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -631,21 +631,21 @@ class LibvirtConnection(object): admin_context = context.get_admin_context() address = db.instance_get_fixed_address(admin_context, inst['id']) - addressv6 = db.instance_get_fixed_address_v6(admin_context, + address_v6 = db.instance_get_fixed_address_v6(admin_context, inst['id']) - ra_server = network_ref['ra_server'] - if not ra_server: - ra_server = "fd00::" + gateway_v6 = network_ref['gateway_v6'] + if not gateway_v6: + gateway_v6 = "fd00::" interfaces_info = {'address': address, 'netmask': network_ref['netmask'], 'gateway': network_ref['gateway'], 'broadcast': network_ref['broadcast'], 'dns': network_ref['dns'], - 'ra_server': ra_server, - 'addressv6': addressv6, - 'gatewayv6': network_ref['gatewayv6'], - 'netmaskv6': network_ref['netmaskv6'], + 'gateway_v6': gateway_v6, + 'address_v6': address_v6, + 'gateway_v6': network_ref['gateway_v6'], + 'netmask_v6': network_ref['netmask_v6'], 'use_ipv6': FLAGS.use_ipv6} net = str(Template(self.interfaces_xml, @@ -683,7 +683,7 @@ class LibvirtConnection(object): instance['id']) # Assume that the gateway also acts as the dhcp server. dhcp_server = network['gateway'] - ra_server = network['ra_server'] + gateway_v6 = network['gateway_v6'] if FLAGS.allow_project_net_traffic: if FLAGS.use_ipv6: @@ -728,8 +728,8 @@ class LibvirtConnection(object): 'local': instance_type['local_gb'], 'driver_type': driver_type} - if ra_server: - xml_info['ra_server'] = ra_server + "/128" + if gateway_v6: + xml_info['gateway_v6'] = gateway_v6 + "/128" if not rescue: if instance['kernel_id']: xml_info['kernel'] = xml_info['basepath'] + "/kernel" @@ -921,10 +921,10 @@ class FirewallDriver(object): """ raise NotImplementedError() - def _ra_server_for_instance(self, instance): + def _gateway_v6_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) - return network['ra_server'] + return network['gateway_v6'] class NWFilterFirewall(FirewallDriver): @@ -1140,8 +1140,8 @@ class NWFilterFirewall(FirewallDriver): 'nova-base-ipv6', 'nova-allow-dhcp-server'] if FLAGS.use_ipv6: - ra_server = self._ra_server_for_instance(instance) - if ra_server: + gateway_v6 = self._gateway_v6_for_instance(instance) + if gateway_v6: instance_secgroup_filter_children += ['nova-allow-ra-server'] ctxt = context.get_admin_context() @@ -1328,10 +1328,10 @@ class IptablesFirewallDriver(FirewallDriver): our_rules += ['-A %s -s %s -j ACCEPT' % (chain_name, cidr)] elif(ip_version == 6): # Allow RA responses - ra_server = self._ra_server_for_instance(instance) - if ra_server: + gateway_v6 = self._gateway_v6_for_instance(instance) + if gateway_v6: our_rules += ['-A %s -s %s -p icmpv6 -j ACCEPT' % - (chain_name, ra_server + "/128")] + (chain_name, gateway_v6 + "/128")] #Allow project network traffic if (FLAGS.allow_project_net_traffic): cidrv6 = self._project_cidrv6_for_instance(instance) @@ -1427,10 +1427,10 @@ class IptablesFirewallDriver(FirewallDriver): instance['id']) return network['gateway'] - def _ra_server_for_instance(self, instance): + def _gateway_v6_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) - return network['ra_server'] + return network['gateway_v6'] def _project_cidr_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), -- cgit From 0a9ba675c88ae0b2a18f47524d24075409261658 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 3 Mar 2011 15:39:23 -0800 Subject: altered ra_server name to gateway_v6 --- .../versions/007_add_ipv6_flatmanager.py | 14 ++-- .../versions/007_add_ipv6_to_fixed_ips.py | 90 ---------------------- 2 files changed, 6 insertions(+), 98 deletions(-) delete mode 100644 nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py index e09f46652..937712970 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py @@ -28,7 +28,10 @@ meta = MetaData() # networks = Table('networks', meta, Column('id', Integer(), primary_key=True, nullable=False), - ) + Column('ra_server', String(length=255, convert_unicode=False, + assert_unicode=None, unicode_error=None, + _warn_on_bytestring=False)) + ) # # New Tables @@ -43,12 +46,6 @@ networks = Table('networks', meta, # # Columns to add to existing tables # - -networks_gateway_v6 = Column( - 'gateway_v6', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)) - networks_netmask_v6 = Column( 'netmask_v6', String(length=255, convert_unicode=False, assert_unicode=None, @@ -60,6 +57,7 @@ def upgrade(migrate_engine): # bind migrate_engine to your metadata meta.bind = migrate_engine + # Alter column name + networks.c.ra_server.alter(name='gateway_v6') # Add columns to existing tables - networks.create_column(networks_gateway_v6) networks.create_column(networks_netmask_v6) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py deleted file mode 100644 index 427934d53..000000000 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_to_fixed_ips.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2011 OpenStack LLC -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from sqlalchemy import * -from migrate import * - -from nova import log as logging - - -meta = MetaData() - - -# Table stub-definitions -# Just for the ForeignKey and column creation to succeed, these are not the -# actual definitions of instances or services. -# -fixed_ips = Table( - "fixed_ips", - meta, - Column( - "id", - Integer(), - primary_key=True, - nullable=False)) - -# -# New Tables -# -# None - -# -# Tables to alter -# -# None - -# -# Columns to add to existing tables -# - -fixed_ips_addressV6 = Column( - "addressV6", - String( - length=255, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)) - - -fixed_ips_netmaskV6 = Column( - "netmaskV6", - String( - length=3, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)) - - -fixed_ips_gatewayV6 = Column( - "gatewayV6", - String( - length=255, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)) - - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - - # Add columns to existing tables - fixed_ips.create_column(fixed_ips_addressV6) - fixed_ips.create_column(fixed_ips_netmaskV6) - fixed_ips.create_column(fixed_ips_gatewayV6) -- cgit From 35be7d39866f6ac1017dd94d33d9c01f47a6bc74 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 3 Mar 2011 15:44:01 -0800 Subject: Removed properties added to fixed_ips by xs-ipv6 BP --- nova/db/sqlalchemy/models.py | 3 --- nova/network/manager.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 4c94cd3db..7b4683427 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -458,9 +458,6 @@ class FixedIp(BASE, NovaBase): allocated = Column(Boolean, default=False) leased = Column(Boolean, default=False) reserved = Column(Boolean, default=False) - addressV6 = Column(String(255)) - netmaskV6 = Column(String(3)) - gatewayV6 = Column(String(255)) class User(BASE, NovaBase): diff --git a/nova/network/manager.py b/nova/network/manager.py index fb6e16772..686ab9732 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -167,7 +167,7 @@ class NetworkManager(manager.Manager): # with a network, or a cluster of computes with a network # and use that network here with a method like # network_get_by_compute_host - network_ref = self.db.network_get_by_bridge(context, + network_ref = self.db.network_get_by_bridge(context.elevated(), FLAGS.flat_network_bridge) address = self.db.fixed_ip_associate_pool(context.elevated(), network_ref['id'], -- cgit From aa09f87060c1d1885b7a557ff26a3c421ad42df8 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 3 Mar 2011 17:31:37 -0800 Subject: remove ra_server from model and fix migration issue while running unit tests --- .../versions/007_add_ipv6_flatmanager.py | 60 +++++++++++++++++++--- nova/db/sqlalchemy/models.py | 2 - 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py index 937712970..d14f52af1 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py @@ -12,6 +12,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from lib2to3.fixer_util import String from sqlalchemy import * from migrate import * @@ -27,12 +28,59 @@ meta = MetaData() # actual definitions of instances or services. # networks = Table('networks', meta, + Column('created_at', DateTime(timezone=False)), + Column('updated_at', DateTime(timezone=False)), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', Boolean(create_constraint=True, name=None)), Column('id', Integer(), primary_key=True, nullable=False), - Column('ra_server', String(length=255, convert_unicode=False, - assert_unicode=None, unicode_error=None, - _warn_on_bytestring=False)) - ) - + Column('injected', Boolean(create_constraint=True, name=None)), + Column('cidr', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('netmask', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('bridge', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('gateway', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('broadcast', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('dns', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vlan', Integer()), + Column('vpn_public_address', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vpn_public_port', Integer()), + Column('vpn_private_address', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('dhcp_start', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('project_id', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('host', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('cidr_v6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column( + 'ra_server', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column( + 'label', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)) + ) # # New Tables # @@ -59,5 +107,5 @@ def upgrade(migrate_engine): # Alter column name networks.c.ra_server.alter(name='gateway_v6') - # Add columns to existing tables + # Add new column to existing table networks.create_column(networks_netmask_v6) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 7b4683427..14ff46647 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -402,8 +402,6 @@ class Network(BASE, NovaBase): cidr = Column(String(255), unique=True) cidr_v6 = Column(String(255), unique=True) - ra_server = Column(String(255)) - gateway_v6 = Column(String(255)) netmask_v6 = Column(String(255)) netmask = Column(String(255)) -- cgit From 1831f31af0ac21ded3535f15777bd5147c615c34 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Fri, 4 Mar 2011 11:52:18 -0800 Subject: added flatmanager unit testcases and renamed test_network.py to test_vlan_network.py --- nova/tests/test_flat_network.py | 276 +++++++++++++++++++++++++++++ nova/tests/test_network.py | 369 --------------------------------------- nova/tests/test_vlan_network.py | 373 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 649 insertions(+), 369 deletions(-) create mode 100644 nova/tests/test_flat_network.py delete mode 100644 nova/tests/test_network.py create mode 100644 nova/tests/test_vlan_network.py diff --git a/nova/tests/test_flat_network.py b/nova/tests/test_flat_network.py new file mode 100644 index 000000000..91a49920d --- /dev/null +++ b/nova/tests/test_flat_network.py @@ -0,0 +1,276 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Unit Tests for network code +""" +import IPy +import os +import unittest + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.auth import manager + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +class FlatNetworkTestCase(test.TestCase): + """Test cases for network code""" + def setUp(self): + super(FlatNetworkTestCase, self).setUp() + # NOTE(vish): if you change these flags, make sure to change the + # flags in the corresponding section in nova-dhcpbridge + self.flags(connection_type='fake', + fake_call=True, + fake_network=True) + self.manager = manager.AuthManager() + self.user = self.manager.create_user('netuser', 'netuser', 'netuser') + self.projects = [] + self.network = utils.import_object(FLAGS.network_manager) + self.context = context.RequestContext(project=None, user=self.user) + for i in range(5): + name = 'project%s' % i + project = self.manager.create_project(name, 'netuser', name) + self.projects.append(project) + # create the necessary network data for the project + user_context = context.RequestContext(project=self.projects[i], + user=self.user) + host = self.network.get_network_host(user_context.elevated()) + instance_ref = self._create_instance(0) + self.instance_id = instance_ref['id'] + instance_ref = self._create_instance(1) + self.instance2_id = instance_ref['id'] + + def tearDown(self): + # TODO(termie): this should really be instantiating clean datastores + # in between runs, one failure kills all the tests + db.instance_destroy(context.get_admin_context(), self.instance_id) + db.instance_destroy(context.get_admin_context(), self.instance2_id) + for project in self.projects: + self.manager.delete_project(project) + self.manager.delete_user(self.user) + super(FlatNetworkTestCase, self).tearDown() + + def _create_instance(self, project_num, mac=None): + if not mac: + mac = utils.generate_mac() + project = self.projects[project_num] + self.context._project = project + self.context.project_id = project.id + return db.instance_create(self.context, + {'project_id': project.id, + 'mac_address': mac}) + + def _create_address(self, project_num, instance_id=None): + """Create an address in given project num""" + if instance_id is None: + instance_id = self.instance_id + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + return self.network.allocate_fixed_ip(self.context, instance_id) + + def _deallocate_address(self, project_num, address): + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + self.network.deallocate_fixed_ip(self.context, address) + + def test_private_ipv6(self): + """Make sure ipv6 is OK""" + if FLAGS.use_ipv6: + instance_ref = self._create_instance(0) + address = self._create_address(0, instance_ref['id']) + network_ref = db.project_get_network( + context.get_admin_context(), + self.context.project_id) + address_v6 = db.instance_get_fixed_address_v6( + context.get_admin_context(), + instance_ref['id']) + self.assertEqual(instance_ref['mac_address'], + utils.to_mac(address_v6)) + instance_ref2 = db.fixed_ip_get_instance_v6( + context.get_admin_context(), + address_v6) + self.assertEqual(instance_ref['id'], instance_ref2['id']) + self.assertEqual(address_v6, + utils.to_global_ipv6( + network_ref['cidr_v6'], + instance_ref['mac_address'])) + self._deallocate_address(0, address) + db.instance_destroy(context.get_admin_context(), + instance_ref['id']) + + def test_public_network_association(self): + """Makes sure that we can allocate a public ip""" + # TODO(vish): better way of adding floating ips + + self.context._project = self.projects[0] + self.context.project_id = self.projects[0].id + pubnet = IPy.IP(flags.FLAGS.floating_range) + address = str(pubnet[0]) + try: + db.floating_ip_get_by_address(context.get_admin_context(), address) + except exception.NotFound: + db.floating_ip_create(context.get_admin_context(), + {'address': address, + 'host': FLAGS.host}) + + self.assertRaises(NotImplementedError, + self.network.allocate_floating_ip, + self.context, self.projects[0].id) + + fix_addr = self._create_address(0) + float_addr = address + self.assertRaises(NotImplementedError, + self.network.associate_floating_ip, + self.context, float_addr, fix_addr) + + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, None) + + self.assertRaises(NotImplementedError, + self.network.disassociate_floating_ip, + self.context, float_addr) + + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, None) + + self.assertRaises(NotImplementedError, + self.network.deallocate_floating_ip, + self.context, float_addr) + + self.network.deallocate_fixed_ip(self.context, fix_addr) + db.floating_ip_destroy(context.get_admin_context(), float_addr) + + def test_allocate_deallocate_fixed_ip(self): + """Makes sure that we can allocate and deallocate a fixed ip""" + address = self._create_address(0) + self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self._deallocate_address(0, address) + + # check if the fixed ip address is really deallocated + self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + + def test_side_effects(self): + """Ensures allocating and releasing has no side effects""" + address = self._create_address(0) + address2 = self._create_address(1, self.instance2_id) + + self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) + + self._deallocate_address(0, address) + self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + + # First address release shouldn't affect the second + self.assertTrue(is_allocated_in_project(address2, self.projects[0].id)) + + self._deallocate_address(1, address2) + self.assertFalse(is_allocated_in_project(address2, + self.projects[1].id)) + + def test_ips_are_reused(self): + """Makes sure that ip addresses that are deallocated get reused""" + address = self._create_address(0) + self.network.deallocate_fixed_ip(self.context, address) + + address2 = self._create_address(0) + self.assertEqual(address, address2) + + self.network.deallocate_fixed_ip(self.context, address2) + + def test_available_ips(self): + """Make sure the number of available ips for the network is correct + + The number of available IP addresses depends on the test + environment's setup. + + Network size is set in test fixture's setUp method. + + There are ips reserved at the bottom and top of the range. + services (network, gateway, CloudPipe, broadcast) + """ + network = db.project_get_network(context.get_admin_context(), + self.projects[0].id) + net_size = flags.FLAGS.network_size + admin_context = context.get_admin_context() + total_ips = (db.network_count_available_ips(admin_context, + network['id']) + + db.network_count_reserved_ips(admin_context, + network['id']) + + db.network_count_allocated_ips(admin_context, + network['id'])) + self.assertEqual(total_ips, net_size) + + def test_too_many_addresses(self): + """Test for a NoMoreAddresses exception when all fixed ips are used. + """ + admin_context = context.get_admin_context() + network = db.project_get_network(admin_context, self.projects[0].id) + num_available_ips = db.network_count_available_ips(admin_context, + network['id']) + addresses = [] + instance_ids = [] + for i in range(num_available_ips): + instance_ref = self._create_instance(0) + instance_ids.append(instance_ref['id']) + address = self._create_address(0, instance_ref['id']) + addresses.append(address) + + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, 0) + self.assertRaises(db.NoMoreAddresses, + self.network.allocate_fixed_ip, + self.context, + 'foo') + + for i in range(num_available_ips): + self.network.deallocate_fixed_ip(self.context, addresses[i]) + db.instance_destroy(context.get_admin_context(), instance_ids[i]) + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, num_available_ips) + + def run(self, result=None): + if(FLAGS.network_manager == 'nova.network.manager.FlatManager'): + super(FlatNetworkTestCase, self).run(result) + + +def is_allocated_in_project(address, project_id): + """Returns true if address is in specified project""" + #project_net = db.project_get_network(context.get_admin_context(), + # project_id) + project_net = db.network_get_by_bridge(context.get_admin_context(), + FLAGS.flat_network_bridge) + network = db.fixed_ip_get_network(context.get_admin_context(), address) + instance = db.fixed_ip_get_instance(context.get_admin_context(), address) + # instance exists until release + return instance is not None and network['id'] == project_net['id'] + + +def binpath(script): + """Returns the absolute path to a script in bin""" + return os.path.abspath(os.path.join(__file__, "../../../bin", script)) diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py deleted file mode 100644 index ce1c77210..000000000 --- a/nova/tests/test_network.py +++ /dev/null @@ -1,369 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Unit Tests for network code -""" -import IPy -import os - -from nova import context -from nova import db -from nova import exception -from nova import flags -from nova import log as logging -from nova import test -from nova import utils -from nova.auth import manager - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.network') - - -class NetworkTestCase(test.TestCase): - """Test cases for network code""" - def setUp(self): - super(NetworkTestCase, self).setUp() - # NOTE(vish): if you change these flags, make sure to change the - # flags in the corresponding section in nova-dhcpbridge - self.flags(connection_type='fake', - fake_call=True, - fake_network=True) - self.manager = manager.AuthManager() - self.user = self.manager.create_user('netuser', 'netuser', 'netuser') - self.projects = [] - self.network = utils.import_object(FLAGS.network_manager) - self.context = context.RequestContext(project=None, user=self.user) - for i in range(FLAGS.num_networks): - name = 'project%s' % i - project = self.manager.create_project(name, 'netuser', name) - self.projects.append(project) - # create the necessary network data for the project - user_context = context.RequestContext(project=self.projects[i], - user=self.user) - host = self.network.get_network_host(user_context.elevated()) - instance_ref = self._create_instance(0) - self.instance_id = instance_ref['id'] - instance_ref = self._create_instance(1) - self.instance2_id = instance_ref['id'] - - def tearDown(self): - # TODO(termie): this should really be instantiating clean datastores - # in between runs, one failure kills all the tests - db.instance_destroy(context.get_admin_context(), self.instance_id) - db.instance_destroy(context.get_admin_context(), self.instance2_id) - for project in self.projects: - self.manager.delete_project(project) - self.manager.delete_user(self.user) - super(NetworkTestCase, self).tearDown() - - def _create_instance(self, project_num, mac=None): - if not mac: - mac = utils.generate_mac() - project = self.projects[project_num] - self.context._project = project - self.context.project_id = project.id - return db.instance_create(self.context, - {'project_id': project.id, - 'mac_address': mac}) - - def _create_address(self, project_num, instance_id=None): - """Create an address in given project num""" - if instance_id is None: - instance_id = self.instance_id - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - return self.network.allocate_fixed_ip(self.context, instance_id) - - def _deallocate_address(self, project_num, address): - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - self.network.deallocate_fixed_ip(self.context, address) - - def test_private_ipv6(self): - """Make sure ipv6 is OK""" - if FLAGS.use_ipv6: - instance_ref = self._create_instance(0) - address = self._create_address(0, instance_ref['id']) - network_ref = db.project_get_network( - context.get_admin_context(), - self.context.project_id) - address_v6 = db.instance_get_fixed_address_v6( - context.get_admin_context(), - instance_ref['id']) - self.assertEqual(instance_ref['mac_address'], - utils.to_mac(address_v6)) - instance_ref2 = db.fixed_ip_get_instance_v6( - context.get_admin_context(), - address_v6) - self.assertEqual(instance_ref['id'], instance_ref2['id']) - self.assertEqual(address_v6, - utils.to_global_ipv6( - network_ref['cidr_v6'], - instance_ref['mac_address'])) - self._deallocate_address(0, address) - db.instance_destroy(context.get_admin_context(), - instance_ref['id']) - - def test_public_network_association(self): - """Makes sure that we can allocaate a public ip""" - # TODO(vish): better way of adding floating ips - self.context._project = self.projects[0] - self.context.project_id = self.projects[0].id - pubnet = IPy.IP(flags.FLAGS.floating_range) - address = str(pubnet[0]) - try: - db.floating_ip_get_by_address(context.get_admin_context(), address) - except exception.NotFound: - db.floating_ip_create(context.get_admin_context(), - {'address': address, - 'host': FLAGS.host}) - float_addr = self.network.allocate_floating_ip(self.context, - self.projects[0].id) - fix_addr = self._create_address(0) - lease_ip(fix_addr) - self.assertEqual(float_addr, str(pubnet[0])) - self.network.associate_floating_ip(self.context, float_addr, fix_addr) - address = db.instance_get_floating_address(context.get_admin_context(), - self.instance_id) - self.assertEqual(address, float_addr) - self.network.disassociate_floating_ip(self.context, float_addr) - address = db.instance_get_floating_address(context.get_admin_context(), - self.instance_id) - self.assertEqual(address, None) - self.network.deallocate_floating_ip(self.context, float_addr) - self.network.deallocate_fixed_ip(self.context, fix_addr) - release_ip(fix_addr) - db.floating_ip_destroy(context.get_admin_context(), float_addr) - - def test_allocate_deallocate_fixed_ip(self): - """Makes sure that we can allocate and deallocate a fixed ip""" - address = self._create_address(0) - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) - lease_ip(address) - self._deallocate_address(0, address) - - # Doesn't go away until it's dhcp released - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) - - release_ip(address) - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) - - def test_side_effects(self): - """Ensures allocating and releasing has no side effects""" - address = self._create_address(0) - address2 = self._create_address(1, self.instance2_id) - - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) - self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) - self.assertFalse(is_allocated_in_project(address, self.projects[1].id)) - - # Addresses are allocated before they're issued - lease_ip(address) - lease_ip(address2) - - self._deallocate_address(0, address) - release_ip(address) - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) - - # First address release shouldn't affect the second - self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) - - self._deallocate_address(1, address2) - release_ip(address2) - self.assertFalse(is_allocated_in_project(address2, - self.projects[1].id)) - - def test_subnet_edge(self): - """Makes sure that private ips don't overlap""" - first = self._create_address(0) - lease_ip(first) - instance_ids = [] - for i in range(1, FLAGS.num_networks): - instance_ref = self._create_instance(i, mac=utils.generate_mac()) - instance_ids.append(instance_ref['id']) - address = self._create_address(i, instance_ref['id']) - instance_ref = self._create_instance(i, mac=utils.generate_mac()) - instance_ids.append(instance_ref['id']) - address2 = self._create_address(i, instance_ref['id']) - instance_ref = self._create_instance(i, mac=utils.generate_mac()) - instance_ids.append(instance_ref['id']) - address3 = self._create_address(i, instance_ref['id']) - lease_ip(address) - lease_ip(address2) - lease_ip(address3) - self.context._project = self.projects[i] - self.context.project_id = self.projects[i].id - self.assertFalse(is_allocated_in_project(address, - self.projects[0].id)) - self.assertFalse(is_allocated_in_project(address2, - self.projects[0].id)) - self.assertFalse(is_allocated_in_project(address3, - self.projects[0].id)) - self.network.deallocate_fixed_ip(self.context, address) - self.network.deallocate_fixed_ip(self.context, address2) - self.network.deallocate_fixed_ip(self.context, address3) - release_ip(address) - release_ip(address2) - release_ip(address3) - for instance_id in instance_ids: - db.instance_destroy(context.get_admin_context(), instance_id) - self.context._project = self.projects[0] - self.context.project_id = self.projects[0].id - self.network.deallocate_fixed_ip(self.context, first) - self._deallocate_address(0, first) - release_ip(first) - - def test_vpn_ip_and_port_looks_valid(self): - """Ensure the vpn ip and port are reasonable""" - self.assert_(self.projects[0].vpn_ip) - self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start) - self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start + - FLAGS.num_networks) - - def test_too_many_networks(self): - """Ensure error is raised if we run out of networks""" - projects = [] - networks_left = (FLAGS.num_networks - - db.network_count(context.get_admin_context())) - for i in range(networks_left): - project = self.manager.create_project('many%s' % i, self.user) - projects.append(project) - db.project_get_network(context.get_admin_context(), project.id) - project = self.manager.create_project('last', self.user) - projects.append(project) - self.assertRaises(db.NoMoreNetworks, - db.project_get_network, - context.get_admin_context(), - project.id) - for project in projects: - self.manager.delete_project(project) - - def test_ips_are_reused(self): - """Makes sure that ip addresses that are deallocated get reused""" - address = self._create_address(0) - lease_ip(address) - self.network.deallocate_fixed_ip(self.context, address) - release_ip(address) - - address2 = self._create_address(0) - self.assertEqual(address, address2) - lease_ip(address) - self.network.deallocate_fixed_ip(self.context, address2) - release_ip(address) - - def test_available_ips(self): - """Make sure the number of available ips for the network is correct - - The number of available IP addresses depends on the test - environment's setup. - - Network size is set in test fixture's setUp method. - - There are ips reserved at the bottom and top of the range. - services (network, gateway, CloudPipe, broadcast) - """ - network = db.project_get_network(context.get_admin_context(), - self.projects[0].id) - net_size = flags.FLAGS.network_size - admin_context = context.get_admin_context() - total_ips = (db.network_count_available_ips(admin_context, - network['id']) + - db.network_count_reserved_ips(admin_context, - network['id']) + - db.network_count_allocated_ips(admin_context, - network['id'])) - self.assertEqual(total_ips, net_size) - - def test_too_many_addresses(self): - """Test for a NoMoreAddresses exception when all fixed ips are used. - """ - admin_context = context.get_admin_context() - network = db.project_get_network(admin_context, self.projects[0].id) - num_available_ips = db.network_count_available_ips(admin_context, - network['id']) - addresses = [] - instance_ids = [] - for i in range(num_available_ips): - instance_ref = self._create_instance(0) - instance_ids.append(instance_ref['id']) - address = self._create_address(0, instance_ref['id']) - addresses.append(address) - lease_ip(address) - - ip_count = db.network_count_available_ips(context.get_admin_context(), - network['id']) - self.assertEqual(ip_count, 0) - self.assertRaises(db.NoMoreAddresses, - self.network.allocate_fixed_ip, - self.context, - 'foo') - - for i in range(num_available_ips): - self.network.deallocate_fixed_ip(self.context, addresses[i]) - release_ip(addresses[i]) - db.instance_destroy(context.get_admin_context(), instance_ids[i]) - ip_count = db.network_count_available_ips(context.get_admin_context(), - network['id']) - self.assertEqual(ip_count, num_available_ips) - - -def is_allocated_in_project(address, project_id): - """Returns true if address is in specified project""" - project_net = db.project_get_network(context.get_admin_context(), - project_id) - network = db.fixed_ip_get_network(context.get_admin_context(), address) - instance = db.fixed_ip_get_instance(context.get_admin_context(), address) - # instance exists until release - return instance is not None and network['id'] == project_net['id'] - - -def binpath(script): - """Returns the absolute path to a script in bin""" - return os.path.abspath(os.path.join(__file__, "../../../bin", script)) - - -def lease_ip(private_ip): - """Run add command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'), - instance_ref['mac_address'], - private_ip) - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(cmd, addl_env=env) - LOG.debug("ISSUE_IP: %s, %s ", out, err) - - -def release_ip(private_ip): - """Run del command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'), - instance_ref['mac_address'], - private_ip) - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(cmd, addl_env=env) - LOG.debug("RELEASE_IP: %s, %s ", out, err) diff --git a/nova/tests/test_vlan_network.py b/nova/tests/test_vlan_network.py new file mode 100644 index 000000000..be39313bb --- /dev/null +++ b/nova/tests/test_vlan_network.py @@ -0,0 +1,373 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Unit Tests for network code +""" +import IPy +import os + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.auth import manager + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +class VlanNetworkTestCase(test.TestCase): + """Test cases for network code""" + def setUp(self): + super(VlanNetworkTestCase, self).setUp() + # NOTE(vish): if you change these flags, make sure to change the + # flags in the corresponding section in nova-dhcpbridge + self.flags(connection_type='fake', + fake_call=True, + fake_network=True) + self.manager = manager.AuthManager() + self.user = self.manager.create_user('netuser', 'netuser', 'netuser') + self.projects = [] + self.network = utils.import_object(FLAGS.network_manager) + self.context = context.RequestContext(project=None, user=self.user) + for i in range(FLAGS.num_networks): + name = 'project%s' % i + project = self.manager.create_project(name, 'netuser', name) + self.projects.append(project) + # create the necessary network data for the project + user_context = context.RequestContext(project=self.projects[i], + user=self.user) + host = self.network.get_network_host(user_context.elevated()) + instance_ref = self._create_instance(0) + self.instance_id = instance_ref['id'] + instance_ref = self._create_instance(1) + self.instance2_id = instance_ref['id'] + + def tearDown(self): + # TODO(termie): this should really be instantiating clean datastores + # in between runs, one failure kills all the tests + db.instance_destroy(context.get_admin_context(), self.instance_id) + db.instance_destroy(context.get_admin_context(), self.instance2_id) + for project in self.projects: + self.manager.delete_project(project) + self.manager.delete_user(self.user) + super(VlanNetworkTestCase, self).tearDown() + + def run(self, result=None): + if(FLAGS.network_manager == 'nova.network.manager.VlanManager'): + super(VlanNetworkTestCase, self).run(result) + + def _create_instance(self, project_num, mac=None): + if not mac: + mac = utils.generate_mac() + project = self.projects[project_num] + self.context._project = project + self.context.project_id = project.id + return db.instance_create(self.context, + {'project_id': project.id, + 'mac_address': mac}) + + def _create_address(self, project_num, instance_id=None): + """Create an address in given project num""" + if instance_id is None: + instance_id = self.instance_id + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + return self.network.allocate_fixed_ip(self.context, instance_id) + + def _deallocate_address(self, project_num, address): + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + self.network.deallocate_fixed_ip(self.context, address) + + def test_private_ipv6(self): + """Make sure ipv6 is OK""" + if FLAGS.use_ipv6: + instance_ref = self._create_instance(0) + address = self._create_address(0, instance_ref['id']) + network_ref = db.project_get_network( + context.get_admin_context(), + self.context.project_id) + address_v6 = db.instance_get_fixed_address_v6( + context.get_admin_context(), + instance_ref['id']) + self.assertEqual(instance_ref['mac_address'], + utils.to_mac(address_v6)) + instance_ref2 = db.fixed_ip_get_instance_v6( + context.get_admin_context(), + address_v6) + self.assertEqual(instance_ref['id'], instance_ref2['id']) + self.assertEqual(address_v6, + utils.to_global_ipv6( + network_ref['cidr_v6'], + instance_ref['mac_address'])) + self._deallocate_address(0, address) + db.instance_destroy(context.get_admin_context(), + instance_ref['id']) + + def test_public_network_association(self): + """Makes sure that we can allocaate a public ip""" + # TODO(vish): better way of adding floating ips + self.context._project = self.projects[0] + self.context.project_id = self.projects[0].id + pubnet = IPy.IP(flags.FLAGS.floating_range) + address = str(pubnet[0]) + try: + db.floating_ip_get_by_address(context.get_admin_context(), address) + except exception.NotFound: + db.floating_ip_create(context.get_admin_context(), + {'address': address, + 'host': FLAGS.host}) + float_addr = self.network.allocate_floating_ip(self.context, + self.projects[0].id) + fix_addr = self._create_address(0) + lease_ip(fix_addr) + self.assertEqual(float_addr, str(pubnet[0])) + self.network.associate_floating_ip(self.context, float_addr, fix_addr) + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, float_addr) + self.network.disassociate_floating_ip(self.context, float_addr) + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, None) + self.network.deallocate_floating_ip(self.context, float_addr) + self.network.deallocate_fixed_ip(self.context, fix_addr) + release_ip(fix_addr) + db.floating_ip_destroy(context.get_admin_context(), float_addr) + + def test_allocate_deallocate_fixed_ip(self): + """Makes sure that we can allocate and deallocate a fixed ip""" + address = self._create_address(0) + self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + lease_ip(address) + self._deallocate_address(0, address) + + # Doesn't go away until it's dhcp released + self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + + release_ip(address) + self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + + def test_side_effects(self): + """Ensures allocating and releasing has no side effects""" + address = self._create_address(0) + address2 = self._create_address(1, self.instance2_id) + + self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) + self.assertFalse(is_allocated_in_project(address, self.projects[1].id)) + + # Addresses are allocated before they're issued + lease_ip(address) + lease_ip(address2) + + self._deallocate_address(0, address) + release_ip(address) + self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + + # First address release shouldn't affect the second + self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) + + self._deallocate_address(1, address2) + release_ip(address2) + self.assertFalse(is_allocated_in_project(address2, + self.projects[1].id)) + + def test_subnet_edge(self): + """Makes sure that private ips don't overlap""" + first = self._create_address(0) + lease_ip(first) + instance_ids = [] + for i in range(1, FLAGS.num_networks): + instance_ref = self._create_instance(i, mac=utils.generate_mac()) + instance_ids.append(instance_ref['id']) + address = self._create_address(i, instance_ref['id']) + instance_ref = self._create_instance(i, mac=utils.generate_mac()) + instance_ids.append(instance_ref['id']) + address2 = self._create_address(i, instance_ref['id']) + instance_ref = self._create_instance(i, mac=utils.generate_mac()) + instance_ids.append(instance_ref['id']) + address3 = self._create_address(i, instance_ref['id']) + lease_ip(address) + lease_ip(address2) + lease_ip(address3) + self.context._project = self.projects[i] + self.context.project_id = self.projects[i].id + self.assertFalse(is_allocated_in_project(address, + self.projects[0].id)) + self.assertFalse(is_allocated_in_project(address2, + self.projects[0].id)) + self.assertFalse(is_allocated_in_project(address3, + self.projects[0].id)) + self.network.deallocate_fixed_ip(self.context, address) + self.network.deallocate_fixed_ip(self.context, address2) + self.network.deallocate_fixed_ip(self.context, address3) + release_ip(address) + release_ip(address2) + release_ip(address3) + for instance_id in instance_ids: + db.instance_destroy(context.get_admin_context(), instance_id) + self.context._project = self.projects[0] + self.context.project_id = self.projects[0].id + self.network.deallocate_fixed_ip(self.context, first) + self._deallocate_address(0, first) + release_ip(first) + + def test_vpn_ip_and_port_looks_valid(self): + """Ensure the vpn ip and port are reasonable""" + self.assert_(self.projects[0].vpn_ip) + self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start) + self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start + + FLAGS.num_networks) + + def test_too_many_networks(self): + """Ensure error is raised if we run out of networks""" + projects = [] + networks_left = (FLAGS.num_networks - + db.network_count(context.get_admin_context())) + for i in range(networks_left): + project = self.manager.create_project('many%s' % i, self.user) + projects.append(project) + db.project_get_network(context.get_admin_context(), project.id) + project = self.manager.create_project('last', self.user) + projects.append(project) + self.assertRaises(db.NoMoreNetworks, + db.project_get_network, + context.get_admin_context(), + project.id) + for project in projects: + self.manager.delete_project(project) + + def test_ips_are_reused(self): + """Makes sure that ip addresses that are deallocated get reused""" + address = self._create_address(0) + lease_ip(address) + self.network.deallocate_fixed_ip(self.context, address) + release_ip(address) + + address2 = self._create_address(0) + self.assertEqual(address, address2) + lease_ip(address) + self.network.deallocate_fixed_ip(self.context, address2) + release_ip(address) + + def test_available_ips(self): + """Make sure the number of available ips for the network is correct + + The number of available IP addresses depends on the test + environment's setup. + + Network size is set in test fixture's setUp method. + + There are ips reserved at the bottom and top of the range. + services (network, gateway, CloudPipe, broadcast) + """ + network = db.project_get_network(context.get_admin_context(), + self.projects[0].id) + net_size = flags.FLAGS.network_size + admin_context = context.get_admin_context() + total_ips = (db.network_count_available_ips(admin_context, + network['id']) + + db.network_count_reserved_ips(admin_context, + network['id']) + + db.network_count_allocated_ips(admin_context, + network['id'])) + self.assertEqual(total_ips, net_size) + + def test_too_many_addresses(self): + """Test for a NoMoreAddresses exception when all fixed ips are used. + """ + admin_context = context.get_admin_context() + network = db.project_get_network(admin_context, self.projects[0].id) + num_available_ips = db.network_count_available_ips(admin_context, + network['id']) + addresses = [] + instance_ids = [] + for i in range(num_available_ips): + instance_ref = self._create_instance(0) + instance_ids.append(instance_ref['id']) + address = self._create_address(0, instance_ref['id']) + addresses.append(address) + lease_ip(address) + + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, 0) + self.assertRaises(db.NoMoreAddresses, + self.network.allocate_fixed_ip, + self.context, + 'foo') + + for i in range(num_available_ips): + self.network.deallocate_fixed_ip(self.context, addresses[i]) + release_ip(addresses[i]) + db.instance_destroy(context.get_admin_context(), instance_ids[i]) + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, num_available_ips) + + +def is_allocated_in_project(address, project_id): + """Returns true if address is in specified project""" + project_net = db.project_get_network(context.get_admin_context(), + project_id) + network = db.fixed_ip_get_network(context.get_admin_context(), address) + instance = db.fixed_ip_get_instance(context.get_admin_context(), address) + # instance exists until release + return instance is not None and network['id'] == project_net['id'] + + +def binpath(script): + """Returns the absolute path to a script in bin""" + return os.path.abspath(os.path.join(__file__, "../../../bin", script)) + + +def lease_ip(private_ip): + """Run add command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'), + instance_ref['mac_address'], + private_ip) + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(cmd, addl_env=env) + LOG.debug("ISSUE_IP: %s, %s ", out, err) + + +def release_ip(private_ip): + """Run del command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'), + instance_ref['mac_address'], + private_ip) + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(cmd, addl_env=env) + LOG.debug("RELEASE_IP: %s, %s ", out, err) -- cgit From a74bf3381ada34f35c43d6f307fbae9abecfb255 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Tue, 8 Mar 2011 10:30:48 -0800 Subject: abstracted network code in the base class for flat and vlan --- nova/network/manager.py | 8 +- nova/tests/network/__init__.py | 47 +++++++++ nova/tests/network/base.py | 154 ++++++++++++++++++++++++++++++ nova/tests/test_flat_network.py | 147 ++++------------------------ nova/tests/test_vlan_network.py | 205 ++++++++-------------------------------- 5 files changed, 259 insertions(+), 302 deletions(-) create mode 100644 nova/tests/network/__init__.py create mode 100644 nova/tests/network/base.py diff --git a/nova/network/manager.py b/nova/network/manager.py index 686ab9732..670ff55fd 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -404,9 +404,11 @@ class FlatManager(NetworkManager): net = {} net['injected'] = FLAGS.flat_injected net['dns'] = FLAGS.flat_network_dns - if(FLAGS.use_ipv6): - net['gateway_v6'] = \ - utils.get_my_linklocal(FLAGS.flat_network_bridge) + if not FLAGS.fake_network: + if(FLAGS.use_ipv6): + net['gateway_v6'] = \ + utils.get_my_linklocal( + FLAGS.flat_network_bridge) self.db.network_update(context, network_id, net) def allocate_floating_ip(self, context, project_id): diff --git a/nova/tests/network/__init__.py b/nova/tests/network/__init__.py new file mode 100644 index 000000000..e51065983 --- /dev/null +++ b/nova/tests/network/__init__.py @@ -0,0 +1,47 @@ +import os + +from nova import context +from nova import db +from nova import flags +from nova import log as logging +from nova import utils + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +def binpath(script): + """Returns the absolute path to a script in bin""" + return os.path.abspath(os.path.join(__file__, "../../../../bin", script)) + + +def lease_ip(private_ip): + """Run add command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'), + instance_ref['mac_address'], + private_ip) + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(cmd, addl_env=env) + LOG.debug("ISSUE_IP: %s, %s ", out, err) + + +def release_ip(private_ip): + """Run del command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'), + instance_ref['mac_address'], + private_ip) + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(cmd, addl_env=env) + LOG.debug("RELEASE_IP: %s, %s ", out, err) diff --git a/nova/tests/network/base.py b/nova/tests/network/base.py new file mode 100644 index 000000000..2dd8178ff --- /dev/null +++ b/nova/tests/network/base.py @@ -0,0 +1,154 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Base class of Unit Tests for all network models +""" +import IPy +import os + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.auth import manager + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +class NetworkTestCase(test.TestCase): + """Test cases for network code""" + def setUp(self): + super(NetworkTestCase, self).setUp() + # NOTE(vish): if you change these flags, make sure to change the + # flags in the corresponding section in nova-dhcpbridge + self.flags(connection_type='fake', + fake_call=True, + fake_network=True) + self.manager = manager.AuthManager() + self.user = self.manager.create_user('netuser', 'netuser', 'netuser') + self.projects = [] + self.network = utils.import_object(FLAGS.network_manager) + self.context = context.RequestContext(project=None, user=self.user) + for i in range(FLAGS.num_networks): + name = 'project%s' % i + project = self.manager.create_project(name, 'netuser', name) + self.projects.append(project) + # create the necessary network data for the project + user_context = context.RequestContext(project=self.projects[i], + user=self.user) + host = self.network.get_network_host(user_context.elevated()) + instance_ref = self._create_instance(0) + self.instance_id = instance_ref['id'] + instance_ref = self._create_instance(1) + self.instance2_id = instance_ref['id'] + + def tearDown(self): + # TODO(termie): this should really be instantiating clean datastores + # in between runs, one failure kills all the tests + db.instance_destroy(context.get_admin_context(), self.instance_id) + db.instance_destroy(context.get_admin_context(), self.instance2_id) + for project in self.projects: + self.manager.delete_project(project) + self.manager.delete_user(self.user) + super(NetworkTestCase, self).tearDown() + + def _create_instance(self, project_num, mac=None): + if not mac: + mac = utils.generate_mac() + project = self.projects[project_num] + self.context._project = project + self.context.project_id = project.id + return db.instance_create(self.context, + {'project_id': project.id, + 'mac_address': mac}) + + def _create_address(self, project_num, instance_id=None): + """Create an address in given project num""" + if instance_id is None: + instance_id = self.instance_id + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + return self.network.allocate_fixed_ip(self.context, instance_id) + + def _deallocate_address(self, project_num, address): + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + self.network.deallocate_fixed_ip(self.context, address) + + def _is_allocated_in_project(self, address, project_id): + """Returns true if address is in specified project""" + project_net = db.network_get_by_bridge(context.get_admin_context(), + FLAGS.flat_network_bridge) + network = db.fixed_ip_get_network(context.get_admin_context(), + address) + instance = db.fixed_ip_get_instance(context.get_admin_context(), + address) + # instance exists until release + return instance is not None and network['id'] == project_net['id'] + + def test_private_ipv6(self): + """Make sure ipv6 is OK""" + if FLAGS.use_ipv6: + instance_ref = self._create_instance(0) + address = self._create_address(0, instance_ref['id']) + network_ref = db.project_get_network( + context.get_admin_context(), + self.context.project_id) + address_v6 = db.instance_get_fixed_address_v6( + context.get_admin_context(), + instance_ref['id']) + self.assertEqual(instance_ref['mac_address'], + utils.to_mac(address_v6)) + instance_ref2 = db.fixed_ip_get_instance_v6( + context.get_admin_context(), + address_v6) + self.assertEqual(instance_ref['id'], instance_ref2['id']) + self.assertEqual(address_v6, + utils.to_global_ipv6( + network_ref['cidr_v6'], + instance_ref['mac_address'])) + self._deallocate_address(0, address) + db.instance_destroy(context.get_admin_context(), + instance_ref['id']) + + def test_available_ips(self): + """Make sure the number of available ips for the network is correct + + The number of available IP addresses depends on the test + environment's setup. + + Network size is set in test fixture's setUp method. + + There are ips reserved at the bottom and top of the range. + services (network, gateway, CloudPipe, broadcast) + """ + network = db.project_get_network(context.get_admin_context(), + self.projects[0].id) + net_size = flags.FLAGS.network_size + admin_context = context.get_admin_context() + total_ips = (db.network_count_available_ips(admin_context, + network['id']) + + db.network_count_reserved_ips(admin_context, + network['id']) + + db.network_count_allocated_ips(admin_context, + network['id'])) + self.assertEqual(total_ips, net_size) diff --git a/nova/tests/test_flat_network.py b/nova/tests/test_flat_network.py index 91a49920d..a9a934158 100644 --- a/nova/tests/test_flat_network.py +++ b/nova/tests/test_flat_network.py @@ -30,96 +30,15 @@ from nova import log as logging from nova import test from nova import utils from nova.auth import manager +from nova.tests.network import base + FLAGS = flags.FLAGS LOG = logging.getLogger('nova.tests.network') -class FlatNetworkTestCase(test.TestCase): +class FlatNetworkTestCase(base.NetworkTestCase): """Test cases for network code""" - def setUp(self): - super(FlatNetworkTestCase, self).setUp() - # NOTE(vish): if you change these flags, make sure to change the - # flags in the corresponding section in nova-dhcpbridge - self.flags(connection_type='fake', - fake_call=True, - fake_network=True) - self.manager = manager.AuthManager() - self.user = self.manager.create_user('netuser', 'netuser', 'netuser') - self.projects = [] - self.network = utils.import_object(FLAGS.network_manager) - self.context = context.RequestContext(project=None, user=self.user) - for i in range(5): - name = 'project%s' % i - project = self.manager.create_project(name, 'netuser', name) - self.projects.append(project) - # create the necessary network data for the project - user_context = context.RequestContext(project=self.projects[i], - user=self.user) - host = self.network.get_network_host(user_context.elevated()) - instance_ref = self._create_instance(0) - self.instance_id = instance_ref['id'] - instance_ref = self._create_instance(1) - self.instance2_id = instance_ref['id'] - - def tearDown(self): - # TODO(termie): this should really be instantiating clean datastores - # in between runs, one failure kills all the tests - db.instance_destroy(context.get_admin_context(), self.instance_id) - db.instance_destroy(context.get_admin_context(), self.instance2_id) - for project in self.projects: - self.manager.delete_project(project) - self.manager.delete_user(self.user) - super(FlatNetworkTestCase, self).tearDown() - - def _create_instance(self, project_num, mac=None): - if not mac: - mac = utils.generate_mac() - project = self.projects[project_num] - self.context._project = project - self.context.project_id = project.id - return db.instance_create(self.context, - {'project_id': project.id, - 'mac_address': mac}) - - def _create_address(self, project_num, instance_id=None): - """Create an address in given project num""" - if instance_id is None: - instance_id = self.instance_id - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - return self.network.allocate_fixed_ip(self.context, instance_id) - - def _deallocate_address(self, project_num, address): - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - self.network.deallocate_fixed_ip(self.context, address) - - def test_private_ipv6(self): - """Make sure ipv6 is OK""" - if FLAGS.use_ipv6: - instance_ref = self._create_instance(0) - address = self._create_address(0, instance_ref['id']) - network_ref = db.project_get_network( - context.get_admin_context(), - self.context.project_id) - address_v6 = db.instance_get_fixed_address_v6( - context.get_admin_context(), - instance_ref['id']) - self.assertEqual(instance_ref['mac_address'], - utils.to_mac(address_v6)) - instance_ref2 = db.fixed_ip_get_instance_v6( - context.get_admin_context(), - address_v6) - self.assertEqual(instance_ref['id'], instance_ref2['id']) - self.assertEqual(address_v6, - utils.to_global_ipv6( - network_ref['cidr_v6'], - instance_ref['mac_address'])) - self._deallocate_address(0, address) - db.instance_destroy(context.get_admin_context(), - instance_ref['id']) - def test_public_network_association(self): """Makes sure that we can allocate a public ip""" # TODO(vish): better way of adding floating ips @@ -167,28 +86,34 @@ class FlatNetworkTestCase(test.TestCase): def test_allocate_deallocate_fixed_ip(self): """Makes sure that we can allocate and deallocate a fixed ip""" address = self._create_address(0) - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) self._deallocate_address(0, address) # check if the fixed ip address is really deallocated - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) def test_side_effects(self): """Ensures allocating and releasing has no side effects""" address = self._create_address(0) address2 = self._create_address(1, self.instance2_id) - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) - self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[1].id)) self._deallocate_address(0, address) - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) # First address release shouldn't affect the second - self.assertTrue(is_allocated_in_project(address2, self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[0].id)) self._deallocate_address(1, address2) - self.assertFalse(is_allocated_in_project(address2, + self.assertFalse(self._is_allocated_in_project(address2, self.projects[1].id)) def test_ips_are_reused(self): @@ -201,29 +126,6 @@ class FlatNetworkTestCase(test.TestCase): self.network.deallocate_fixed_ip(self.context, address2) - def test_available_ips(self): - """Make sure the number of available ips for the network is correct - - The number of available IP addresses depends on the test - environment's setup. - - Network size is set in test fixture's setUp method. - - There are ips reserved at the bottom and top of the range. - services (network, gateway, CloudPipe, broadcast) - """ - network = db.project_get_network(context.get_admin_context(), - self.projects[0].id) - net_size = flags.FLAGS.network_size - admin_context = context.get_admin_context() - total_ips = (db.network_count_available_ips(admin_context, - network['id']) + - db.network_count_reserved_ips(admin_context, - network['id']) + - db.network_count_allocated_ips(admin_context, - network['id'])) - self.assertEqual(total_ips, net_size) - def test_too_many_addresses(self): """Test for a NoMoreAddresses exception when all fixed ips are used. """ @@ -257,20 +159,3 @@ class FlatNetworkTestCase(test.TestCase): def run(self, result=None): if(FLAGS.network_manager == 'nova.network.manager.FlatManager'): super(FlatNetworkTestCase, self).run(result) - - -def is_allocated_in_project(address, project_id): - """Returns true if address is in specified project""" - #project_net = db.project_get_network(context.get_admin_context(), - # project_id) - project_net = db.network_get_by_bridge(context.get_admin_context(), - FLAGS.flat_network_bridge) - network = db.fixed_ip_get_network(context.get_admin_context(), address) - instance = db.fixed_ip_get_instance(context.get_admin_context(), address) - # instance exists until release - return instance is not None and network['id'] == project_net['id'] - - -def binpath(script): - """Returns the absolute path to a script in bin""" - return os.path.abspath(os.path.join(__file__, "../../../bin", script)) diff --git a/nova/tests/test_vlan_network.py b/nova/tests/test_vlan_network.py index be39313bb..f3478320b 100644 --- a/nova/tests/test_vlan_network.py +++ b/nova/tests/test_vlan_network.py @@ -29,100 +29,16 @@ from nova import log as logging from nova import test from nova import utils from nova.auth import manager +from nova.tests.network import base +from nova.tests.network import binpath,\ + lease_ip, release_ip FLAGS = flags.FLAGS LOG = logging.getLogger('nova.tests.network') -class VlanNetworkTestCase(test.TestCase): +class VlanNetworkTestCase(base.NetworkTestCase): """Test cases for network code""" - def setUp(self): - super(VlanNetworkTestCase, self).setUp() - # NOTE(vish): if you change these flags, make sure to change the - # flags in the corresponding section in nova-dhcpbridge - self.flags(connection_type='fake', - fake_call=True, - fake_network=True) - self.manager = manager.AuthManager() - self.user = self.manager.create_user('netuser', 'netuser', 'netuser') - self.projects = [] - self.network = utils.import_object(FLAGS.network_manager) - self.context = context.RequestContext(project=None, user=self.user) - for i in range(FLAGS.num_networks): - name = 'project%s' % i - project = self.manager.create_project(name, 'netuser', name) - self.projects.append(project) - # create the necessary network data for the project - user_context = context.RequestContext(project=self.projects[i], - user=self.user) - host = self.network.get_network_host(user_context.elevated()) - instance_ref = self._create_instance(0) - self.instance_id = instance_ref['id'] - instance_ref = self._create_instance(1) - self.instance2_id = instance_ref['id'] - - def tearDown(self): - # TODO(termie): this should really be instantiating clean datastores - # in between runs, one failure kills all the tests - db.instance_destroy(context.get_admin_context(), self.instance_id) - db.instance_destroy(context.get_admin_context(), self.instance2_id) - for project in self.projects: - self.manager.delete_project(project) - self.manager.delete_user(self.user) - super(VlanNetworkTestCase, self).tearDown() - - def run(self, result=None): - if(FLAGS.network_manager == 'nova.network.manager.VlanManager'): - super(VlanNetworkTestCase, self).run(result) - - def _create_instance(self, project_num, mac=None): - if not mac: - mac = utils.generate_mac() - project = self.projects[project_num] - self.context._project = project - self.context.project_id = project.id - return db.instance_create(self.context, - {'project_id': project.id, - 'mac_address': mac}) - - def _create_address(self, project_num, instance_id=None): - """Create an address in given project num""" - if instance_id is None: - instance_id = self.instance_id - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - return self.network.allocate_fixed_ip(self.context, instance_id) - - def _deallocate_address(self, project_num, address): - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - self.network.deallocate_fixed_ip(self.context, address) - - def test_private_ipv6(self): - """Make sure ipv6 is OK""" - if FLAGS.use_ipv6: - instance_ref = self._create_instance(0) - address = self._create_address(0, instance_ref['id']) - network_ref = db.project_get_network( - context.get_admin_context(), - self.context.project_id) - address_v6 = db.instance_get_fixed_address_v6( - context.get_admin_context(), - instance_ref['id']) - self.assertEqual(instance_ref['mac_address'], - utils.to_mac(address_v6)) - instance_ref2 = db.fixed_ip_get_instance_v6( - context.get_admin_context(), - address_v6) - self.assertEqual(instance_ref['id'], instance_ref2['id']) - self.assertEqual(address_v6, - utils.to_global_ipv6( - network_ref['cidr_v6'], - instance_ref['mac_address'])) - self._deallocate_address(0, address) - db.instance_destroy(context.get_admin_context(), - instance_ref['id']) - def test_public_network_association(self): """Makes sure that we can allocaate a public ip""" # TODO(vish): better way of adding floating ips @@ -157,24 +73,30 @@ class VlanNetworkTestCase(test.TestCase): def test_allocate_deallocate_fixed_ip(self): """Makes sure that we can allocate and deallocate a fixed ip""" address = self._create_address(0) - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) lease_ip(address) self._deallocate_address(0, address) # Doesn't go away until it's dhcp released - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) release_ip(address) - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) def test_side_effects(self): """Ensures allocating and releasing has no side effects""" address = self._create_address(0) address2 = self._create_address(1, self.instance2_id) - self.assertTrue(is_allocated_in_project(address, self.projects[0].id)) - self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) - self.assertFalse(is_allocated_in_project(address, self.projects[1].id)) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[1].id)) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[1].id)) # Addresses are allocated before they're issued lease_ip(address) @@ -182,14 +104,16 @@ class VlanNetworkTestCase(test.TestCase): self._deallocate_address(0, address) release_ip(address) - self.assertFalse(is_allocated_in_project(address, self.projects[0].id)) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) # First address release shouldn't affect the second - self.assertTrue(is_allocated_in_project(address2, self.projects[1].id)) + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[1].id)) self._deallocate_address(1, address2) release_ip(address2) - self.assertFalse(is_allocated_in_project(address2, + self.assertFalse(self._is_allocated_in_project(address2, self.projects[1].id)) def test_subnet_edge(self): @@ -212,11 +136,11 @@ class VlanNetworkTestCase(test.TestCase): lease_ip(address3) self.context._project = self.projects[i] self.context.project_id = self.projects[i].id - self.assertFalse(is_allocated_in_project(address, + self.assertFalse(self._is_allocated_in_project(address, self.projects[0].id)) - self.assertFalse(is_allocated_in_project(address2, + self.assertFalse(self._is_allocated_in_project(address2, self.projects[0].id)) - self.assertFalse(is_allocated_in_project(address3, + self.assertFalse(self._is_allocated_in_project(address3, self.projects[0].id)) self.network.deallocate_fixed_ip(self.context, address) self.network.deallocate_fixed_ip(self.context, address2) @@ -270,29 +194,6 @@ class VlanNetworkTestCase(test.TestCase): self.network.deallocate_fixed_ip(self.context, address2) release_ip(address) - def test_available_ips(self): - """Make sure the number of available ips for the network is correct - - The number of available IP addresses depends on the test - environment's setup. - - Network size is set in test fixture's setUp method. - - There are ips reserved at the bottom and top of the range. - services (network, gateway, CloudPipe, broadcast) - """ - network = db.project_get_network(context.get_admin_context(), - self.projects[0].id) - net_size = flags.FLAGS.network_size - admin_context = context.get_admin_context() - total_ips = (db.network_count_available_ips(admin_context, - network['id']) + - db.network_count_reserved_ips(admin_context, - network['id']) + - db.network_count_allocated_ips(admin_context, - network['id'])) - self.assertEqual(total_ips, net_size) - def test_too_many_addresses(self): """Test for a NoMoreAddresses exception when all fixed ips are used. """ @@ -325,49 +226,17 @@ class VlanNetworkTestCase(test.TestCase): network['id']) self.assertEqual(ip_count, num_available_ips) + def _is_allocated_in_project(self, address, project_id): + """Returns true if address is in specified project""" + project_net = db.project_get_network(context.get_admin_context(), + project_id) + network = db.fixed_ip_get_network(context.get_admin_context(), + address) + instance = db.fixed_ip_get_instance(context.get_admin_context(), + address) + # instance exists until release + return instance is not None and network['id'] == project_net['id'] -def is_allocated_in_project(address, project_id): - """Returns true if address is in specified project""" - project_net = db.project_get_network(context.get_admin_context(), - project_id) - network = db.fixed_ip_get_network(context.get_admin_context(), address) - instance = db.fixed_ip_get_instance(context.get_admin_context(), address) - # instance exists until release - return instance is not None and network['id'] == project_net['id'] - - -def binpath(script): - """Returns the absolute path to a script in bin""" - return os.path.abspath(os.path.join(__file__, "../../../bin", script)) - - -def lease_ip(private_ip): - """Run add command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = "%s add %s %s fake" % (binpath('nova-dhcpbridge'), - instance_ref['mac_address'], - private_ip) - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(cmd, addl_env=env) - LOG.debug("ISSUE_IP: %s, %s ", out, err) - - -def release_ip(private_ip): - """Run del command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = "%s del %s %s fake" % (binpath('nova-dhcpbridge'), - instance_ref['mac_address'], - private_ip) - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(cmd, addl_env=env) - LOG.debug("RELEASE_IP: %s, %s ", out, err) + def run(self, result=None): + if(FLAGS.network_manager == 'nova.network.manager.VlanManager'): + super(VlanNetworkTestCase, self).run(result) -- cgit From 25bbe2afb0be3c79264376dd6a11e2bc97847702 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Thu, 10 Mar 2011 11:17:34 -0800 Subject: fixed formatting and redundant imports --- nova/api/ec2/cloud.py | 6 +++--- .../db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6ed6186be..c6309f03c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -701,9 +701,9 @@ class CloudController(object): fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] if instance['fixed_ip']['network'] and 'use_v6' in kwargs: - i['dnsNameV6'] = utils.to_global_ipv6( - instance['fixed_ip']['network']['cidr_v6'], - instance['mac_address']) + i['dnsNameV6'] = utils.to_global_ipv6( + instance['fixed_ip']['network']['cidr_v6'], + instance['mac_address']) i['privateDnsName'] = fixed_addr i['publicDnsName'] = floating_addr diff --git a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py index d14f52af1..b8514c439 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/007_add_ipv6_flatmanager.py @@ -12,7 +12,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -from lib2to3.fixer_util import String from sqlalchemy import * from migrate import * -- cgit From 998975651ac2f2df7a3f8af16d62d197f451180f Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 10 Mar 2011 13:53:27 -0800 Subject: Test login. Uncovered bug732866 --- nova/tests/integrated/integrated_helpers.py | 182 ++++++++++++++++++++++++++++ nova/tests/integrated/test_login.py | 77 ++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 nova/tests/integrated/integrated_helpers.py create mode 100644 nova/tests/integrated/test_login.py diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py new file mode 100644 index 000000000..691ead6e1 --- /dev/null +++ b/nova/tests/integrated/integrated_helpers.py @@ -0,0 +1,182 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Provides common functionality for integrated unit tests +""" + +import random +import string + +from nova import exception +from nova import flags +from nova import service +from nova import test # For the flags +from nova.auth import manager +from nova.exception import Error +from nova.log import logging +from nova.tests.integrated.api import client + + +FLAGS = flags.FLAGS + +LOG = logging.getLogger('nova.tests.integrated') + + +def generate_random_alphanumeric(length): + """Creates a random alphanumeric string of specified length""" + return ''.join(random.choice(string.ascii_uppercase + string.digits) + for _x in range(length)) + + +def generate_random_numeric(length): + """Creates a random numeric string of specified length""" + return ''.join(random.choice(string.digits) + for _x in range(length)) + + +def generate_new_element(items, prefix, numeric=False): + """Creates a random string with prefix, that is not in 'items' list""" + while True: + if numeric: + candidate = prefix + generate_random_numeric(8) + else: + candidate = prefix + generate_random_alphanumeric(8) + if not candidate in items: + return candidate + print "Random collision on %s" % candidate + + +class TestUser(object): + def __init__(self, name, secret, auth_url): + self.name = name + self.secret = secret + self.auth_url = auth_url + + if not auth_url: + raise exception.Error("auth_url is required") + self.openstack_api = client.TestOpenStackClient(self.name, + self.secret, + self.auth_url) + + +class IntegratedUnitTestContext(object): + __INSTANCE = None + + def __init__(self): + self.auth_manager = manager.AuthManager() + + self.wsgi_server = None + self.wsgi_apps = [] + self.api_service = None + + self.services = [] + self.auth_url = None + self.project_name = None + + self.setup() + + def setup(self): + self._start_services() + + self._create_test_user() + + def _create_test_user(self): + self.test_user = self._create_unittest_user() + + # No way to currently pass this through the OpenStack API + self.project_name = 'openstack' + self._configure_project(self.project_name, self.test_user) + + def _start_services(self): + # WSGI shutdown broken :-( + if not self.api_service: + self._start_api_service() + + def cleanup(self): + for service in self.services: + service.kill() + self.services = [] + # TODO(justinsb): Shutdown WSGI & anything else we startup + # WSGI shutdown broken :-( + # self.wsgi_server.terminate() + # self.wsgi_server = None + self.test_user = None + + def _create_unittest_user(self): + users = self.auth_manager.get_users() + user_names = [user.name for user in users] + auth_name = generate_new_element(user_names, 'unittest_user_') + auth_key = generate_random_alphanumeric(16) + + # Right now there's a bug where auth_name and auth_key are reversed + auth_key = auth_name + + self.auth_manager.create_user(auth_name, auth_name, auth_key, False) + return TestUser(auth_name, auth_key, self.auth_url) + + def _configure_project(self, project_name, user): + projects = self.auth_manager.get_projects() + project_names = [project.name for project in projects] + if not project_name in project_names: + project = self.auth_manager.create_project(project_name, + user.name, + description=None, + member_users=None) + else: + self.auth_manager.add_to_project(user.name, project_name) + + def _start_api_service(self): + api_service = service.ApiService.create() + api_service.start() + + if not api_service: + raise Exception("API Service was None") + + # WSGI shutdown broken :-( + #self.services.append(volume_service) + self.api_service = api_service + + self.auth_url = 'http://localhost:8774/v1.0' + + return api_service + + # WSGI shutdown broken :-( + #@staticmethod + #def get(): + # if not IntegratedUnitTestContext.__INSTANCE: + # IntegratedUnitTestContext.startup() + # #raise Error("Must call IntegratedUnitTestContext::startup") + # return IntegratedUnitTestContext.__INSTANCE + + @staticmethod + def startup(): + # Because WSGI shutdown is broken at the moment, we have to recycle + if IntegratedUnitTestContext.__INSTANCE: + #raise Error("Multiple calls to IntegratedUnitTestContext.startup") + IntegratedUnitTestContext.__INSTANCE.setup() + else: + IntegratedUnitTestContext.__INSTANCE = IntegratedUnitTestContext() + return IntegratedUnitTestContext.__INSTANCE + + @staticmethod + def shutdown(): + if not IntegratedUnitTestContext.__INSTANCE: + raise Error("Must call IntegratedUnitTestContext::startup") + IntegratedUnitTestContext.__INSTANCE.cleanup() + # WSGI shutdown broken :-( + #IntegratedUnitTestContext.__INSTANCE = None diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py new file mode 100644 index 000000000..990dcaaf4 --- /dev/null +++ b/nova/tests/integrated/test_login.py @@ -0,0 +1,77 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Justin Santa Barbara +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import unittest + +from nova import flags +from nova.log import logging +from nova.tests.integrated import integrated_helpers +from nova.tests.integrated.api import client + +LOG = logging.getLogger('nova.tests.integrated') + +FLAGS = flags.FLAGS +FLAGS.verbose = True + + +class LoginTest(unittest.TestCase): + def setUp(self): + super(LoginTest, self).setUp() + context = integrated_helpers.IntegratedUnitTestContext.startup() + self.user = context.test_user + self.api = self.user.openstack_api + + def tearDown(self): + integrated_helpers.IntegratedUnitTestContext.shutdown() + super(LoginTest, self).tearDown() + + def test_login(self): + """Simple check - we list flavors - so we know we're logged in""" + flavors = self.api.get_flavors() + for flavor in flavors: + LOG.debug(_("flavor: %s") % flavor) + + def test_bad_login_password(self): + """Test that I get a 401 with a bad username""" + bad_credentials_api = client.TestOpenStackClient(self.user.name, + "notso_password", + self.user.auth_url) + + self.assertRaises(client.OpenstackApiAuthenticationException, + bad_credentials_api.get_flavors) + + def test_bad_login_username(self): + """Test that I get a 401 with a bad password""" + bad_credentials_api = client.TestOpenStackClient("notso_username", + self.user.secret, + self.user.auth_url) + + self.assertRaises(client.OpenstackApiAuthenticationException, + bad_credentials_api.get_flavors) + + + def test_bad_login_both_bad(self): + """Test that I get a 401 with both bad username and bad password""" + bad_credentials_api = client.TestOpenStackClient("notso_username", + "notso_password", + self.user.auth_url) + + self.assertRaises(client.OpenstackApiAuthenticationException, + bad_credentials_api.get_flavors) + +if __name__ == "__main__": + unittest.main() -- cgit From 3d6430ecd114daa21c72c3d215daaa94f0e87e62 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 10 Mar 2011 14:12:41 -0800 Subject: Re-removed the code that was deleted upstream but somehow didn't get merged in. Bizarre! --- nova/tests/integrated/api/client.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 0ce480ae7..da8d87e07 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -172,27 +172,6 @@ class TestOpenStackClient(object): kwargs.setdefault('check_response_status', [200, 202]) return self.api_request(relative_uri, **kwargs) - def get_keys_detail(self): - return self.api_get('/keys/detail')['keys'] - - def post_key(self, key): - return self.api_post('/keys', key)['key'] - - def delete_key(self, key_id): - return self.api_delete('/keys/%s' % key_id) - - def get_volume(self, volume_id): - return self.api_get('/volumes/%s' % volume_id)['volume'] - - def get_volumes_detail(self): - return self.api_get('/volumes/detail')['volumes'] - - def post_volume(self, volume): - return self.api_post('/volumes', volume)['volume'] - - def delete_volume(self, volume_id): - return self.api_delete('/volumes/%s' % volume_id) - def get_server(self, server_id): return self.api_get('/servers/%s' % server_id)['server'] -- cgit From 29bc4f5074ca3ada98a25a745077b998b4c5509c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 10 Mar 2011 14:14:01 -0800 Subject: Pep8 / Style --- nova/tests/integrated/test_login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index 990dcaaf4..e362f92d6 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -22,6 +22,7 @@ from nova.log import logging from nova.tests.integrated import integrated_helpers from nova.tests.integrated.api import client + LOG = logging.getLogger('nova.tests.integrated') FLAGS = flags.FLAGS @@ -63,7 +64,6 @@ class LoginTest(unittest.TestCase): self.assertRaises(client.OpenstackApiAuthenticationException, bad_credentials_api.get_flavors) - def test_bad_login_both_bad(self): """Test that I get a 401 with both bad username and bad password""" bad_credentials_api = client.TestOpenStackClient("notso_username", -- cgit From 0d3e950ed4b0c8abbd619d4ac8724b4c3ce45bf1 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Thu, 10 Mar 2011 14:21:36 -0800 Subject: Document known bug numbers by the code which is degraded until the bugs are fixed --- nova/tests/integrated/api/client.py | 1 + nova/tests/integrated/integrated_helpers.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index da8d87e07..6fba2930a 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -109,6 +109,7 @@ class TestOpenStackClient(object): LOG.debug(_("%(auth_uri)s => code %(http_status)s") % locals()) # Until bug732866 is fixed, we can't check this properly... + # bug732866 #if http_status == 401: if http_status != 204: raise OpenstackApiAuthenticationException(response=response) diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 691ead6e1..47093636e 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -104,6 +104,7 @@ class IntegratedUnitTestContext(object): def _start_services(self): # WSGI shutdown broken :-( + # bug731668 if not self.api_service: self._start_api_service() @@ -112,6 +113,7 @@ class IntegratedUnitTestContext(object): service.kill() self.services = [] # TODO(justinsb): Shutdown WSGI & anything else we startup + # bug731668 # WSGI shutdown broken :-( # self.wsgi_server.terminate() # self.wsgi_server = None @@ -124,6 +126,7 @@ class IntegratedUnitTestContext(object): auth_key = generate_random_alphanumeric(16) # Right now there's a bug where auth_name and auth_key are reversed + # bug732907 auth_key = auth_name self.auth_manager.create_user(auth_name, auth_name, auth_key, False) @@ -156,6 +159,7 @@ class IntegratedUnitTestContext(object): return api_service # WSGI shutdown broken :-( + # bug731668 #@staticmethod #def get(): # if not IntegratedUnitTestContext.__INSTANCE: @@ -166,6 +170,7 @@ class IntegratedUnitTestContext(object): @staticmethod def startup(): # Because WSGI shutdown is broken at the moment, we have to recycle + # bug731668 if IntegratedUnitTestContext.__INSTANCE: #raise Error("Multiple calls to IntegratedUnitTestContext.startup") IntegratedUnitTestContext.__INSTANCE.setup() @@ -179,4 +184,5 @@ class IntegratedUnitTestContext(object): raise Error("Must call IntegratedUnitTestContext::startup") IntegratedUnitTestContext.__INSTANCE.cleanup() # WSGI shutdown broken :-( + # bug731668 #IntegratedUnitTestContext.__INSTANCE = None -- cgit From e891e48b63065a7218627289a908aece0f6a3730 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Fri, 11 Mar 2011 10:31:08 -0800 Subject: Made changes to xs-ipv6 code impacted because of addition of flatmanger ipv6 support --- nova/virt/xenapi/vmops.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9ac83efb0..52d2652f9 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -617,9 +617,10 @@ class VMOps(object): def ip6_dict(ip6): return { - "ip": ip6.addressV6, - "netmask": ip6.netmaskV6, - "gateway": ip6.gatewayV6, + "ip": utils.to_global_ipv6(network['cidr_v6'], + instance['mac_address']), + "netmask": network['netmask_v6'], + "gateway": network['gateway_v6'], "enabled": "1"} mac_id = instance.mac_address.replace(':', '') -- cgit From bacce305a99dff77aa0e24c64cb937514e368ec1 Mon Sep 17 00:00:00 2001 From: Anne Gentle Date: Fri, 11 Mar 2011 17:13:56 -0600 Subject: Adding a sidebar element to the nova.openstack.org site to point people to additional versions of the site. --- doc/source/_static/tweaks.css | 147 ++++++++++++++++++++++++++++++++++++++++++ doc/source/_theme/layout.html | 11 +++- 2 files changed, 157 insertions(+), 1 deletion(-) diff --git a/doc/source/_static/tweaks.css b/doc/source/_static/tweaks.css index 1a18dbac6..7c57c8f35 100644 --- a/doc/source/_static/tweaks.css +++ b/doc/source/_static/tweaks.css @@ -69,3 +69,150 @@ table.docutils { .tweet_list li .tweet_avatar { float: left; } + +/* ------------------------------------------ +PURE CSS SPEECH BUBBLES +by Nicolas Gallagher +- http://nicolasgallagher.com/pure-css-speech-bubbles/ + +http://nicolasgallagher.com +http://twitter.com/necolas + +Created: 02 March 2010 +Version: 1.1 (21 October 2010) + +Dual licensed under MIT and GNU GPLv2 © Nicolas Gallagher +------------------------------------------ */ +/* THE SPEECH BUBBLE +------------------------------------------------------------------------------------------------------------------------------- */ + +/* THE SPEECH BUBBLE +------------------------------------------------------------------------------------------------------------------------------- */ + +.triangle-border { + position:relative; + padding:15px; + margin:1em 0 3em; + border:5px solid #BC1518; + color:#333; + background:#fff; + + /* css3 */ + -moz-border-radius:10px; + -webkit-border-radius:10px; + border-radius:10px; +} + +/* Variant : for left positioned triangle +------------------------------------------ */ + +.triangle-border.left { + margin-left:30px; +} + +/* Variant : for right positioned triangle +------------------------------------------ */ + +.triangle-border.right { + margin-right:30px; +} + +/* THE TRIANGLE +------------------------------------------------------------------------------------------------------------------------------- */ + +.triangle-border:before { + content:""; + display:block; /* reduce the damage in FF3.0 */ + position:absolute; + bottom:-40px; /* value = - border-top-width - border-bottom-width */ + left:40px; /* controls horizontal position */ + width:0; + height:0; + border:20px solid transparent; + border-top-color:#BC1518; +} + +/* creates the smaller triangle */ +.triangle-border:after { + content:""; + display:block; /* reduce the damage in FF3.0 */ + position:absolute; + bottom:-26px; /* value = - border-top-width - border-bottom-width */ + left:47px; /* value = (:before left) + (:before border-left) - (:after border-left) */ + width:0; + height:0; + border:13px solid transparent; + border-top-color:#fff; +} + +/* Variant : top +------------------------------------------ */ + +/* creates the larger triangle */ +.triangle-border.top:before { + top:-40px; /* value = - border-top-width - border-bottom-width */ + right:40px; /* controls horizontal position */ + bottom:auto; + left:auto; + border:20px solid transparent; + border-bottom-color:#BC1518; +} + +/* creates the smaller triangle */ +.triangle-border.top:after { + top:-26px; /* value = - border-top-width - border-bottom-width */ + right:47px; /* value = (:before right) + (:before border-right) - (:after border-right) */ + bottom:auto; + left:auto; + border:13px solid transparent; + border-bottom-color:#fff; +} + +/* Variant : left +------------------------------------------ */ + +/* creates the larger triangle */ +.triangle-border.left:before { + top:10px; /* controls vertical position */ + left:-30px; /* value = - border-left-width - border-right-width */ + bottom:auto; + border-width:15px 30px 15px 0; + border-style:solid; + border-color:transparent #BC1518; +} + +/* creates the smaller triangle */ +.triangle-border.left:after { + top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */ + left:-21px; /* value = - border-left-width - border-right-width */ + bottom:auto; + border-width:9px 21px 9px 0; + border-style:solid; + border-color:transparent #fff; +} + +/* Variant : right +------------------------------------------ */ + +/* creates the larger triangle */ +.triangle-border.right:before { + top:10px; /* controls vertical position */ + right:-30px; /* value = - border-left-width - border-right-width */ + bottom:auto; + left:auto; + border-width:15px 0 15px 30px; + border-style:solid; + border-color:transparent #BC1518; +} + +/* creates the smaller triangle */ +.triangle-border.right:after { + top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */ + right:-21px; /* value = - border-left-width - border-right-width */ + bottom:auto; + left:auto; + border-width:9px 0 9px 21px; + border-style:solid; + border-color:transparent #fff; +} + diff --git a/doc/source/_theme/layout.html b/doc/source/_theme/layout.html index e3eb54b71..958c512e4 100644 --- a/doc/source/_theme/layout.html +++ b/doc/source/_theme/layout.html @@ -71,12 +71,21 @@

+ +

+ Psst... hey. You're reading the latest content, but it might be out of sync with code. You can read Nova 2011.1 docs or all OpenStack docs too. +

+ {%- endif %} {%- if pagename == "index" %} -

{{ _('Twitter Feed') }}

+ + +

{{ _('Twitter Feed') }}

{%- endif %} + + {%- endblock %} -- cgit From d45947d83fa22f98b0889d269d447fabaa764a3c Mon Sep 17 00:00:00 2001 From: Anne Gentle Date: Mon, 14 Mar 2011 09:48:58 -0500 Subject: Fixes link to 2011.1 instad of just to trunk docs --- doc/source/_theme/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/_theme/layout.html b/doc/source/_theme/layout.html index 958c512e4..0a37a7943 100644 --- a/doc/source/_theme/layout.html +++ b/doc/source/_theme/layout.html @@ -73,7 +73,7 @@

- Psst... hey. You're reading the latest content, but it might be out of sync with code. You can read Nova 2011.1 docs or all OpenStack docs too. + Psst... hey. You're reading the latest content, but it might be out of sync with code. You can read Nova 2011.1 docs or all OpenStack docs too.

{%- endif %} -- cgit From 06051ac8660983aae9ea6e72ab9bb1a31ceed9af Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Mon, 14 Mar 2011 11:08:00 -0700 Subject: Reverted unmodified files --- tools/ajaxterm/README.txt | 240 +++++++++++++++++++++++----------------------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/tools/ajaxterm/README.txt b/tools/ajaxterm/README.txt index a649771c5..4b0ae99af 100644 --- a/tools/ajaxterm/README.txt +++ b/tools/ajaxterm/README.txt @@ -1,120 +1,120 @@ -= [http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm Ajaxterm] = - -Ajaxterm is a web based terminal. It was totally inspired and works almost -exactly like http://anyterm.org/ except it's much easier to install (see -comparaison with anyterm below). - -Ajaxterm written in python (and some AJAX javascript for client side) and depends only on python2.3 or better.[[BR]] -Ajaxterm is '''very simple to install''' on Linux, MacOS X, FreeBSD, Solaris, cygwin and any Unix that runs python2.3.[[BR]] -Ajaxterm was written by Antony Lesuisse (email: al AT udev.org), License Public Domain. - -Use the [/qweb/forum/viewforum.php?id=2 Forum], if you have any question or remark. - -== News == - - * 2006-10-29: v0.10 allow space in login, cgi launch fix, redhat init - * 2006-07-12: v0.9 change uid, daemon fix (Daniel Fischer) - * 2006-07-04: v0.8 add login support to ssh (Sven Geggus), change max width to 256 - * 2006-05-31: v0.7 minor fixes, daemon option - * 2006-05-23: v0.6 Applied debian and gentoo patches, renamed to Ajaxterm, default port 8022 - -== Download and Install == - - * Release: [/qweb/files/Ajaxterm-0.10.tar.gz Ajaxterm-0.10.tar.gz] - * Browse src: [/qweb/trac/browser/trunk/ajaxterm/ ajaxterm/] - -To install Ajaxterm issue the following commands: -{{{ -wget http://antony.lesuisse.org/qweb/files/Ajaxterm-0.10.tar.gz -tar zxvf Ajaxterm-0.10.tar.gz -cd Ajaxterm-0.10 -./ajaxterm.py -}}} -Then point your browser to this URL : http://localhost:8022/ - -== Screenshot == - -{{{ -#!html -
ajaxterm screenshot
-}}} - -== Documentation and Caveats == - - * Ajaxterm only support latin1, if you use Ubuntu or any LANG==en_US.UTF-8 distribution don't forget to "unset LANG". - - * If run as root ajaxterm will run /bin/login, otherwise it will run ssh - localhost. To use an other command use the -c option. - - * By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is - strongly recommended to use '''https SSL/TLS''', and that is simple to - configure if you use the apache web server using mod_proxy.[[BR]][[BR]] - Using ssl will also speed up ajaxterm (probably because of keepalive).[[BR]][[BR]] - Here is an configuration example: - -{{{ - Listen 443 - NameVirtualHost *:443 - - - ServerName localhost - SSLEngine On - SSLCertificateKeyFile ssl/apache.pem - SSLCertificateFile ssl/apache.pem - - ProxyRequests Off - - Order deny,allow - Allow from all - - ProxyPass /ajaxterm/ http://localhost:8022/ - ProxyPassReverse /ajaxterm/ http://localhost:8022/ - -}}} - - * Using GET HTTP request seems to speed up ajaxterm, just click on GET in the - interface, but be warned that your keystrokes might be loggued (by apache or - any proxy). I usually enable it after the login. - - * Ajaxterm commandline usage: - -{{{ -usage: ajaxterm.py [options] - -options: - -h, --help show this help message and exit - -pPORT, --port=PORT Set the TCP port (default: 8022) - -cCMD, --command=CMD set the command (default: /bin/login or ssh localhost) - -l, --log log requests to stderr (default: quiet mode) - -d, --daemon run as daemon in the background - -PPIDFILE, --pidfile=PIDFILE - set the pidfile (default: /var/run/ajaxterm.pid) - -iINDEX_FILE, --index=INDEX_FILE - default index file (default: ajaxterm.html) - -uUID, --uid=UID Set the daemon's user id -}}} - - * Ajaxterm was first written as a demo for qweb (my web framework), but - actually doesn't use many features of qweb. - - * Compared to anyterm: - * There are no partial updates, ajaxterm updates either all the screen or - nothing. That make the code simpler and I also think it's faster. HTTP - replies are always gzencoded. When used in 80x25 mode, almost all of - them are below the 1500 bytes (size of an ethernet frame) and we just - replace the screen with the reply (no javascript string handling). - * Ajaxterm polls the server for updates with an exponentially growing - timeout when the screen hasn't changed. The timeout is also resetted as - soon as a key is pressed. Anyterm blocks on a pending request and use a - parallel connection for keypresses. The anyterm approch is better - when there aren't any keypress. - - * Ajaxterm files are released in the Public Domain, (except [http://sarissa.sourceforge.net/doc/ sarissa*] which are LGPL). - -== TODO == - - * insert mode ESC [ 4 h - * change size x,y from gui (sending signal) - * vt102 graphic codepage - * use innerHTML or prototype instead of sarissa - += [http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm Ajaxterm] = + +Ajaxterm is a web based terminal. It was totally inspired and works almost +exactly like http://anyterm.org/ except it's much easier to install (see +comparaison with anyterm below). + +Ajaxterm written in python (and some AJAX javascript for client side) and depends only on python2.3 or better.[[BR]] +Ajaxterm is '''very simple to install''' on Linux, MacOS X, FreeBSD, Solaris, cygwin and any Unix that runs python2.3.[[BR]] +Ajaxterm was written by Antony Lesuisse (email: al AT udev.org), License Public Domain. + +Use the [/qweb/forum/viewforum.php?id=2 Forum], if you have any question or remark. + +== News == + + * 2006-10-29: v0.10 allow space in login, cgi launch fix, redhat init + * 2006-07-12: v0.9 change uid, daemon fix (Daniel Fischer) + * 2006-07-04: v0.8 add login support to ssh (Sven Geggus), change max width to 256 + * 2006-05-31: v0.7 minor fixes, daemon option + * 2006-05-23: v0.6 Applied debian and gentoo patches, renamed to Ajaxterm, default port 8022 + +== Download and Install == + + * Release: [/qweb/files/Ajaxterm-0.10.tar.gz Ajaxterm-0.10.tar.gz] + * Browse src: [/qweb/trac/browser/trunk/ajaxterm/ ajaxterm/] + +To install Ajaxterm issue the following commands: +{{{ +wget http://antony.lesuisse.org/qweb/files/Ajaxterm-0.10.tar.gz +tar zxvf Ajaxterm-0.10.tar.gz +cd Ajaxterm-0.10 +./ajaxterm.py +}}} +Then point your browser to this URL : http://localhost:8022/ + +== Screenshot == + +{{{ +#!html +
ajaxterm screenshot
+}}} + +== Documentation and Caveats == + + * Ajaxterm only support latin1, if you use Ubuntu or any LANG==en_US.UTF-8 distribution don't forget to "unset LANG". + + * If run as root ajaxterm will run /bin/login, otherwise it will run ssh + localhost. To use an other command use the -c option. + + * By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is + strongly recommended to use '''https SSL/TLS''', and that is simple to + configure if you use the apache web server using mod_proxy.[[BR]][[BR]] + Using ssl will also speed up ajaxterm (probably because of keepalive).[[BR]][[BR]] + Here is an configuration example: + +{{{ + Listen 443 + NameVirtualHost *:443 + + + ServerName localhost + SSLEngine On + SSLCertificateKeyFile ssl/apache.pem + SSLCertificateFile ssl/apache.pem + + ProxyRequests Off + + Order deny,allow + Allow from all + + ProxyPass /ajaxterm/ http://localhost:8022/ + ProxyPassReverse /ajaxterm/ http://localhost:8022/ + +}}} + + * Using GET HTTP request seems to speed up ajaxterm, just click on GET in the + interface, but be warned that your keystrokes might be loggued (by apache or + any proxy). I usually enable it after the login. + + * Ajaxterm commandline usage: + +{{{ +usage: ajaxterm.py [options] + +options: + -h, --help show this help message and exit + -pPORT, --port=PORT Set the TCP port (default: 8022) + -cCMD, --command=CMD set the command (default: /bin/login or ssh localhost) + -l, --log log requests to stderr (default: quiet mode) + -d, --daemon run as daemon in the background + -PPIDFILE, --pidfile=PIDFILE + set the pidfile (default: /var/run/ajaxterm.pid) + -iINDEX_FILE, --index=INDEX_FILE + default index file (default: ajaxterm.html) + -uUID, --uid=UID Set the daemon's user id +}}} + + * Ajaxterm was first written as a demo for qweb (my web framework), but + actually doesn't use many features of qweb. + + * Compared to anyterm: + * There are no partial updates, ajaxterm updates either all the screen or + nothing. That make the code simpler and I also think it's faster. HTTP + replies are always gzencoded. When used in 80x25 mode, almost all of + them are below the 1500 bytes (size of an ethernet frame) and we just + replace the screen with the reply (no javascript string handling). + * Ajaxterm polls the server for updates with an exponentially growing + timeout when the screen hasn't changed. The timeout is also resetted as + soon as a key is pressed. Anyterm blocks on a pending request and use a + parallel connection for keypresses. The anyterm approch is better + when there aren't any keypress. + + * Ajaxterm files are released in the Public Domain, (except [http://sarissa.sourceforge.net/doc/ sarissa*] which are LGPL). + +== TODO == + + * insert mode ESC [ 4 h + * change size x,y from gui (sending signal) + * vt102 graphic codepage + * use innerHTML or prototype instead of sarissa + -- cgit -- cgit -- cgit From 5b1422afe12d4e9b7fdfdc6a61cdcd51962dab4d Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Mon, 14 Mar 2011 14:43:53 -0700 Subject: Fix for LP Bug #704300 --- nova/virt/libvirt_conn.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 0b306c950..e0222956e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -339,7 +339,11 @@ class LibvirtConnection(object): def reboot(self, instance): self.destroy(instance, False) xml = self.to_xml(instance) + self.firewall_driver.setup_basic_filtering(instance) + self.firewall_driver.prepare_instance_filter(instance) self._conn.createXML(xml, 0) + self.firewall_driver.apply_instance_filter(instance) + timer = utils.LoopingCall(f=None) def _wait_for_reboot(): -- cgit From 2b20306fcaddcb6b9bc57fb55b17230d709cd1ce Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 14 Mar 2011 22:23:38 -0700 Subject: Derive unit test from standard nova.test.TestCase --- nova/tests/integrated/test_login.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index e362f92d6..5fa558bdf 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -18,6 +18,7 @@ import unittest from nova import flags +from nova import test from nova.log import logging from nova.tests.integrated import integrated_helpers from nova.tests.integrated.api import client @@ -29,7 +30,7 @@ FLAGS = flags.FLAGS FLAGS.verbose = True -class LoginTest(unittest.TestCase): +class LoginTest(test.TestCase): def setUp(self): super(LoginTest, self).setUp() context = integrated_helpers.IntegratedUnitTestContext.startup() @@ -73,5 +74,6 @@ class LoginTest(unittest.TestCase): self.assertRaises(client.OpenstackApiAuthenticationException, bad_credentials_api.get_flavors) + if __name__ == "__main__": unittest.main() -- cgit From db8beffc9acd90c748512c1fa9c127d39756232c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 14 Mar 2011 22:36:30 -0700 Subject: Reapplied rename of Openstack -> OpenStack. Easier to do it by hand than to ask Bazaar to do it. --- nova/tests/integrated/api/client.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 6fba2930a..568e8c17e 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -24,7 +24,7 @@ from nova import log as logging LOG = logging.getLogger('nova.tests.api') -class OpenstackApiException(Exception): +class OpenStackApiException(Exception): def __init__(self, message=None, response=None): self.response = response if not message: @@ -37,22 +37,22 @@ class OpenstackApiException(Exception): message = _('%(message)s\nStatus Code: %(_status)s\n' 'Body: %(_body)s') % locals() - super(OpenstackApiException, self).__init__(message) + super(OpenStackApiException, self).__init__(message) -class OpenstackApiAuthenticationException(OpenstackApiException): +class OpenStackApiAuthenticationException(OpenStackApiException): def __init__(self, response=None, message=None): if not message: message = _("Authentication error") - super(OpenstackApiAuthenticationException, self).__init__(message, + super(OpenStackApiAuthenticationException, self).__init__(message, response) -class OpenstackApiNotFoundException(OpenstackApiException): +class OpenStackApiNotFoundException(OpenStackApiException): def __init__(self, response=None, message=None): if not message: message = _("Item not found") - super(OpenstackApiNotFoundException, self).__init__(message, response) + super(OpenStackApiNotFoundException, self).__init__(message, response) class TestOpenStackClient(object): @@ -82,7 +82,7 @@ class TestOpenStackClient(object): conn = httplib.HTTPSConnection(hostname, port=port) else: - raise OpenstackApiException("Unknown scheme: %s" % url) + raise OpenStackApiException("Unknown scheme: %s" % url) relative_url = parsed_url.path if parsed_url.query: @@ -112,7 +112,7 @@ class TestOpenStackClient(object): # bug732866 #if http_status == 401: if http_status != 204: - raise OpenstackApiAuthenticationException(response=response) + raise OpenStackApiAuthenticationException(response=response) auth_headers = {} for k, v in response.getheaders(): @@ -139,9 +139,9 @@ class TestOpenStackClient(object): if check_response_status: if not http_status in check_response_status: if http_status == 404: - raise OpenstackApiNotFoundException(response=response) + raise OpenStackApiNotFoundException(response=response) else: - raise OpenstackApiException( + raise OpenStackApiException( message=_("Unexpected status code"), response=response) -- cgit From e0563f49792441af106c52e662bdada3c7997feb Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Mon, 14 Mar 2011 22:43:21 -0700 Subject: Reapplied rename to another file. --- nova/tests/integrated/test_login.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index 5fa558bdf..501f8c919 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -53,7 +53,7 @@ class LoginTest(test.TestCase): "notso_password", self.user.auth_url) - self.assertRaises(client.OpenstackApiAuthenticationException, + self.assertRaises(client.OpenStackApiAuthenticationException, bad_credentials_api.get_flavors) def test_bad_login_username(self): @@ -62,7 +62,7 @@ class LoginTest(test.TestCase): self.user.secret, self.user.auth_url) - self.assertRaises(client.OpenstackApiAuthenticationException, + self.assertRaises(client.OpenStackApiAuthenticationException, bad_credentials_api.get_flavors) def test_bad_login_both_bad(self): @@ -71,7 +71,7 @@ class LoginTest(test.TestCase): "notso_password", self.user.auth_url) - self.assertRaises(client.OpenstackApiAuthenticationException, + self.assertRaises(client.OpenStackApiAuthenticationException, bad_credentials_api.get_flavors) -- cgit From f1acc3d199a1a92b531a3e74ed54a8b2fcdb999c Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Tue, 15 Mar 2011 13:52:03 -0700 Subject: Now that the fix for 732866, stop working around the bug --- nova/tests/integrated/api/client.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py index 568e8c17e..fc7c344e7 100644 --- a/nova/tests/integrated/api/client.py +++ b/nova/tests/integrated/api/client.py @@ -108,10 +108,7 @@ class TestOpenStackClient(object): http_status = response.status LOG.debug(_("%(auth_uri)s => code %(http_status)s") % locals()) - # Until bug732866 is fixed, we can't check this properly... - # bug732866 - #if http_status == 401: - if http_status != 204: + if http_status == 401: raise OpenStackApiAuthenticationException(response=response) auth_headers = {} -- cgit From e2f8c143eab3b43acd9e3658a480f75f435e7d42 Mon Sep 17 00:00:00 2001 From: Koji Iida Date: Wed, 16 Mar 2011 19:51:06 +0900 Subject: Updating gateway_v6 in _on_set_network_host() is not required for FlatManager --- nova/network/manager.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nova/network/manager.py b/nova/network/manager.py index c51eb9ad0..7e28e6da2 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -404,11 +404,6 @@ class FlatManager(NetworkManager): net = {} net['injected'] = FLAGS.flat_injected net['dns'] = FLAGS.flat_network_dns - if not FLAGS.fake_network: - if(FLAGS.use_ipv6): - net['gateway_v6'] = \ - utils.get_my_linklocal( - FLAGS.flat_network_bridge) self.db.network_update(context, network_id, net) def allocate_floating_ip(self, context, project_id): -- cgit From 8964cbecc10885bc6eff08544d62db1747fb14ef Mon Sep 17 00:00:00 2001 From: Koji Iida Date: Wed, 16 Mar 2011 20:24:20 +0900 Subject: pep8 clean --- nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py index be1edc8f6..9f98f436f 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py @@ -83,8 +83,7 @@ networks = Table('networks', meta, Column( 'label', String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)) - ) + unicode_error=None, _warn_on_bytestring=False))) fixed_ips = Table('fixed_ips', meta, Column('created_at', DateTime(timezone=False)), -- cgit From 2e81ce6bb5b1083220e7ae5c17113fd44465ddbf Mon Sep 17 00:00:00 2001 From: Koji Iida Date: Wed, 16 Mar 2011 21:17:19 +0900 Subject: Fix instance creation fail under use_ipv6=false and FlatManager --- nova/virt/libvirt_conn.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9efbb3342..a850bad87 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -660,11 +660,10 @@ class LibvirtConnection(object): if network_ref['injected']: admin_context = context.get_admin_context() address = db.instance_get_fixed_address(admin_context, inst['id']) - address_v6 = db.instance_get_fixed_address_v6(admin_context, - inst['id']) - gateway_v6 = network_ref['gateway_v6'] - if not gateway_v6: - gateway_v6 = "fd00::" + address_v6 = None + if FLAGS.use_ipv6: + address_v6 = db.instance_get_fixed_address_v6(admin_context, + inst['id']) interfaces_info = {'address': address, 'netmask': network_ref['netmask'], -- cgit From d95187aaf144cb40558f48d584a6bb8e07c6937d Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Wed, 16 Mar 2011 14:13:57 -0700 Subject: converted new lines from CRLF to LF --- .../versions/012_add_ipv6_flatmanager.py | 302 +++++++++---------- nova/tests/network/__init__.py | 94 +++--- nova/tests/network/base.py | 308 ++++++++++---------- nova/tests/test_flat_network.py | 322 ++++++++++----------- 4 files changed, 513 insertions(+), 513 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py index 9f98f436f..5f5e3d007 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py @@ -1,151 +1,151 @@ -# Copyright 2010 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from sqlalchemy import * -from migrate import * - -from nova import log as logging - - -meta = MetaData() - - -# Table stub-definitions -# Just for the ForeignKey and column creation to succeed, these are not the -# actual definitions of instances or services. -# - -# -# Tables to alter -# -networks = Table('networks', meta, - Column('created_at', DateTime(timezone=False)), - Column('updated_at', DateTime(timezone=False)), - Column('deleted_at', DateTime(timezone=False)), - Column('deleted', Boolean(create_constraint=True, name=None)), - Column('id', Integer(), primary_key=True, nullable=False), - Column('injected', Boolean(create_constraint=True, name=None)), - Column('cidr', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('netmask', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('bridge', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('gateway', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('broadcast', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('dns', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('vlan', Integer()), - Column('vpn_public_address', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('vpn_public_port', Integer()), - Column('vpn_private_address', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('dhcp_start', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('project_id', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('host', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('cidr_v6', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('ra_server', String(length=255, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)), - Column( - 'label', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False))) - -fixed_ips = Table('fixed_ips', meta, - Column('created_at', DateTime(timezone=False)), - Column('updated_at', DateTime(timezone=False)), - Column('deleted_at', DateTime(timezone=False)), - Column('deleted', Boolean(create_constraint=True, name=None)), - Column('id', Integer(), primary_key=True, nullable=False), - Column('address', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)), - Column('network_id', - Integer(), - ForeignKey('networks.id'), - nullable=True), - Column('instance_id', - Integer(), - ForeignKey('instances.id'), - nullable=True), - Column('allocated', Boolean(create_constraint=True, name=None)), - Column('leased', Boolean(create_constraint=True, name=None)), - Column('reserved', Boolean(create_constraint=True, name=None)), - Column("addressV6", String(length=255, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)), - Column("netmaskV6", String(length=3, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)), - Column("gatewayV6", String(length=255, - convert_unicode=False, - assert_unicode=None, - unicode_error=None, - _warn_on_bytestring=False)), - ) -# -# New Tables -# -# None - -# -# Columns to add to existing tables -# -networks_netmask_v6 = Column( - 'netmask_v6', - String(length=255, convert_unicode=False, assert_unicode=None, - unicode_error=None, _warn_on_bytestring=False)) - - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; - # bind migrate_engine to your metadata - meta.bind = migrate_engine - - # Alter column name - networks.c.ra_server.alter(name='gateway_v6') - # Add new column to existing table - networks.create_column(networks_netmask_v6) - - # drop existing columns from table - fixed_ips.c.addressV6.drop() - fixed_ips.c.netmaskV6.drop() - fixed_ips.c.gatewayV6.drop() +# Copyright 2010 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import * +from migrate import * + +from nova import log as logging + + +meta = MetaData() + + +# Table stub-definitions +# Just for the ForeignKey and column creation to succeed, these are not the +# actual definitions of instances or services. +# + +# +# Tables to alter +# +networks = Table('networks', meta, + Column('created_at', DateTime(timezone=False)), + Column('updated_at', DateTime(timezone=False)), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', Boolean(create_constraint=True, name=None)), + Column('id', Integer(), primary_key=True, nullable=False), + Column('injected', Boolean(create_constraint=True, name=None)), + Column('cidr', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('netmask', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('bridge', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('gateway', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('broadcast', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('dns', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vlan', Integer()), + Column('vpn_public_address', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('vpn_public_port', Integer()), + Column('vpn_private_address', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('dhcp_start', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('project_id', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('host', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('cidr_v6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('ra_server', String(length=255, + convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)), + Column( + 'label', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False))) + +fixed_ips = Table('fixed_ips', meta, + Column('created_at', DateTime(timezone=False)), + Column('updated_at', DateTime(timezone=False)), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', Boolean(create_constraint=True, name=None)), + Column('id', Integer(), primary_key=True, nullable=False), + Column('address', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('network_id', + Integer(), + ForeignKey('networks.id'), + nullable=True), + Column('instance_id', + Integer(), + ForeignKey('instances.id'), + nullable=True), + Column('allocated', Boolean(create_constraint=True, name=None)), + Column('leased', Boolean(create_constraint=True, name=None)), + Column('reserved', Boolean(create_constraint=True, name=None)), + Column("addressV6", String(length=255, + convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)), + Column("netmaskV6", String(length=3, + convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)), + Column("gatewayV6", String(length=255, + convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)), + ) +# +# New Tables +# +# None + +# +# Columns to add to existing tables +# +networks_netmask_v6 = Column( + 'netmask_v6', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + # Alter column name + networks.c.ra_server.alter(name='gateway_v6') + # Add new column to existing table + networks.create_column(networks_netmask_v6) + + # drop existing columns from table + fixed_ips.c.addressV6.drop() + fixed_ips.c.netmaskV6.drop() + fixed_ips.c.gatewayV6.drop() diff --git a/nova/tests/network/__init__.py b/nova/tests/network/__init__.py index 8f71a30ba..e0d479f8c 100644 --- a/nova/tests/network/__init__.py +++ b/nova/tests/network/__init__.py @@ -1,47 +1,47 @@ -import os - -from nova import context -from nova import db -from nova import flags -from nova import log as logging -from nova import utils - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.network') - - -def binpath(script): - """Returns the absolute path to a script in bin""" - return os.path.abspath(os.path.join(__file__, "../../../../bin", script)) - - -def lease_ip(private_ip): - """Run add command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = (binpath('nova-dhcpbridge'), 'add', - instance_ref['mac_address'], - private_ip, 'fake') - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(*cmd, addl_env=env) - LOG.debug("ISSUE_IP: %s, %s ", out, err) - - -def release_ip(private_ip): - """Run del command on dhcpbridge""" - network_ref = db.fixed_ip_get_network(context.get_admin_context(), - private_ip) - instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), - private_ip) - cmd = (binpath('nova-dhcpbridge'), 'del', - instance_ref['mac_address'], - private_ip, 'fake') - env = {'DNSMASQ_INTERFACE': network_ref['bridge'], - 'TESTING': '1', - 'FLAGFILE': FLAGS.dhcpbridge_flagfile} - (out, err) = utils.execute(*cmd, addl_env=env) - LOG.debug("RELEASE_IP: %s, %s ", out, err) +import os + +from nova import context +from nova import db +from nova import flags +from nova import log as logging +from nova import utils + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +def binpath(script): + """Returns the absolute path to a script in bin""" + return os.path.abspath(os.path.join(__file__, "../../../../bin", script)) + + +def lease_ip(private_ip): + """Run add command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = (binpath('nova-dhcpbridge'), 'add', + instance_ref['mac_address'], + private_ip, 'fake') + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(*cmd, addl_env=env) + LOG.debug("ISSUE_IP: %s, %s ", out, err) + + +def release_ip(private_ip): + """Run del command on dhcpbridge""" + network_ref = db.fixed_ip_get_network(context.get_admin_context(), + private_ip) + instance_ref = db.fixed_ip_get_instance(context.get_admin_context(), + private_ip) + cmd = (binpath('nova-dhcpbridge'), 'del', + instance_ref['mac_address'], + private_ip, 'fake') + env = {'DNSMASQ_INTERFACE': network_ref['bridge'], + 'TESTING': '1', + 'FLAGFILE': FLAGS.dhcpbridge_flagfile} + (out, err) = utils.execute(*cmd, addl_env=env) + LOG.debug("RELEASE_IP: %s, %s ", out, err) diff --git a/nova/tests/network/base.py b/nova/tests/network/base.py index 2dd8178ff..988a1de72 100644 --- a/nova/tests/network/base.py +++ b/nova/tests/network/base.py @@ -1,154 +1,154 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Base class of Unit Tests for all network models -""" -import IPy -import os - -from nova import context -from nova import db -from nova import exception -from nova import flags -from nova import log as logging -from nova import test -from nova import utils -from nova.auth import manager - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.network') - - -class NetworkTestCase(test.TestCase): - """Test cases for network code""" - def setUp(self): - super(NetworkTestCase, self).setUp() - # NOTE(vish): if you change these flags, make sure to change the - # flags in the corresponding section in nova-dhcpbridge - self.flags(connection_type='fake', - fake_call=True, - fake_network=True) - self.manager = manager.AuthManager() - self.user = self.manager.create_user('netuser', 'netuser', 'netuser') - self.projects = [] - self.network = utils.import_object(FLAGS.network_manager) - self.context = context.RequestContext(project=None, user=self.user) - for i in range(FLAGS.num_networks): - name = 'project%s' % i - project = self.manager.create_project(name, 'netuser', name) - self.projects.append(project) - # create the necessary network data for the project - user_context = context.RequestContext(project=self.projects[i], - user=self.user) - host = self.network.get_network_host(user_context.elevated()) - instance_ref = self._create_instance(0) - self.instance_id = instance_ref['id'] - instance_ref = self._create_instance(1) - self.instance2_id = instance_ref['id'] - - def tearDown(self): - # TODO(termie): this should really be instantiating clean datastores - # in between runs, one failure kills all the tests - db.instance_destroy(context.get_admin_context(), self.instance_id) - db.instance_destroy(context.get_admin_context(), self.instance2_id) - for project in self.projects: - self.manager.delete_project(project) - self.manager.delete_user(self.user) - super(NetworkTestCase, self).tearDown() - - def _create_instance(self, project_num, mac=None): - if not mac: - mac = utils.generate_mac() - project = self.projects[project_num] - self.context._project = project - self.context.project_id = project.id - return db.instance_create(self.context, - {'project_id': project.id, - 'mac_address': mac}) - - def _create_address(self, project_num, instance_id=None): - """Create an address in given project num""" - if instance_id is None: - instance_id = self.instance_id - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - return self.network.allocate_fixed_ip(self.context, instance_id) - - def _deallocate_address(self, project_num, address): - self.context._project = self.projects[project_num] - self.context.project_id = self.projects[project_num].id - self.network.deallocate_fixed_ip(self.context, address) - - def _is_allocated_in_project(self, address, project_id): - """Returns true if address is in specified project""" - project_net = db.network_get_by_bridge(context.get_admin_context(), - FLAGS.flat_network_bridge) - network = db.fixed_ip_get_network(context.get_admin_context(), - address) - instance = db.fixed_ip_get_instance(context.get_admin_context(), - address) - # instance exists until release - return instance is not None and network['id'] == project_net['id'] - - def test_private_ipv6(self): - """Make sure ipv6 is OK""" - if FLAGS.use_ipv6: - instance_ref = self._create_instance(0) - address = self._create_address(0, instance_ref['id']) - network_ref = db.project_get_network( - context.get_admin_context(), - self.context.project_id) - address_v6 = db.instance_get_fixed_address_v6( - context.get_admin_context(), - instance_ref['id']) - self.assertEqual(instance_ref['mac_address'], - utils.to_mac(address_v6)) - instance_ref2 = db.fixed_ip_get_instance_v6( - context.get_admin_context(), - address_v6) - self.assertEqual(instance_ref['id'], instance_ref2['id']) - self.assertEqual(address_v6, - utils.to_global_ipv6( - network_ref['cidr_v6'], - instance_ref['mac_address'])) - self._deallocate_address(0, address) - db.instance_destroy(context.get_admin_context(), - instance_ref['id']) - - def test_available_ips(self): - """Make sure the number of available ips for the network is correct - - The number of available IP addresses depends on the test - environment's setup. - - Network size is set in test fixture's setUp method. - - There are ips reserved at the bottom and top of the range. - services (network, gateway, CloudPipe, broadcast) - """ - network = db.project_get_network(context.get_admin_context(), - self.projects[0].id) - net_size = flags.FLAGS.network_size - admin_context = context.get_admin_context() - total_ips = (db.network_count_available_ips(admin_context, - network['id']) + - db.network_count_reserved_ips(admin_context, - network['id']) + - db.network_count_allocated_ips(admin_context, - network['id'])) - self.assertEqual(total_ips, net_size) +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Base class of Unit Tests for all network models +""" +import IPy +import os + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.auth import manager + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +class NetworkTestCase(test.TestCase): + """Test cases for network code""" + def setUp(self): + super(NetworkTestCase, self).setUp() + # NOTE(vish): if you change these flags, make sure to change the + # flags in the corresponding section in nova-dhcpbridge + self.flags(connection_type='fake', + fake_call=True, + fake_network=True) + self.manager = manager.AuthManager() + self.user = self.manager.create_user('netuser', 'netuser', 'netuser') + self.projects = [] + self.network = utils.import_object(FLAGS.network_manager) + self.context = context.RequestContext(project=None, user=self.user) + for i in range(FLAGS.num_networks): + name = 'project%s' % i + project = self.manager.create_project(name, 'netuser', name) + self.projects.append(project) + # create the necessary network data for the project + user_context = context.RequestContext(project=self.projects[i], + user=self.user) + host = self.network.get_network_host(user_context.elevated()) + instance_ref = self._create_instance(0) + self.instance_id = instance_ref['id'] + instance_ref = self._create_instance(1) + self.instance2_id = instance_ref['id'] + + def tearDown(self): + # TODO(termie): this should really be instantiating clean datastores + # in between runs, one failure kills all the tests + db.instance_destroy(context.get_admin_context(), self.instance_id) + db.instance_destroy(context.get_admin_context(), self.instance2_id) + for project in self.projects: + self.manager.delete_project(project) + self.manager.delete_user(self.user) + super(NetworkTestCase, self).tearDown() + + def _create_instance(self, project_num, mac=None): + if not mac: + mac = utils.generate_mac() + project = self.projects[project_num] + self.context._project = project + self.context.project_id = project.id + return db.instance_create(self.context, + {'project_id': project.id, + 'mac_address': mac}) + + def _create_address(self, project_num, instance_id=None): + """Create an address in given project num""" + if instance_id is None: + instance_id = self.instance_id + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + return self.network.allocate_fixed_ip(self.context, instance_id) + + def _deallocate_address(self, project_num, address): + self.context._project = self.projects[project_num] + self.context.project_id = self.projects[project_num].id + self.network.deallocate_fixed_ip(self.context, address) + + def _is_allocated_in_project(self, address, project_id): + """Returns true if address is in specified project""" + project_net = db.network_get_by_bridge(context.get_admin_context(), + FLAGS.flat_network_bridge) + network = db.fixed_ip_get_network(context.get_admin_context(), + address) + instance = db.fixed_ip_get_instance(context.get_admin_context(), + address) + # instance exists until release + return instance is not None and network['id'] == project_net['id'] + + def test_private_ipv6(self): + """Make sure ipv6 is OK""" + if FLAGS.use_ipv6: + instance_ref = self._create_instance(0) + address = self._create_address(0, instance_ref['id']) + network_ref = db.project_get_network( + context.get_admin_context(), + self.context.project_id) + address_v6 = db.instance_get_fixed_address_v6( + context.get_admin_context(), + instance_ref['id']) + self.assertEqual(instance_ref['mac_address'], + utils.to_mac(address_v6)) + instance_ref2 = db.fixed_ip_get_instance_v6( + context.get_admin_context(), + address_v6) + self.assertEqual(instance_ref['id'], instance_ref2['id']) + self.assertEqual(address_v6, + utils.to_global_ipv6( + network_ref['cidr_v6'], + instance_ref['mac_address'])) + self._deallocate_address(0, address) + db.instance_destroy(context.get_admin_context(), + instance_ref['id']) + + def test_available_ips(self): + """Make sure the number of available ips for the network is correct + + The number of available IP addresses depends on the test + environment's setup. + + Network size is set in test fixture's setUp method. + + There are ips reserved at the bottom and top of the range. + services (network, gateway, CloudPipe, broadcast) + """ + network = db.project_get_network(context.get_admin_context(), + self.projects[0].id) + net_size = flags.FLAGS.network_size + admin_context = context.get_admin_context() + total_ips = (db.network_count_available_ips(admin_context, + network['id']) + + db.network_count_reserved_ips(admin_context, + network['id']) + + db.network_count_allocated_ips(admin_context, + network['id'])) + self.assertEqual(total_ips, net_size) diff --git a/nova/tests/test_flat_network.py b/nova/tests/test_flat_network.py index b6f7762c5..dcc617e25 100644 --- a/nova/tests/test_flat_network.py +++ b/nova/tests/test_flat_network.py @@ -1,161 +1,161 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Unit Tests for flat network code -""" -import IPy -import os -import unittest - -from nova import context -from nova import db -from nova import exception -from nova import flags -from nova import log as logging -from nova import test -from nova import utils -from nova.auth import manager -from nova.tests.network import base - - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.network') - - -class FlatNetworkTestCase(base.NetworkTestCase): - """Test cases for network code""" - def test_public_network_association(self): - """Makes sure that we can allocate a public ip""" - # TODO(vish): better way of adding floating ips - - self.context._project = self.projects[0] - self.context.project_id = self.projects[0].id - pubnet = IPy.IP(flags.FLAGS.floating_range) - address = str(pubnet[0]) - try: - db.floating_ip_get_by_address(context.get_admin_context(), address) - except exception.NotFound: - db.floating_ip_create(context.get_admin_context(), - {'address': address, - 'host': FLAGS.host}) - - self.assertRaises(NotImplementedError, - self.network.allocate_floating_ip, - self.context, self.projects[0].id) - - fix_addr = self._create_address(0) - float_addr = address - self.assertRaises(NotImplementedError, - self.network.associate_floating_ip, - self.context, float_addr, fix_addr) - - address = db.instance_get_floating_address(context.get_admin_context(), - self.instance_id) - self.assertEqual(address, None) - - self.assertRaises(NotImplementedError, - self.network.disassociate_floating_ip, - self.context, float_addr) - - address = db.instance_get_floating_address(context.get_admin_context(), - self.instance_id) - self.assertEqual(address, None) - - self.assertRaises(NotImplementedError, - self.network.deallocate_floating_ip, - self.context, float_addr) - - self.network.deallocate_fixed_ip(self.context, fix_addr) - db.floating_ip_destroy(context.get_admin_context(), float_addr) - - def test_allocate_deallocate_fixed_ip(self): - """Makes sure that we can allocate and deallocate a fixed ip""" - address = self._create_address(0) - self.assertTrue(self._is_allocated_in_project(address, - self.projects[0].id)) - self._deallocate_address(0, address) - - # check if the fixed ip address is really deallocated - self.assertFalse(self._is_allocated_in_project(address, - self.projects[0].id)) - - def test_side_effects(self): - """Ensures allocating and releasing has no side effects""" - address = self._create_address(0) - address2 = self._create_address(1, self.instance2_id) - - self.assertTrue(self._is_allocated_in_project(address, - self.projects[0].id)) - self.assertTrue(self._is_allocated_in_project(address2, - self.projects[1].id)) - - self._deallocate_address(0, address) - self.assertFalse(self._is_allocated_in_project(address, - self.projects[0].id)) - - # First address release shouldn't affect the second - self.assertTrue(self._is_allocated_in_project(address2, - self.projects[0].id)) - - self._deallocate_address(1, address2) - self.assertFalse(self._is_allocated_in_project(address2, - self.projects[1].id)) - - def test_ips_are_reused(self): - """Makes sure that ip addresses that are deallocated get reused""" - address = self._create_address(0) - self.network.deallocate_fixed_ip(self.context, address) - - address2 = self._create_address(0) - self.assertEqual(address, address2) - - self.network.deallocate_fixed_ip(self.context, address2) - - def test_too_many_addresses(self): - """Test for a NoMoreAddresses exception when all fixed ips are used. - """ - admin_context = context.get_admin_context() - network = db.project_get_network(admin_context, self.projects[0].id) - num_available_ips = db.network_count_available_ips(admin_context, - network['id']) - addresses = [] - instance_ids = [] - for i in range(num_available_ips): - instance_ref = self._create_instance(0) - instance_ids.append(instance_ref['id']) - address = self._create_address(0, instance_ref['id']) - addresses.append(address) - - ip_count = db.network_count_available_ips(context.get_admin_context(), - network['id']) - self.assertEqual(ip_count, 0) - self.assertRaises(db.NoMoreAddresses, - self.network.allocate_fixed_ip, - self.context, - 'foo') - - for i in range(num_available_ips): - self.network.deallocate_fixed_ip(self.context, addresses[i]) - db.instance_destroy(context.get_admin_context(), instance_ids[i]) - ip_count = db.network_count_available_ips(context.get_admin_context(), - network['id']) - self.assertEqual(ip_count, num_available_ips) - - def run(self, result=None): - if(FLAGS.network_manager == 'nova.network.manager.FlatManager'): - super(FlatNetworkTestCase, self).run(result) +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Unit Tests for flat network code +""" +import IPy +import os +import unittest + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.auth import manager +from nova.tests.network import base + + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.network') + + +class FlatNetworkTestCase(base.NetworkTestCase): + """Test cases for network code""" + def test_public_network_association(self): + """Makes sure that we can allocate a public ip""" + # TODO(vish): better way of adding floating ips + + self.context._project = self.projects[0] + self.context.project_id = self.projects[0].id + pubnet = IPy.IP(flags.FLAGS.floating_range) + address = str(pubnet[0]) + try: + db.floating_ip_get_by_address(context.get_admin_context(), address) + except exception.NotFound: + db.floating_ip_create(context.get_admin_context(), + {'address': address, + 'host': FLAGS.host}) + + self.assertRaises(NotImplementedError, + self.network.allocate_floating_ip, + self.context, self.projects[0].id) + + fix_addr = self._create_address(0) + float_addr = address + self.assertRaises(NotImplementedError, + self.network.associate_floating_ip, + self.context, float_addr, fix_addr) + + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, None) + + self.assertRaises(NotImplementedError, + self.network.disassociate_floating_ip, + self.context, float_addr) + + address = db.instance_get_floating_address(context.get_admin_context(), + self.instance_id) + self.assertEqual(address, None) + + self.assertRaises(NotImplementedError, + self.network.deallocate_floating_ip, + self.context, float_addr) + + self.network.deallocate_fixed_ip(self.context, fix_addr) + db.floating_ip_destroy(context.get_admin_context(), float_addr) + + def test_allocate_deallocate_fixed_ip(self): + """Makes sure that we can allocate and deallocate a fixed ip""" + address = self._create_address(0) + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) + self._deallocate_address(0, address) + + # check if the fixed ip address is really deallocated + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) + + def test_side_effects(self): + """Ensures allocating and releasing has no side effects""" + address = self._create_address(0) + address2 = self._create_address(1, self.instance2_id) + + self.assertTrue(self._is_allocated_in_project(address, + self.projects[0].id)) + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[1].id)) + + self._deallocate_address(0, address) + self.assertFalse(self._is_allocated_in_project(address, + self.projects[0].id)) + + # First address release shouldn't affect the second + self.assertTrue(self._is_allocated_in_project(address2, + self.projects[0].id)) + + self._deallocate_address(1, address2) + self.assertFalse(self._is_allocated_in_project(address2, + self.projects[1].id)) + + def test_ips_are_reused(self): + """Makes sure that ip addresses that are deallocated get reused""" + address = self._create_address(0) + self.network.deallocate_fixed_ip(self.context, address) + + address2 = self._create_address(0) + self.assertEqual(address, address2) + + self.network.deallocate_fixed_ip(self.context, address2) + + def test_too_many_addresses(self): + """Test for a NoMoreAddresses exception when all fixed ips are used. + """ + admin_context = context.get_admin_context() + network = db.project_get_network(admin_context, self.projects[0].id) + num_available_ips = db.network_count_available_ips(admin_context, + network['id']) + addresses = [] + instance_ids = [] + for i in range(num_available_ips): + instance_ref = self._create_instance(0) + instance_ids.append(instance_ref['id']) + address = self._create_address(0, instance_ref['id']) + addresses.append(address) + + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, 0) + self.assertRaises(db.NoMoreAddresses, + self.network.allocate_fixed_ip, + self.context, + 'foo') + + for i in range(num_available_ips): + self.network.deallocate_fixed_ip(self.context, addresses[i]) + db.instance_destroy(context.get_admin_context(), instance_ids[i]) + ip_count = db.network_count_available_ips(context.get_admin_context(), + network['id']) + self.assertEqual(ip_count, num_available_ips) + + def run(self, result=None): + if(FLAGS.network_manager == 'nova.network.manager.FlatManager'): + super(FlatNetworkTestCase, self).run(result) -- cgit From a3fe673108602e27cca132209e87369fa8bf1323 Mon Sep 17 00:00:00 2001 From: Tushar Patil Date: Fri, 18 Mar 2011 19:46:04 -0700 Subject: Changed Copyright to NTT for newly added files for flatmanager ipv6 --- .../versions/012_add_ipv6_flatmanager.py | 2 +- nova/tests/network/__init__.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py index 5f5e3d007..8c9cf3377 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py @@ -1,4 +1,4 @@ -# Copyright 2010 OpenStack LLC. +# Copyright (c) 2011 NTT. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may diff --git a/nova/tests/network/__init__.py b/nova/tests/network/__init__.py index e0d479f8c..97f96b6fa 100644 --- a/nova/tests/network/__init__.py +++ b/nova/tests/network/__init__.py @@ -1,3 +1,23 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Utility methods +""" import os from nova import context -- cgit From 0cff0a13bac3539a46b3b932bfd016df7f190196 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Mon, 21 Mar 2011 14:20:13 -0700 Subject: import greenthread in libvirt --- nova/virt/libvirt_conn.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index e80b9fbdf..f57f1a675 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -46,10 +46,9 @@ import time import uuid from xml.dom import minidom - +from eventlet import greenthread from eventlet import tpool from eventlet import semaphore - import IPy from nova import context -- cgit From 4b8ed5afd1fd3e616eda0015f9bf16c7097f5476 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 22 Mar 2011 03:13:12 -0400 Subject: vpn changes --- nova/api/ec2/admin.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index d9a4ef999..208fe5c4f 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -28,6 +28,7 @@ from nova import exception from nova import flags from nova import log as logging from nova import utils +from nova.api.ec2 import ec2utils from nova.auth import manager @@ -92,15 +93,18 @@ def vpn_dict(project, vpn_instance): 'public_ip': project.vpn_ip, 'public_port': project.vpn_port} if vpn_instance: - rv['instance_id'] = vpn_instance['ec2_id'] + rv['instance_id'] = ec2utils.id_to_ec2_id(vpn_instance['id']) rv['created_at'] = utils.isotime(vpn_instance['created_at']) address = vpn_instance.get('fixed_ip', None) if address: rv['internal_ip'] = address['address'] - if utils.vpn_ping(project.vpn_ip, project.vpn_port): - rv['state'] = 'running' + if project.vpn_ip and project.vpn_port: + if utils.vpn_ping(project.vpn_ip, project.vpn_port): + rv['state'] = 'running' + else: + rv['state'] = 'down' else: - rv['state'] = 'down' + rv['state'] = 'down - invalid project vpn config' else: rv['state'] = 'pending' return rv @@ -279,7 +283,7 @@ class AdminController(object): ", ensure it isn't running, and try " "again in a few minutes") instance = self._vpn_for(context, project) - return {'instance_id': instance['ec2_id']} + return {'instance_id': ec2utils.id_to_ec2_id(instance['id'])} def describe_vpns(self, context): vpns = [] -- cgit From d06bce4b64b57551a722688a4038a4eaffa34278 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 22 Mar 2011 16:34:02 -0400 Subject: typo fix. --- nova/api/ec2/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index d9a4ef999..f32d0804f 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -60,7 +60,7 @@ def project_dict(project): def host_dict(host, compute_service, instances, volume_service, volumes, now): """Convert a host model object to a result dict""" - rv = {'hostanme': host, 'instance_count': len(instances), + rv = {'hostname': host, 'instance_count': len(instances), 'volume_count': len(volumes)} if compute_service: latest = compute_service['updated_at'] or compute_service['created_at'] -- cgit From 0dc2140d645d94d585fa8e3e5d189cd776574d28 Mon Sep 17 00:00:00 2001 From: Koji Iida Date: Wed, 23 Mar 2011 13:14:54 +0900 Subject: Fix to avoid db migration failure in virtualenv --- nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py index 8c9cf3377..e87085668 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/012_add_ipv6_flatmanager.py @@ -26,6 +26,9 @@ meta = MetaData() # Just for the ForeignKey and column creation to succeed, these are not the # actual definitions of instances or services. # +instances = Table('instances', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) # # Tables to alter -- cgit From 846b09925da07c2858052143d5fff4766a782cf1 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 22 Mar 2011 22:54:34 -0700 Subject: Fix for lp740742 - format describe_instance_output correctly to prevent errors in dashboard --- nova/api/ec2/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 037184b40..d8d90ad83 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -120,7 +120,8 @@ class AdminController(object): def describe_instance_types(self, context, **_kwargs): """Returns all active instance types data (vcpus, memory, etc.)""" - return {'instanceTypeSet': [db.instance_type_get_all(context)]} + return {'instanceTypeSet': [instance_dict(v) for v in + db.instance_type_get_all(context).values()]} def describe_user(self, _context, name, **_kwargs): """Returns user data, including access and secret keys.""" -- cgit