summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-05-11 15:12:12 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-05-11 15:12:12 +0000
commit43fa5afac9e5af74e2e3977a5dafd9640d064cf1 (patch)
treeac8daf40051e4c97fc3445ad54f9478d423c3bfe /nova
parent21f18f77e7d729107742fa9157b531ce56f3272a (diff)
Abstract out IPv6 address generation to pluggable backends
Diffstat (limited to 'nova')
-rw-r--r--nova/api/ec2/cloud.py3
-rw-r--r--nova/db/sqlalchemy/api.py5
-rw-r--r--nova/ipv6/__init__.py17
-rw-r--r--nova/ipv6/api.py34
-rw-r--r--nova/ipv6/rfc2462.py42
-rw-r--r--nova/tests/network/base.py8
-rw-r--r--nova/utils.py20
-rw-r--r--nova/virt/libvirt_conn.py3
-rw-r--r--nova/virt/xenapi/vmops.py3
9 files changed, 106 insertions, 29 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 092b80fa2..993c91fe1 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -39,6 +39,7 @@ from nova import log as logging
from nova import network
from nova import utils
from nova import volume
+from nova import ipv6
from nova.api.ec2 import ec2utils
from nova.compute import instance_types
from nova.image import s3
@@ -718,7 +719,7 @@ 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(
+ i['dnsNameV6'] = ipv6.to_global(
instance['fixed_ip']['network']['cidr_v6'],
instance['mac_address'])
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 285b22a04..6c76248ce 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -26,6 +26,7 @@ from nova import db
from nova import exception
from nova import flags
from nova import utils
+from nova import ipv6
from nova.db.sqlalchemy import models
from nova.db.sqlalchemy.session import get_session
from sqlalchemy import or_
@@ -744,7 +745,7 @@ def fixed_ip_get_all_by_instance(context, instance_id):
@require_context
def fixed_ip_get_instance_v6(context, address):
session = get_session()
- mac = utils.to_mac(address)
+ mac = ipv6.to_mac(address)
result = session.query(models.Instance).\
filter_by(mac_address=mac).\
@@ -974,7 +975,7 @@ def instance_get_fixed_address_v6(context, instance_id):
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)
+ return ipv6.to_global(prefix, mac)
@require_context
diff --git a/nova/ipv6/__init__.py b/nova/ipv6/__init__.py
new file mode 100644
index 000000000..da4567cfb
--- /dev/null
+++ b/nova/ipv6/__init__.py
@@ -0,0 +1,17 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 Openstack, LLC.
+#
+# 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 nova.ipv6.api import *
diff --git a/nova/ipv6/api.py b/nova/ipv6/api.py
new file mode 100644
index 000000000..95b20c945
--- /dev/null
+++ b/nova/ipv6/api.py
@@ -0,0 +1,34 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 Openstack, LLC.
+#
+# 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 nova import flags
+from nova import utils
+
+
+FLAGS = flags.FLAGS
+flags.DEFINE_string('ipv6_backend',
+ 'rfc2462',
+ 'Backend to use for IPv6 generation')
+
+IMPL = utils.LazyPluggable(FLAGS['ipv6_backend'],
+ rfc2462='nova.ipv6.rfc2462')
+
+
+def to_global(prefix, mac):
+ return IMPL.to_global(prefix, mac)
+
+def to_mac(ipv6_address):
+ return IMPL.to_mac(ipv6_address)
diff --git a/nova/ipv6/rfc2462.py b/nova/ipv6/rfc2462.py
new file mode 100644
index 000000000..3af4556e7
--- /dev/null
+++ b/nova/ipv6/rfc2462.py
@@ -0,0 +1,42 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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.
+
+"""RFC2462 style IPv6 address generation"""
+
+import netaddr
+
+
+def to_global(prefix, mac):
+ try:
+ mac64 = netaddr.EUI(mac).eui64().words
+ int_addr = int(''.join(['%02x' % i for i in mac64]), 16)
+ mac64_addr = netaddr.IPAddress(int_addr)
+ maskIP = netaddr.IPNetwork(prefix).ip
+ return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).\
+ format()
+ except TypeError:
+ raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac)
+
+
+def to_mac(ipv6_address):
+ address = netaddr.IPAddress(ipv6_address)
+ mask1 = netaddr.IPAddress('::ffff:ffff:ffff:ffff')
+ mask2 = netaddr.IPAddress('::0200:0:0:0')
+ mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words
+ return ':'.join(['%02x' % i for i in mac64[0:3] + mac64[5:8]])
diff --git a/nova/tests/network/base.py b/nova/tests/network/base.py
index 988a1de72..5de1255cd 100644
--- a/nova/tests/network/base.py
+++ b/nova/tests/network/base.py
@@ -28,6 +28,7 @@ from nova import flags
from nova import log as logging
from nova import test
from nova import utils
+from nova import ipv6
from nova.auth import manager
FLAGS = flags.FLAGS
@@ -117,15 +118,14 @@ class NetworkTestCase(test.TestCase):
context.get_admin_context(),
instance_ref['id'])
self.assertEqual(instance_ref['mac_address'],
- utils.to_mac(address_v6))
+ ipv6.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']))
+ ipv6.to_global(network_ref['cidr_v6'],
+ instance_ref['mac_address']))
self._deallocate_address(0, address)
db.instance_destroy(context.get_admin_context(),
instance_ref['id'])
diff --git a/nova/utils.py b/nova/utils.py
index 80bf1197f..aa77caf71 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -303,26 +303,6 @@ def get_my_linklocal(interface):
" :%(ex)s") % locals())
-def to_global_ipv6(prefix, mac):
- try:
- mac64 = netaddr.EUI(mac).eui64().words
- int_addr = int(''.join(['%02x' % i for i in mac64]), 16)
- mac64_addr = netaddr.IPAddress(int_addr)
- maskIP = netaddr.IPNetwork(prefix).ip
- return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).\
- format()
- except TypeError:
- raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac)
-
-
-def to_mac(ipv6_address):
- address = netaddr.IPAddress(ipv6_address)
- mask1 = netaddr.IPAddress('::ffff:ffff:ffff:ffff')
- mask2 = netaddr.IPAddress('::0200:0:0:0')
- mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words
- return ':'.join(['%02x' % i for i in mac64[0:3] + mac64[5:8]])
-
-
def utcnow():
"""Overridable version of datetime.datetime.utcnow."""
if utcnow.override_time:
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 9780c69a6..4dce3b41f 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -60,6 +60,7 @@ from nova import flags
from nova import log as logging
from nova import utils
from nova import vnc
+from nova import ipv6
from nova.auth import manager
from nova.compute import instance_types
from nova.compute import power_state
@@ -185,7 +186,7 @@ def _get_network_info(instance):
prefix = network['cidr_v6']
mac = instance['mac_address']
return {
- 'ip': utils.to_global_ipv6(prefix, mac),
+ 'ip': ipv6.to_global(prefix, mac),
'netmask': network['netmask_v6'],
'enabled': '1'}
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index fe9a74dd6..0b05e702a 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -34,6 +34,7 @@ from nova import log as logging
from nova import exception
from nova import utils
from nova import flags
+from nova import ipv6
from nova.auth.manager import AuthManager
from nova.compute import power_state
@@ -808,7 +809,7 @@ class VMOps(object):
def ip6_dict():
return {
- "ip": utils.to_global_ipv6(network['cidr_v6'],
+ "ip": ipv6.to_global(network['cidr_v6'],
instance['mac_address']),
"netmask": network['netmask_v6'],
"enabled": "1"}