pig2 发表于 2014-1-3 02:34:24

给horizon添加分配指定floating IP的功能

本帖最后由 pig2 于 2014-1-3 02:58 编辑

适应版本:E使用方法:如下图所示,若要分配指定的floatingIP,可在里输入指定IP;若不要分配指定的floating IP,“IP地址”栏为空,直接点“分配IP”按钮。
修改过程
1./usr/share/pyshared/horizon/dashboards/nova/access_and_security/floating_ips/forms.py:FloatingIpAllocate中添加一个变量address,address从horizon的页面上接受用户输入的floating ip的值;并在api函数中添加该变量。class FloatingIpAllocate(forms.SelfHandlingForm):
    tenant_name = forms.CharField(widget=forms.HiddenInput())
    pool = forms.ChoiceField(label=_("Pool"))
    address = forms.CharField(required=False,label=_("IP Address"))

    def __init__(self, *args, **kwargs):
      super(FloatingIpAllocate, self).__init__(*args, **kwargs)
      floating_pool_list = kwargs.get('initial', {}).get('pool_list', [])
      self.fields['pool'].choices = floating_pool_list
      #self.fields['address'].choices = None

    def handle(self, request, data):
      try:
            fip = api.tenant_floating_ip_allocate(request,
                                                pool=data.get('pool', None),address=data.get('address',None))
            LOG.info('Allocating Floating IP "%s" to project "%s"'
                     % (fip.ip, data['tenant_name']))

            messages.success(request,
                           _('Successfully allocated Floating IP "%(ip)s" '
                               'to project "%(project)s"')
                           % {"ip": fip.ip, "project": data['tenant_name']})
      except:
            exceptions.handle(request, _('Unable to allocate Floating IP.'))
      return shortcuts.redirect(
                        'horizon:nova:access_and_security:index')
2. /usr/share/pyshared/horizon/api/nova.py添加address变量def tenant_floating_ip_allocate(request, pool=None, address=None):
    """Allocates a floating ip to tenant. Optionally you may provide a pool
    for which you would like the IP.
    """
    """
return novaclient(request).floating_ips.create(pool=pool,address=address)
3./usr/share/pyshared/novaclient/v1_1/floating_ips.py:FloatingIPManager.create()
添加address变量    def create(self, pool=None, address=None):
      """
      Create (allocate) afloating ip for a tenant
      """
      return self._create("/os-floating-ips", {'pool': pool,'address':address}, "floating_ip")
4./usr/share/pyshared/nova/api/openstack/compute/contrib/floating_ips.py:FloatIPController.create()添加address变量 def create(self, req, body=None):
      context = req.environ['nova.context']
      authorize(context)

      pool = None
      address_your= None
      if body and 'pool' in body:
            pool = body['pool']
      if body and 'address' in body:
            address_your = body['address']
      LOG.debug(_('ozg.debug xxxxxxxxxxxxxxxxx address = %s'), address_your)

      try:
            address = self.network_api.allocate_floating_ip(context, pool, address_your)
            ip = self.network_api.get_floating_ip_by_address(context, address)
      except rpc_common.RemoteError as ex:
            # NOTE(tr3buchet) - why does this block exist?
            if ex.exc_type == 'NoMoreFloatingIps':
                if pool:
                  msg = _("No more floating ips in pool %s.") % pool
                else:
                  msg = _("No more floating ips available.")
                raise webob.exc.HTTPBadRequest(explanation=msg)
            else:
                raise

      return _translate_floating_ip_view(ip)
5. /usr/share/pyshared/nova/network/api.py.allocate_floating_ip()添加address变量
    def allocate_floating_ip(self, context, pool=None, address_your=None):
      """Adds a floating ip to a project from a pool. (allocates)"""
      # NOTE(vish): We don't know which network host should get the ip
      #             when we allocate, so just send it to any one.This
      #             will probably need to move into a network supervisor
      #             at some point.
      # ozg
      LOG.debug(_("ozg.debug xxxxxxx rpc.call!!!"))
      return rpc.call(context,
                        FLAGS.network_topic,
                        {'method': 'allocate_floating_ip',
                         'args': {'project_id': context.project_id,
                                  'pool': pool,
                                  'address_your': address_your}})


6. /usr/share/pyshared/nova/network/manager.py.allocate_floating_ip()添加address变量
@wrap_check_policy
    def allocate_floating_ip(self, context, project_id, pool=None, address_your=None):
      """Gets a floating ip from the pool."""
      # NOTE(tr3buchet): all network hosts in zone now use the same pool
      LOG.debug("QUOTA: %s" % quota.allowed_floating_ips(context, 1))
      if quota.allowed_floating_ips(context, 1) < 1:
            LOG.warn(_('Quota exceeded for %s, tried to allocate address'),
                     context.project_id)
            raise exception.QuotaError(code='AddressLimitExceeded')
      pool = pool or FLAGS.default_floating_pool
      LOG.debug(_('ozg.debug network manager accept the messages xxxxxxxxxxxxx, address_your = %s'), address_your)
      return self.db.floating_ip_allocate_address(context,
                                                    project_id,
                                                    pool,
                                                    address_your)




7. /usr/share/pyshared/nova/db/api.py. floating_ip_allocate_address()添加address变量

def floating_ip_allocate_address (context, project_id, pool, address_your=None):
    """Allocate free floating ip from specified pool and return the address.

    Raises if one is not available.
    ozg add address_your

    """
return IMPL.floating_ip_allocate_address(context, project_id, pool, address_your)




8./usr/share/pyshared/nova/db/sqlalchemy/api.py将floating_ip_allocate_address函数改为如下:@require_context
def floating_ip_allocate_address(context, project_id, pool, address_your):
    authorize_project_context(context, project_id)
    session = get_session()
    LOG.debug(_("ozg.debug xxxxxxx db.sql... address_your = %s"), address_your)

    with session.begin():
      if not address_your:
            floating_ip_ref = model_query(context, models.FloatingIp,
                                          session=session, read_deleted="no").\
                                    filter_by(fixed_ip_id=None).\
                                    filter_by(project_id=None).\
                                    filter_by(pool=pool).\
                                    with_lockmode('update').\
                                    first()

      else:
            floating_ip_ref = model_query(context, models.FloatingIp,
                                          session=session, read_deleted="no").\
                                    filter_by(fixed_ip_id=None).\
                                    filter_by(project_id=None).\
                                    filter_by(pool=pool).\
                                    filter_by(address=address_your).\
                                    with_lockmode('update').\
                                    first()
      # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
      #             then this has concurrency issues
      if not floating_ip_ref:
            raise exception.NoMoreFloatingIps()
      floating_ip_ref['project_id'] = project_id
      session.add(floating_ip_ref)

    return floating_ip_ref['address']
页: [1]
查看完整版本: 给horizon添加分配指定floating IP的功能