summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorEldar Nugaev <enugaev@griddynamics.com>2011-04-22 06:46:28 +0000
committerTarmac <>2011-04-22 06:46:28 +0000
commitfdab470f28a2cb8ef0c4d174241e5a6dc362a21d (patch)
treeae40fd91c27313fcd31ab4d040ae0a3edd55d679 /nova
parentc028a791c8434a3c58ff1c7e0cd02b2f9f5b8417 (diff)
parent5904cba617038600f3d8e7f65c71485abb163927 (diff)
Provide option of auto assigning floating ip to each instance. Depend on auto_assign_floating_ip boolean flag value. False by default.
Diffstat (limited to 'nova')
-rw-r--r--nova/compute/manager.py36
-rw-r--r--nova/db/api.py5
-rw-r--r--nova/db/sqlalchemy/api.py14
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py39
-rw-r--r--nova/db/sqlalchemy/models.py1
-rw-r--r--nova/network/api.py15
6 files changed, 98 insertions, 12 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 86a9e87b0..307e0a2ff 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -37,8 +37,6 @@ terminating it.
import datetime
import os
-import random
-import string
import socket
import sys
import tempfile
@@ -50,6 +48,7 @@ from nova import exception
from nova import flags
from nova import log as logging
from nova import manager
+from nova import network
from nova import rpc
from nova import utils
from nova import volume
@@ -75,6 +74,8 @@ flags.DEFINE_integer('live_migration_retry_count', 30,
flags.DEFINE_integer("rescue_timeout", 0,
"Automatically unrescue an instance after N seconds."
" Set to 0 to disable.")
+flags.DEFINE_bool('auto_assign_floating_ip', False,
+ 'Autoassigning floating ip to VM')
LOG = logging.getLogger('nova.compute.manager')
@@ -128,6 +129,7 @@ class ComputeManager(manager.SchedulerDependentManager):
self.network_manager = utils.import_object(FLAGS.network_manager)
self.volume_manager = utils.import_object(FLAGS.volume_manager)
+ self.network_api = network.API()
super(ComputeManager, self).__init__(service_name="compute",
*args, **kwargs)
@@ -248,6 +250,18 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_id,
power_state.SHUTDOWN)
+ if not FLAGS.stub_network and FLAGS.auto_assign_floating_ip:
+ public_ip = self.network_api.allocate_floating_ip(context)
+
+ self.db.floating_ip_set_auto_assigned(context, public_ip)
+ fixed_ip = self.db.fixed_ip_get_by_address(context, address)
+ floating_ip = self.db.floating_ip_get_by_address(context,
+ public_ip)
+
+ self.network_api.associate_floating_ip(context,
+ floating_ip,
+ fixed_ip,
+ affect_auto_assigned=True)
self._update_state(context, instance_id)
@exception.wrap_exception
@@ -268,13 +282,17 @@ class ComputeManager(manager.SchedulerDependentManager):
# NOTE(vish): Right now we don't really care if the ip is
# disassociated. We may need to worry about
# checking this later.
- network_topic = self.db.queue_get_for(context,
- FLAGS.network_topic,
- floating_ip['host'])
- rpc.cast(context,
- network_topic,
- {"method": "disassociate_floating_ip",
- "args": {"floating_address": address}})
+ self.network_api.disassociate_floating_ip(context,
+ address,
+ True)
+ if (FLAGS.auto_assign_floating_ip
+ and floating_ip.get('auto_assigned')):
+ LOG.debug(_("Deallocating floating ip %s"),
+ floating_ip['address'],
+ context=context)
+ self.network_api.release_floating_ip(context,
+ address,
+ True)
address = fixed_ip['address']
if address:
diff --git a/nova/db/api.py b/nova/db/api.py
index b0c4a31f6..f9a4b5b4b 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -292,8 +292,13 @@ def floating_ip_update(context, address, values):
return IMPL.floating_ip_update(context, address, values)
+def floating_ip_set_auto_assigned(context, address):
+ """Set auto_assigned flag to floating ip"""
+ return IMPL.floating_ip_set_auto_assigned(context, address)
+
####################
+
def migration_update(context, id, values):
"""Update a migration instance."""
return IMPL.migration_update(context, id, values)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index fb9258238..3150e330e 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -461,6 +461,7 @@ def floating_ip_count_by_project(context, project_id):
session = get_session()
return session.query(models.FloatingIp).\
filter_by(project_id=project_id).\
+ filter_by(auto_assigned=False).\
filter_by(deleted=False).\
count()
@@ -489,6 +490,7 @@ def floating_ip_deallocate(context, address):
address,
session=session)
floating_ip_ref['project_id'] = None
+ floating_ip_ref['auto_assigned'] = False
floating_ip_ref.save(session=session)
@@ -522,6 +524,17 @@ def floating_ip_disassociate(context, address):
return fixed_ip_address
+@require_context
+def floating_ip_set_auto_assigned(context, address):
+ session = get_session()
+ with session.begin():
+ floating_ip_ref = floating_ip_get_by_address(context,
+ address,
+ session=session)
+ floating_ip_ref.auto_assigned = True
+ floating_ip_ref.save(session=session)
+
+
@require_admin_context
def floating_ip_get_all(context):
session = get_session()
@@ -548,6 +561,7 @@ def floating_ip_get_all_by_project(context, project_id):
return session.query(models.FloatingIp).\
options(joinedload_all('fixed_ip.instance')).\
filter_by(project_id=project_id).\
+ filter_by(auto_assigned=False).\
filter_by(deleted=False).\
all()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py
new file mode 100644
index 000000000..29b26b3dd
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/015_add_auto_assign_to_floating_ips.py
@@ -0,0 +1,39 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# Copyright 2011 Grid Dynamics
+#
+# 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 sqlalchemy.sql import text
+from migrate import *
+
+
+meta = MetaData()
+
+
+c_auto_assigned = Column('auto_assigned', Boolean, default=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
+
+ floating_ips = Table('floating_ips',
+ meta,
+ autoload=True,
+ autoload_with=migrate_engine)
+
+ floating_ips.create_column(c_auto_assigned)
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index f79d0f16c..36a084a1d 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -592,6 +592,7 @@ class FloatingIp(BASE, NovaBase):
'FloatingIp.deleted == False)')
project_id = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
+ auto_assigned = Column(Boolean, default=False, nullable=False)
class ConsolePool(BASE, NovaBase):
diff --git a/nova/network/api.py b/nova/network/api.py
index c56e3062b..1d8193b28 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -51,8 +51,11 @@ class API(base.Base):
{"method": "allocate_floating_ip",
"args": {"project_id": context.project_id}})
- def release_floating_ip(self, context, address):
+ def release_floating_ip(self, context, address,
+ affect_auto_assigned=False):
floating_ip = self.db.floating_ip_get_by_address(context, address)
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ return
# NOTE(vish): We don't know which network host should get the ip
# when we deallocate, so just send it to any one. This
# will probably need to move into a network supervisor
@@ -62,10 +65,13 @@ class API(base.Base):
{"method": "deallocate_floating_ip",
"args": {"floating_address": floating_ip['address']}})
- def associate_floating_ip(self, context, floating_ip, fixed_ip):
+ def associate_floating_ip(self, context, floating_ip, fixed_ip,
+ affect_auto_assigned=False):
if isinstance(fixed_ip, str) or isinstance(fixed_ip, unicode):
fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip)
floating_ip = self.db.floating_ip_get_by_address(context, floating_ip)
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ return
# Check if the floating ip address is allocated
if floating_ip['project_id'] is None:
raise exception.ApiError(_("Address (%s) is not allocated") %
@@ -90,8 +96,11 @@ class API(base.Base):
"args": {"floating_address": floating_ip['address'],
"fixed_address": fixed_ip['address']}})
- def disassociate_floating_ip(self, context, address):
+ def disassociate_floating_ip(self, context, address,
+ affect_auto_assigned=False):
floating_ip = self.db.floating_ip_get_by_address(context, address)
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ return
if not floating_ip.get('fixed_ip'):
raise exception.ApiError('Address is not associated.')
# NOTE(vish): Get the topic from the host name of the network of