Provide option of auto assigning floating ip to each instance. Depend on auto_assign_floating_ip boolean flag value. False by default.

This commit is contained in:
Eldar Nugaev 2011-04-22 06:46:28 +00:00 committed by Tarmac
commit fdab470f28
6 changed files with 98 additions and 12 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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):

View File

@ -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