Implemented get and get all methods for floating IPs
This commit is contained in:
@@ -323,6 +323,12 @@ def ip_address_find(context, lock_mode=False, **filters):
|
|||||||
return query.filter(*model_filters)
|
return query.filter(*model_filters)
|
||||||
|
|
||||||
|
|
||||||
|
def ip_address_count_all(context, **filters):
|
||||||
|
query = context.session.query(sql_func.count(models.IPAddress.id))
|
||||||
|
model_filters = _model_query(context, models.IPAddress, filters)
|
||||||
|
return query.filter(*model_filters).scalar()
|
||||||
|
|
||||||
|
|
||||||
@scoped
|
@scoped
|
||||||
def ip_address_reallocate(context, update_kwargs, **filters):
|
def ip_address_reallocate(context, update_kwargs, **filters):
|
||||||
LOG.debug("ip_address_reallocate %s", filters)
|
LOG.debug("ip_address_reallocate %s", filters)
|
||||||
@@ -830,3 +836,29 @@ def transaction_create(context):
|
|||||||
transaction = models.Transaction()
|
transaction = models.Transaction()
|
||||||
context.session.add(transaction)
|
context.session.add(transaction)
|
||||||
return transaction
|
return transaction
|
||||||
|
|
||||||
|
|
||||||
|
@scoped
|
||||||
|
def floating_ip_find(context, lock_mode=False, limit=None, sorts=None,
|
||||||
|
marker=None, page_reverse=False, fields=None, **filters):
|
||||||
|
query = context.session.query(models.IPAddress)
|
||||||
|
|
||||||
|
if lock_mode:
|
||||||
|
query = query.with_lockmode("update")
|
||||||
|
|
||||||
|
model_filters = _model_query(context, models.IPAddress, filters)
|
||||||
|
|
||||||
|
if filters.get("port_id"):
|
||||||
|
model_filters.append(models.IPAddress.ports.any(
|
||||||
|
models.Port.id == filters['port_id']))
|
||||||
|
|
||||||
|
if filters.get("address_type"):
|
||||||
|
model_filters.append(
|
||||||
|
models.IPAddress.address_type == filters['address_type'])
|
||||||
|
|
||||||
|
if filters.get("transaction_id"):
|
||||||
|
model_filters.append(
|
||||||
|
models.IPAddress.transaction_id == filters['transaction_id'])
|
||||||
|
|
||||||
|
return paginate_query(query.filter(*model_filters), models.IPAddress,
|
||||||
|
limit, sorts, marker)
|
||||||
|
|||||||
@@ -133,3 +133,7 @@ class RedisSlaveWritesForbidden(exceptions.NeutronException):
|
|||||||
class NoBackendConnectionsDefined(exceptions.NeutronException):
|
class NoBackendConnectionsDefined(exceptions.NeutronException):
|
||||||
message = _("This driver cannot be used without a backend connection "
|
message = _("This driver cannot be used without a backend connection "
|
||||||
"definition. %(msg)")
|
"definition. %(msg)")
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIpNotFound(exceptions.NeutronException):
|
||||||
|
message = _("Floating IP %(id)s not found.")
|
||||||
|
|||||||
@@ -25,11 +25,13 @@ from oslo_log import log as logging
|
|||||||
|
|
||||||
from quark.api import extensions
|
from quark.api import extensions
|
||||||
from quark import ip_availability
|
from quark import ip_availability
|
||||||
|
from quark.plugin_modules import floating_ips
|
||||||
from quark.plugin_modules import ip_addresses
|
from quark.plugin_modules import ip_addresses
|
||||||
from quark.plugin_modules import ip_policies
|
from quark.plugin_modules import ip_policies
|
||||||
from quark.plugin_modules import mac_address_ranges
|
from quark.plugin_modules import mac_address_ranges
|
||||||
from quark.plugin_modules import networks
|
from quark.plugin_modules import networks
|
||||||
from quark.plugin_modules import ports
|
from quark.plugin_modules import ports
|
||||||
|
from quark.plugin_modules import router
|
||||||
from quark.plugin_modules import routes
|
from quark.plugin_modules import routes
|
||||||
from quark.plugin_modules import security_groups
|
from quark.plugin_modules import security_groups
|
||||||
from quark.plugin_modules import subnets
|
from quark.plugin_modules import subnets
|
||||||
@@ -359,49 +361,60 @@ class Plugin(neutron_plugin_base_v2.NeutronPluginBaseV2,
|
|||||||
# they're extensions in Neutron, Nova still expects to be
|
# they're extensions in Neutron, Nova still expects to be
|
||||||
# able to call some of these as if they aren't
|
# able to call some of these as if they aren't
|
||||||
def create_router(self, context, router):
|
def create_router(self, context, router):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
def update_router(self, context, id, router):
|
def update_router(self, context, id, router):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_router(self, context, id, fields=None):
|
def get_router(self, context, id, fields=None):
|
||||||
pass
|
return router.get_router(context, id, fields)
|
||||||
|
|
||||||
def delete_router(self, context, id):
|
def delete_router(self, context, id):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_routers(self, context, filters=None, fields=None,
|
def get_routers(self, context, filters=None, fields=None,
|
||||||
sorts=None, limit=None, marker=None, page_reverse=False):
|
sorts=None, limit=None, marker=None, page_reverse=False):
|
||||||
pass
|
return router.get_routers(context, filters=filters, fields=fields,
|
||||||
|
sorts=sorts, limit=limit, marker=marker,
|
||||||
|
page_reverse=page_reverse)
|
||||||
|
|
||||||
def add_router_interface(self, context, router_id, interface_info):
|
def add_router_interface(self, context, router_id, interface_info):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
def remove_router_interface(self, context, router_id, interface_info):
|
def remove_router_interface(self, context, router_id, interface_info):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def create_floatingip(self, context, floatingip):
|
def create_floatingip(self, context, floatingip):
|
||||||
pass
|
return floating_ips.create_floatingip(context, floatingip)
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def update_floatingip(self, context, id, floatingip):
|
def update_floatingip(self, context, id, floatingip):
|
||||||
pass
|
return floating_ips.update_floatingip(context, id, floatingip)
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def get_floatingip(self, context, id, fields=None):
|
def get_floatingip(self, context, id, fields=None):
|
||||||
return None
|
return floating_ips.get_floatingip(context, id, fields)
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def delete_floatingip(self, context, id):
|
def delete_floatingip(self, context, id):
|
||||||
pass
|
return floating_ips.delete_floatingip(context, id)
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def get_floatingips(self, context, filters=None, fields=None,
|
def get_floatingips(self, context, filters=None, fields=None,
|
||||||
sorts=None, limit=None, marker=None,
|
sorts=None, limit=None, marker=None,
|
||||||
page_reverse=False):
|
page_reverse=False):
|
||||||
return []
|
return floating_ips.get_floatingips(context, filters=filters,
|
||||||
|
fields=fields, sorts=sorts,
|
||||||
|
limit=limit, marker=marker,
|
||||||
|
page_reverse=page_reverse)
|
||||||
|
|
||||||
def get_routers_count(self, context, filters=None):
|
def get_routers_count(self, context, filters=None):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@sessioned
|
||||||
def get_floatingips_count(self, context, filters=None):
|
def get_floatingips_count(self, context, filters=None):
|
||||||
raise NotImplementedError()
|
raise floating_ips.get_floatingips_count(context, filters)
|
||||||
|
|
||||||
def get_ip_availability(self, **kwargs):
|
def get_ip_availability(self, **kwargs):
|
||||||
return ip_availability.get_ip_availability(**kwargs)
|
return ip_availability.get_ip_availability(**kwargs)
|
||||||
|
|||||||
164
quark/plugin_modules/floating_ips.py
Normal file
164
quark/plugin_modules/floating_ips.py
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
# Copyright 2013 Openstack Foundation
|
||||||
|
# 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 oslo.config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from quark.db import api as db_api
|
||||||
|
from quark.db import ip_types
|
||||||
|
from quark import exceptions as quark_exceptions
|
||||||
|
from quark import plugin_views as v
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
quark_router_opts = [
|
||||||
|
cfg.StrOpt('floating_ip_base_url',
|
||||||
|
default='http://localhost/',
|
||||||
|
help=_('floating ips base url'))
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF.register_opts(quark_router_opts, "QUARK")
|
||||||
|
|
||||||
|
|
||||||
|
def create_floatingip(context, body):
|
||||||
|
LOG.info("create_floatingip %s for tenant %s and body %s" %
|
||||||
|
(id, context.tenant_id, body))
|
||||||
|
|
||||||
|
# floating_ip_dict = body.get("ip_address")
|
||||||
|
# tenant_id = floating_ip_dict.get("tenant_id")
|
||||||
|
# network_id = floating_ip_dict.get("floating_network_id")
|
||||||
|
# # fixed_ip_address = floating_ip_dict.get("fixed_ip_address")
|
||||||
|
# # ip_address = floating_ip_dict.get("floating_ip_address")
|
||||||
|
# port_id = floating_ip_dict.get("port_id")
|
||||||
|
#
|
||||||
|
# if not tenant_id:
|
||||||
|
# raise exceptions.BadRequest(resource="floating_ip",
|
||||||
|
# msg="tenant_id is required.")
|
||||||
|
# if not network_id:
|
||||||
|
# raise exceptions.BadRequest(resource="floating_ip",
|
||||||
|
# msg="floating_network_id is required.")
|
||||||
|
# if not port_id:
|
||||||
|
# raise exceptions.BadRequest(resource="floating_ip",
|
||||||
|
# msg="port_id is required.")
|
||||||
|
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def update_floatingip(context, id, body):
|
||||||
|
LOG.info("update_floatingip %s for tenant %s and body %s" %
|
||||||
|
(id, context.tenant_id, body))
|
||||||
|
|
||||||
|
# floating_ip_dict = body.get("ip_address")
|
||||||
|
#
|
||||||
|
# if "port_id" not in floating_ip_dict:
|
||||||
|
# raise exceptions.BadRequest(resource="floating_ip",
|
||||||
|
# msg="port_id is required.")
|
||||||
|
|
||||||
|
# port_id = floating_ip_dict.get("port_id")
|
||||||
|
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def delete_floatingip(context, id):
|
||||||
|
LOG.info("delete_floatingip %s for tenant %s" % (id, context.tenant_id))
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def get_floatingip(context, id, fields=None):
|
||||||
|
"""Retrieve a floating IP.
|
||||||
|
|
||||||
|
:param context: neutron api request context.
|
||||||
|
:param id: The UUID of the floating IP.
|
||||||
|
:param fields: a list of strings that are valid keys in a
|
||||||
|
floating IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
|
||||||
|
object in neutron/api/v2/attributes.py. Only these fields
|
||||||
|
will be returned.
|
||||||
|
|
||||||
|
:returns: Dictionary containing details for the floating IP. If values
|
||||||
|
are declared in the fields parameter, then only those keys will be
|
||||||
|
present.
|
||||||
|
"""
|
||||||
|
LOG.info("get_floatingip %s for tenant %s" % (id, context.tenant_id))
|
||||||
|
|
||||||
|
filters = {"address_type": ip_types.FLOATING}
|
||||||
|
|
||||||
|
addr = db_api.floating_ip_find(context, id=id, scope=db_api.ONE, **filters)
|
||||||
|
|
||||||
|
if not addr:
|
||||||
|
raise quark_exceptions.FloatingIpNotFound(id=id)
|
||||||
|
|
||||||
|
return v._make_floating_ip_dict(addr)
|
||||||
|
|
||||||
|
|
||||||
|
def get_floatingips(context, filters=None, fields=None, sorts=None, limit=None,
|
||||||
|
marker=None, page_reverse=False):
|
||||||
|
"""Retrieve a list of floating ips.
|
||||||
|
|
||||||
|
:param context: neutron api request context.
|
||||||
|
:param filters: a dictionary with keys that are valid keys for
|
||||||
|
a floating ip as listed in the RESOURCE_ATTRIBUTE_MAP object
|
||||||
|
in neutron/api/v2/attributes.py. Values in this dictionary
|
||||||
|
are an iterable containing values that will be used for an exact
|
||||||
|
match comparison for that value. Each result returned by this
|
||||||
|
function will have matched one of the values for each key in
|
||||||
|
filters.
|
||||||
|
:param fields: a list of strings that are valid keys in a
|
||||||
|
floating IP dictionary as listed in the RESOURCE_ATTRIBUTE_MAP
|
||||||
|
object in neutron/api/v2/attributes.py. Only these fields
|
||||||
|
will be returned.
|
||||||
|
|
||||||
|
:returns: List of floating IPs that are accessible to the tenant who
|
||||||
|
submits the request (as indicated by the tenant id of the context)
|
||||||
|
as well as any filters.
|
||||||
|
"""
|
||||||
|
LOG.info("get_floatingips for tenant %s filters %s fields %s" %
|
||||||
|
(context.tenant_id, filters, fields))
|
||||||
|
|
||||||
|
if filters is None:
|
||||||
|
filters = {}
|
||||||
|
|
||||||
|
filters["_deallocated"] = False
|
||||||
|
filters["address_type"] = ip_types.FLOATING
|
||||||
|
|
||||||
|
addrs = db_api.floating_ip_find(context, scope=db_api.ALL, **filters)
|
||||||
|
|
||||||
|
return [v._make_floating_ip_dict(ip) for ip in addrs]
|
||||||
|
|
||||||
|
|
||||||
|
def get_floatingips_count(context, filters=None):
|
||||||
|
"""Return the number of floating IPs.
|
||||||
|
|
||||||
|
:param context: neutron api request context
|
||||||
|
:param filters: a dictionary with keys that are valid keys for
|
||||||
|
a floating IP as listed in the RESOURCE_ATTRIBUTE_MAP object
|
||||||
|
in neutron/api/v2/attributes.py. Values in this dictionary
|
||||||
|
are an iterable containing values that will be used for an exact
|
||||||
|
match comparison for that value. Each result returned by this
|
||||||
|
function will have matched one of the values for each key in
|
||||||
|
filters.
|
||||||
|
|
||||||
|
:returns: The number of floating IPs that are accessible to the tenant who
|
||||||
|
submits the request (as indicated by the tenant id of the context)
|
||||||
|
as well as any filters.
|
||||||
|
|
||||||
|
NOTE: this method is optional, as it was not part of the originally
|
||||||
|
defined plugin API.
|
||||||
|
"""
|
||||||
|
LOG.info("get_floatingips_count for tenant %s filters" %
|
||||||
|
(context.tenant_id, filters))
|
||||||
|
|
||||||
|
raise NotImplementedError()
|
||||||
@@ -434,7 +434,7 @@ def get_ports(context, limit=None, sorts=None, marker=None, page_reverse=False,
|
|||||||
: param context: neutron api request context
|
: param context: neutron api request context
|
||||||
: param filters: a dictionary with keys that are valid keys for
|
: param filters: a dictionary with keys that are valid keys for
|
||||||
a port as listed in the RESOURCE_ATTRIBUTE_MAP object
|
a port as listed in the RESOURCE_ATTRIBUTE_MAP object
|
||||||
in neutron/api/v2/attributes.py. Values in this dictiontary
|
in neutron/api/v2/attributes.py. Values in this dictionary
|
||||||
are an iterable containing values that will be used for an exact
|
are an iterable containing values that will be used for an exact
|
||||||
match comparison for that value. Each result returned by this
|
match comparison for that value. Each result returned by this
|
||||||
function will have matched one of the values for each key in
|
function will have matched one of the values for each key in
|
||||||
@@ -472,8 +472,8 @@ def get_ports_count(context, filters=None):
|
|||||||
(as indicated by the context) as well as any filters.
|
(as indicated by the context) as well as any filters.
|
||||||
: param context: neutron api request context
|
: param context: neutron api request context
|
||||||
: param filters: a dictionary with keys that are valid keys for
|
: param filters: a dictionary with keys that are valid keys for
|
||||||
a network as listed in the RESOURCE_ATTRIBUTE_MAP object
|
a port as listed in the RESOURCE_ATTRIBUTE_MAP object
|
||||||
in neutron/api/v2/attributes.py. Values in this dictiontary
|
in neutron/api/v2/attributes.py. Values in this dictionary
|
||||||
are an iterable containing values that will be used for an exact
|
are an iterable containing values that will be used for an exact
|
||||||
match comparison for that value. Each result returned by this
|
match comparison for that value. Each result returned by this
|
||||||
function will have matched one of the values for each key in
|
function will have matched one of the values for each key in
|
||||||
|
|||||||
52
quark/plugin_modules/router.py
Normal file
52
quark/plugin_modules/router.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Copyright 2013 Openstack Foundation
|
||||||
|
# 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 oslo.config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
quark_router_opts = [
|
||||||
|
cfg.StrOpt('floating_ip_router_id',
|
||||||
|
default='00000000-0000-0000-0000-000000000000',
|
||||||
|
help=_('floating ips default public router id'))
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF.register_opts(quark_router_opts, "QUARK")
|
||||||
|
|
||||||
|
|
||||||
|
def get_router(context, id, fields):
|
||||||
|
LOG.info("get_router for %s for tenant %s fields %s" %
|
||||||
|
(context.tenant_id, fields))
|
||||||
|
if id != CONF.QUARK.floating_ip_router_id:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return _get_floating_ip_default_router(context.tenant_id)
|
||||||
|
|
||||||
|
|
||||||
|
def get_routers(context, filters=None, fields=None, sorts=None, limit=None,
|
||||||
|
marker=None, page_reverse=False):
|
||||||
|
LOG.info("get_routers for tenant %s filters %s fields %s" %
|
||||||
|
(context.tenant_id, filters, fields))
|
||||||
|
return [_get_floating_ip_default_router(context.tenant_id)]
|
||||||
|
|
||||||
|
|
||||||
|
def _get_floating_ip_default_router(tenant_id):
|
||||||
|
return {"id": CONF.QUARK.floating_ip_router_id,
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"name": "Floating IP Public Router",
|
||||||
|
"admin_state_up": True}
|
||||||
@@ -21,6 +21,7 @@ import netaddr
|
|||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from quark.db import ip_types
|
||||||
from quark import network_strategy
|
from quark import network_strategy
|
||||||
from quark import protocols
|
from quark import protocols
|
||||||
|
|
||||||
@@ -241,3 +242,31 @@ def _make_ip_policy_dict(ipp):
|
|||||||
"subnet_ids": [s["id"] for s in ipp["subnets"]],
|
"subnet_ids": [s["id"] for s in ipp["subnets"]],
|
||||||
"network_ids": [n["id"] for n in ipp["networks"]],
|
"network_ids": [n["id"] for n in ipp["networks"]],
|
||||||
"exclude": [ippc["cidr"] for ippc in ipp["exclude"]]}
|
"exclude": [ippc["cidr"] for ippc in ipp["exclude"]]}
|
||||||
|
|
||||||
|
|
||||||
|
def _make_floating_ip_dict(flip):
|
||||||
|
# Note(Alan Quillin) A floating IP should only be associated with a single
|
||||||
|
# port so we need to get the first port from the list if any exist.
|
||||||
|
|
||||||
|
port_id = None
|
||||||
|
fixed_ip = None
|
||||||
|
if flip.ports and len(flip.ports) > 0:
|
||||||
|
port = flip.ports[0]
|
||||||
|
port_id = flip.ports[0].id
|
||||||
|
if port.ip_addresses and len(port.ip_addresses) > 0:
|
||||||
|
# Note(Alan Quillin) If the associated port has multiple fixed IP
|
||||||
|
# addresses, the first one found is used (based on allocated_at)
|
||||||
|
fixed_ip = next(ip.formatted() if ip else None
|
||||||
|
for ip in sorted(port.ip_addresses,
|
||||||
|
key=lambda ip:
|
||||||
|
ip.get("allocated_at"))
|
||||||
|
if ip.get("address_type") == ip_types.FIXED)
|
||||||
|
|
||||||
|
return {"id": flip.get("id"),
|
||||||
|
"floating_network_id": flip.get("network_id"),
|
||||||
|
"router_id": CONF.QUARK.floating_ip_router_id,
|
||||||
|
"fixed_ip_address": fixed_ip,
|
||||||
|
"floating_ip_address": flip.formatted(),
|
||||||
|
"tenant_id": flip.get("tenant_id"),
|
||||||
|
"status": flip.get("status"),
|
||||||
|
"port_id": port_id}
|
||||||
|
|||||||
Reference in New Issue
Block a user