Merge "Expose project_id in octavia api"

This commit is contained in:
Jenkins 2015-12-10 18:27:34 +00:00 committed by Gerrit Code Review
commit 97be0b2477
17 changed files with 213 additions and 139 deletions

View File

@ -16,6 +16,7 @@ import logging
from oslo_db import exception as odb_exceptions
from oslo_utils import excutils
import pecan
from wsmeext import pecan as wsme_pecan
from octavia.api.v1.controllers import base
@ -23,7 +24,6 @@ from octavia.api.v1.types import health_monitor as hm_types
from octavia.common import constants
from octavia.common import data_models
from octavia.common import exceptions
from octavia.db import api as db_api
from octavia.i18n import _LI
@ -44,9 +44,9 @@ class HealthMonitorController(base.BaseController):
"""Gets a single health monitor's details."""
# NOTE(blogan): since a pool can only have one health monitor
# we are using the get_all method to only get the single health monitor
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
if not db_hm:
LOG.info(_LI("Health Monitor for Pool %s was not found"),
self.pool_id)
@ -58,10 +58,10 @@ class HealthMonitorController(base.BaseController):
body=hm_types.HealthMonitorPOST, status_code=202)
def post(self, health_monitor):
"""Creates a health monitor on a pool."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
try:
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
if db_hm:
raise exceptions.DuplicateHealthMonitor()
except exceptions.NotFound:
@ -72,25 +72,26 @@ class HealthMonitorController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Health Monitor for Pool %s cannot be updated "
"because the Load Balancer is immutable."),
self.pool_id)
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
try:
db_hm = self.repositories.health_monitor.create(session, **hm_dict)
db_hm = self.repositories.health_monitor.create(
context.session, **hm_dict)
except odb_exceptions.DBError:
# Setting LB and Listener back to active because this is just a
# validation failure
self.repositories.load_balancer.update(
session, self.load_balancer_id,
context.session, self.load_balancer_id,
provisioning_status=constants.ACTIVE)
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
provisioning_status=constants.ACTIVE)
raise exceptions.InvalidOption(value=hm_dict.get('type'),
option='type')
@ -101,10 +102,10 @@ class HealthMonitorController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
return self._convert_db_to_type(db_hm, hm_types.HealthMonitorResponse)
@wsme_pecan.wsexpose(hm_types.HealthMonitorResponse,
@ -116,9 +117,9 @@ class HealthMonitorController(base.BaseController):
monitor is allowed per pool so there is no need for a health monitor
id.
"""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
if not db_hm:
LOG.info(_LI("Health Monitor for Pool %s was not found"),
self.pool_id)
@ -128,13 +129,13 @@ class HealthMonitorController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Health Monitor for Pool %s cannot be updated "
"because the Load Balancer is immutable."),
self.pool_id)
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
try:
@ -144,18 +145,18 @@ class HealthMonitorController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
return self._convert_db_to_type(db_hm, hm_types.HealthMonitorResponse)
@wsme_pecan.wsexpose(None, status_code=202)
def delete(self):
"""Deletes a health monitor."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
if not db_hm:
LOG.info(_LI("Health Monitor for Pool %s cannot be updated "
"because the Load Balancer is immutable."),
@ -166,13 +167,13 @@ class HealthMonitorController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
db_hm = self.repositories.health_monitor.get(session,
db_hm = self.repositories.health_monitor.get(context.session,
pool_id=self.pool_id)
try:
LOG.info(_LI("Sending Deletion of Health Monitor for Pool %s to "
@ -181,8 +182,8 @@ class HealthMonitorController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_hm = self.repositories.health_monitor.get(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
return self._convert_db_to_type(db_hm, hm_types.HealthMonitorResponse)

View File

@ -49,9 +49,9 @@ class ListenersController(base.BaseController):
@wsme_pecan.wsexpose(listener_types.ListenerResponse, wtypes.text)
def get_one(self, id):
"""Gets a single listener's details."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_listener = self.repositories.listener.get(
session, load_balancer_id=self.load_balancer_id, id=id)
context.session, load_balancer_id=self.load_balancer_id, id=id)
if not db_listener:
LOG.info(_LI("Listener %s not found."), id)
raise exceptions.NotFound(
@ -62,22 +62,23 @@ class ListenersController(base.BaseController):
@wsme_pecan.wsexpose([listener_types.ListenerResponse])
def get_all(self):
"""Lists all listeners on a load balancer."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_listeners = self.repositories.listener.get_all(
session, load_balancer_id=self.load_balancer_id)
context.session, load_balancer_id=self.load_balancer_id)
return self._convert_db_to_type(db_listeners,
[listener_types.ListenerResponse])
def _test_lb_status_post(self, session, lb_repo):
def _test_lb_status_post(self, context, lb_repo):
"""Verify load balancer is in a mutable status for post method."""
if not lb_repo.test_and_set_provisioning_status(
session, self.load_balancer_id, constants.PENDING_UPDATE):
db_lb = lb_repo.get(session, id=self.load_balancer_id)
context.session, self.load_balancer_id,
constants.PENDING_UPDATE):
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
LOG.info(_LI("Load Balancer %s is immutable."), db_lb.id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
def _validate_listeners(self, session, lb_repo, listener_dict):
def _validate_listeners(self, context, lb_repo, listener_dict):
"""Validate listeners for wrong protocol or duplicate listeners
Update the load balancer db when provisioning status changes.
@ -85,18 +86,18 @@ class ListenersController(base.BaseController):
try:
sni_container_ids = listener_dict.pop('sni_containers')
db_listener = self.repositories.listener.create(
session, **listener_dict)
context.session, **listener_dict)
if sni_container_ids is not None:
for container_id in sni_container_ids:
sni_dict = {'listener_id': db_listener.id,
'tls_container_id': container_id}
self.repositories.sni.create(session, **sni_dict)
db_listener = self.repositories.listener.get(session,
self.repositories.sni.create(context.session, **sni_dict)
db_listener = self.repositories.listener.get(context.session,
id=db_listener.id)
except odb_exceptions.DBDuplicateEntry as de:
# Setting LB back to active because this is just a validation
# failure
lb_repo.update(session, self.load_balancer_id,
lb_repo.update(context.session, self.load_balancer_id,
provisioning_status=constants.ACTIVE)
if ['id'] == de.columns:
raise exceptions.IDAlreadyExists()
@ -106,7 +107,7 @@ class ListenersController(base.BaseController):
except odb_exceptions.DBError:
# Setting LB back to active because this is just a validation
# failure
lb_repo.update(session, self.load_balancer_id,
lb_repo.update(context.session, self.load_balancer_id,
provisioning_status=constants.ACTIVE)
raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
option='protocol')
@ -117,10 +118,10 @@ class ListenersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, db_listener.id,
context.session, db_listener.id,
provisioning_status=constants.ERROR)
db_listener = self.repositories.listener.get(
session, id=db_listener.id)
context.session, id=db_listener.id)
return self._convert_db_to_type(db_listener,
listener_types.ListenerResponse)
@ -128,10 +129,10 @@ class ListenersController(base.BaseController):
body=listener_types.ListenerPOST, status_code=202)
def post(self, listener):
"""Creates a listener on a load balancer."""
context = pecan.request.context.get('octavia_context')
self._secure_data(listener)
session = db_api.get_session()
lb_repo = self.repositories.load_balancer
self._test_lb_status_post(session, lb_repo)
self._test_lb_status_post(context, lb_repo)
listener_dict = listener.to_dict()
listener_dict['load_balancer_id'] = self.load_balancer_id
listener_dict['provisioning_status'] = constants.PENDING_CREATE
@ -142,17 +143,17 @@ class ListenersController(base.BaseController):
del listener_dict['tls_termination']
# This is the extra validation layer for wrong protocol or duplicate
# listeners on the same load balancer.
return self._validate_listeners(session, lb_repo, listener_dict)
return self._validate_listeners(context, lb_repo, listener_dict)
def _test_lb_status_put(self, session, id):
def _test_lb_status_put(self, context, id):
"""Test load balancer status for put method."""
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, id, constants.PENDING_UPDATE,
constants.PENDING_UPDATE):
context.session, self.load_balancer_id, id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Load Balancer %s is immutable."),
self.load_balancer_id)
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
@ -161,8 +162,8 @@ class ListenersController(base.BaseController):
def put(self, id, listener):
"""Updates a listener on a load balancer."""
self._secure_data(listener)
session = db_api.get_session()
db_listener = self.repositories.listener.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_listener = self.repositories.listener.get(context.session, id=id)
if not db_listener:
LOG.info(_LI("Listener %s not found."), id)
raise exceptions.NotFound(
@ -170,23 +171,23 @@ class ListenersController(base.BaseController):
# Verify load balancer is in a mutable status. If so it can be assumed
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
self._test_lb_status_put(session, id)
self._test_lb_status_put(context, id)
try:
LOG.info(_LI("Sending Update of Listener %s to handler"), id)
self.handler.update(db_listener, listener)
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, id, provisioning_status=constants.ERROR)
db_listener = self.repositories.listener.get(session, id=id)
context.session, id, provisioning_status=constants.ERROR)
db_listener = self.repositories.listener.get(context.session, id=id)
return self._convert_db_to_type(db_listener,
listener_types.ListenerResponse)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def delete(self, id):
"""Deletes a listener from a load balancer."""
session = db_api.get_session()
db_listener = self.repositories.listener.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_listener = self.repositories.listener.get(context.session, id=id)
if not db_listener:
LOG.info(_LI("Listener %s not found."), id)
raise exceptions.NotFound(
@ -195,13 +196,13 @@ class ListenersController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, id, constants.PENDING_UPDATE,
constants.PENDING_DELETE):
context.session, self.load_balancer_id, id,
constants.PENDING_UPDATE, constants.PENDING_DELETE):
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
db_listener = self.repositories.listener.get(session, id=id)
db_listener = self.repositories.listener.get(context.session, id=id)
try:
LOG.info(_LI("Sending Deletion of Listener %s to handler"),
db_listener.id)
@ -209,10 +210,10 @@ class ListenersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, db_listener.id,
context.session, db_listener.id,
provisioning_status=constants.ERROR)
db_listener = self.repositories.listener.get(
session, id=db_listener.id)
context.session, id=db_listener.id)
return self._convert_db_to_type(db_listener,
listener_types.ListenerResponse)

View File

@ -41,9 +41,9 @@ class LoadBalancersController(base.BaseController):
@wsme_pecan.wsexpose(lb_types.LoadBalancerResponse, wtypes.text)
def get_one(self, id):
"""Gets a single load balancer's details."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
load_balancer = self.repositories.load_balancer.get(
session, id=id)
context.session, id=id)
if not load_balancer:
LOG.info(_LI("Load Balancer %s was not found."), id)
raise exceptions.NotFound(
@ -58,10 +58,10 @@ class LoadBalancersController(base.BaseController):
# NOTE(blogan): tenant_id and project_id are optional query parameters
# tenant_id and project_id are the same thing. tenant_id will be kept
# around for a short amount of time.
project_id = project_id or tenant_id
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
project_id = context.project_id or project_id or tenant_id
load_balancers = self.repositories.load_balancer.get_all(
session, project_id=project_id)
context.session, project_id=project_id)
return self._convert_db_to_type(load_balancers,
[lb_types.LoadBalancerResponse])
@ -69,14 +69,15 @@ class LoadBalancersController(base.BaseController):
body=lb_types.LoadBalancerPOST, status_code=202)
def post(self, load_balancer):
"""Creates a load balancer."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
lb_dict = load_balancer.to_dict()
vip_dict = lb_dict.pop('vip')
lb_dict['provisioning_status'] = constants.PENDING_CREATE
lb_dict['operating_status'] = constants.OFFLINE
lb_dict['project_id'] = lb_dict.get('project_id') or context.project_id
try:
db_lb = self.repositories.create_load_balancer_and_vip(
session, lb_dict, vip_dict)
context.session, lb_dict, vip_dict)
except odb_exceptions.DBDuplicateEntry:
raise exceptions.IDAlreadyExists()
# Handler will be responsible for sending to controller
@ -87,7 +88,8 @@ class LoadBalancersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.load_balancer.update(
session, db_lb.id, provisioning_status=constants.ERROR)
context.session, db_lb.id,
provisioning_status=constants.ERROR)
return self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse)
@wsme_pecan.wsexpose(lb_types.LoadBalancerResponse,
@ -95,17 +97,17 @@ class LoadBalancersController(base.BaseController):
body=lb_types.LoadBalancerPUT)
def put(self, id, load_balancer):
"""Updates a load balancer."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
# Purely to make lines smaller length
lb_repo = self.repositories.load_balancer
db_lb = self.repositories.load_balancer.get(session, id=id)
db_lb = self.repositories.load_balancer.get(context.session, id=id)
if not db_lb:
LOG.info(_LI("Load Balancer %s was not found."), id)
raise exceptions.NotFound(
resource=data_models.LoadBalancer._name(), id=id)
# Check load balancer is in a mutable status
if not lb_repo.test_and_set_provisioning_status(
session, id, constants.PENDING_UPDATE):
context.session, id, constants.PENDING_UPDATE):
LOG.info(_LI("Load Balancer %s is immutable."), id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=id)
@ -116,28 +118,28 @@ class LoadBalancersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.load_balancer.update(
session, id, provisioning_status=constants.ERROR)
lb = self.repositories.load_balancer.get(session, id=id)
context.session, id, provisioning_status=constants.ERROR)
lb = self.repositories.load_balancer.get(context.session, id=id)
return self._convert_db_to_type(lb, lb_types.LoadBalancerResponse)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def delete(self, id):
"""Deletes a load balancer."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
# Purely to make lines smaller length
lb_repo = self.repositories.load_balancer
db_lb = self.repositories.load_balancer.get(session, id=id)
db_lb = self.repositories.load_balancer.get(context.session, id=id)
if not db_lb:
LOG.info(_LI("Load Balancer %s was not found."), id)
raise exceptions.NotFound(
resource=data_models.LoadBalancer._name(), id=id)
# Check load balancer is in a mutable status
if not lb_repo.test_and_set_provisioning_status(
session, id, constants.PENDING_DELETE):
context.session, id, constants.PENDING_DELETE):
LOG.info(_LI("Load Balancer %s is immutable."), id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=id)
db_lb = self.repositories.load_balancer.get(session, id=id)
db_lb = self.repositories.load_balancer.get(context.session, id=id)
try:
LOG.info(_LI("Sending deleted Load Balancer %s to the handler"),
db_lb.id)
@ -145,7 +147,8 @@ class LoadBalancersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.load_balancer.update(
session, db_lb.id, provisioning_status=constants.ERROR)
context.session, db_lb.id,
provisioning_status=constants.ERROR)
return self._convert_db_to_type(db_lb, lb_types.LoadBalancerResponse)
@pecan.expose()
@ -158,7 +161,8 @@ class LoadBalancersController(base.BaseController):
session = db_api.get_session()
if lb_id and len(remainder) and remainder[0] == 'listeners':
remainder = remainder[1:]
db_lb = self.repositories.load_balancer.get(session, id=lb_id)
db_lb = self.repositories.load_balancer.get(
session, id=lb_id)
if not db_lb:
LOG.info(_LI("Load Balancer %s was not found."), lb_id)
raise exceptions.NotFound(

View File

@ -16,6 +16,7 @@ import logging
import oslo_db.exception as oslo_exc
from oslo_utils import excutils
import pecan
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
@ -24,7 +25,6 @@ from octavia.api.v1.types import member as member_types
from octavia.common import constants
from octavia.common import data_models
from octavia.common import exceptions
from octavia.db import api as db_api
from octavia.i18n import _LI
@ -43,8 +43,8 @@ class MembersController(base.BaseController):
@wsme_pecan.wsexpose(member_types.MemberResponse, wtypes.text)
def get(self, id):
"""Gets a single pool member's details."""
session = db_api.get_session()
db_member = self.repositories.member.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_member = self.repositories.member.get(context.session, id=id)
if not db_member:
LOG.info(_LI("Member %s not found"), id)
raise exceptions.NotFound(
@ -54,9 +54,9 @@ class MembersController(base.BaseController):
@wsme_pecan.wsexpose([member_types.MemberResponse])
def get_all(self):
"""Lists all pool members of a pool."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
db_members = self.repositories.member.get_all(
session, pool_id=self.pool_id)
context.session, pool_id=self.pool_id)
return self._convert_db_to_type(db_members,
[member_types.MemberResponse])
@ -64,7 +64,7 @@ class MembersController(base.BaseController):
body=member_types.MemberPOST, status_code=202)
def post(self, member):
"""Creates a pool member on a pool."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
member_dict = member.to_dict()
member_dict['pool_id'] = self.pool_id
member_dict['operating_status'] = constants.OFFLINE
@ -72,24 +72,25 @@ class MembersController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all its listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Member cannot be created because its Load "
"Balancer is in an immutable state."))
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
try:
db_member = self.repositories.member.create(session, **member_dict)
db_member = self.repositories.member.create(
context.session, **member_dict)
except oslo_exc.DBDuplicateEntry as de:
# Setting LB and Listener back to active because this is just a
# validation failure
self.repositories.load_balancer.update(
session, self.load_balancer_id,
context.session, self.load_balancer_id,
provisioning_status=constants.ACTIVE)
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
provisioning_status=constants.ACTIVE)
if ['id'] == de.columns:
raise exceptions.IDAlreadyExists()
@ -105,9 +106,10 @@ class MembersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_member = self.repositories.member.get(session, id=db_member.id)
db_member = self.repositories.member.get(context.session,
id=db_member.id)
return self._convert_db_to_type(db_member, member_types.MemberResponse)
@wsme_pecan.wsexpose(member_types.MemberResponse,
@ -115,8 +117,8 @@ class MembersController(base.BaseController):
status_code=202)
def put(self, id, member):
"""Updates a pool member."""
session = db_api.get_session()
db_member = self.repositories.member.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_member = self.repositories.member.get(context.session, id=id)
if not db_member:
LOG.info(_LI("Member %s cannot be updated because its Load "
"Balancer is in an immutable state."), id)
@ -127,10 +129,10 @@ class MembersController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all its listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
try:
@ -139,16 +141,16 @@ class MembersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_member = self.repositories.member.get(session, id=id)
db_member = self.repositories.member.get(context.session, id=id)
return self._convert_db_to_type(db_member, member_types.MemberResponse)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def delete(self, id):
"""Deletes a pool member."""
session = db_api.get_session()
db_member = self.repositories.member.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_member = self.repositories.member.get(context.session, id=id)
if not db_member:
LOG.info(_LI("Member %s not found"), id)
raise exceptions.NotFound(
@ -157,15 +159,15 @@ class MembersController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all its listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Member %s cannot be deleted because its Load "
"Balancer is in an immutable state."), id)
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
db_member = self.repositories.member.get(session, id=id)
db_member = self.repositories.member.get(context.session, id=id)
try:
LOG.info(_LI("Sending Deletion of Member %s to handler"),
db_member.id)
@ -173,7 +175,7 @@ class MembersController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_member = self.repositories.member.get(session, id=id)
db_member = self.repositories.member.get(context.session, id=id)
return self._convert_db_to_type(db_member, member_types.MemberResponse)

View File

@ -27,7 +27,6 @@ from octavia.api.v1.types import pool as pool_types
from octavia.common import constants
from octavia.common import data_models
from octavia.common import exceptions
from octavia.db import api as db_api
from octavia.i18n import _LI
@ -45,8 +44,8 @@ class PoolsController(base.BaseController):
@wsme_pecan.wsexpose(pool_types.PoolResponse, wtypes.text)
def get(self, id):
"""Gets a pool's details."""
session = db_api.get_session()
db_pool = self.repositories.pool.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_pool = self.repositories.pool.get(context.session, id=id)
if not db_pool:
LOG.info(_LI("Pool %s not found."), id)
raise exceptions.NotFound(resource=data_models.Pool._name(), id=id)
@ -55,9 +54,9 @@ class PoolsController(base.BaseController):
@wsme_pecan.wsexpose([pool_types.PoolResponse])
def get_all(self):
"""Lists all pools on a listener."""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
default_pool = self.repositories.listener.get(
session, id=self.listener_id).default_pool
context.session, id=self.listener_id).default_pool
if default_pool:
default_pool = [default_pool]
else:
@ -123,19 +122,20 @@ class PoolsController(base.BaseController):
is created, another cannot be created until the first one has been
deleted.
"""
session = db_api.get_session()
if self.repositories.listener.has_pool(session, self.listener_id):
context = pecan.request.context.get('octavia_context')
if self.repositories.listener.has_pool(
context.session, self.listener_id):
raise exceptions.DuplicatePoolEntry()
# Verify load balancer is in a mutable status. If so it can be assumed
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
self._test_lb_status(session)
self._test_lb_status(context.session)
pool_dict = pool.to_dict()
sp_dict = pool_dict.pop('session_persistence', None)
pool_dict['operating_status'] = constants.OFFLINE
return self._validate_create_pool(session, sp_dict, pool_dict)
return self._validate_create_pool(context.session, sp_dict, pool_dict)
def _test_lb_status_put(self, session):
"""Verify load balancer is in a mutable status for put method."""
@ -153,15 +153,15 @@ class PoolsController(base.BaseController):
body=pool_types.PoolPUT, status_code=202)
def put(self, id, pool):
"""Updates a pool on a listener."""
session = db_api.get_session()
db_pool = self.repositories.pool.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_pool = self.repositories.pool.get(context.session, id=id)
if not db_pool:
LOG.info(_LI("Pool %s not found."), id)
raise exceptions.NotFound(resource=data_models.Pool._name(), id=id)
# Verify load balancer is in a mutable status. If so it can be assumed
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
self._test_lb_status_put(session)
self._test_lb_status_put(context.session)
try:
LOG.info(_LI("Sending Update of Pool %s to handler"), id)
@ -169,16 +169,16 @@ class PoolsController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
db_pool = self.repositories.pool.get(session, id=id)
db_pool = self.repositories.pool.get(context.session, id=id)
return self._convert_db_to_type(db_pool, pool_types.PoolResponse)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=202)
def delete(self, id):
"""Deletes a pool from a listener."""
session = db_api.get_session()
db_pool = self.repositories.pool.get(session, id=id)
context = pecan.request.context.get('octavia_context')
db_pool = self.repositories.pool.get(context.session, id=id)
if not db_pool:
LOG.info(_LI("Pool %s not found."), id)
raise exceptions.NotFound(resource=data_models.Pool._name(), id=id)
@ -186,15 +186,15 @@ class PoolsController(base.BaseController):
# that the listener is also in a mutable status because a load balancer
# will only be ACTIVE when all it's listeners as ACTIVE.
if not self.repositories.test_and_set_lb_and_listener_prov_status(
session, self.load_balancer_id, self.listener_id,
context.session, self.load_balancer_id, self.listener_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE):
LOG.info(_LI("Pool %s cannot be deleted because the Load "
"Balancer is in an immutable state"), id)
lb_repo = self.repositories.load_balancer
db_lb = lb_repo.get(session, id=self.load_balancer_id)
db_lb = lb_repo.get(context.session, id=self.load_balancer_id)
raise exceptions.ImmutableObject(resource=db_lb._name(),
id=self.load_balancer_id)
db_pool = self.repositories.pool.get(session, id=id)
db_pool = self.repositories.pool.get(context.session, id=id)
try:
LOG.info(_LI("Sending Deletion of Pool %s to handler"),
db_pool.id)
@ -202,12 +202,12 @@ class PoolsController(base.BaseController):
except Exception:
with excutils.save_and_reraise_exception(reraise=False):
self.repositories.listener.update(
session, self.listener_id,
context.session, self.listener_id,
operating_status=constants.ERROR)
self.repositories.pool.update(
session, db_pool.id,
context.session, db_pool.id,
operating_status=constants.ERROR)
db_pool = self.repositories.pool.get(session, id=db_pool.id)
db_pool = self.repositories.pool.get(context.session, id=db_pool.id)
return self._convert_db_to_type(db_pool, pool_types.PoolResponse)
@pecan.expose()
@ -217,10 +217,10 @@ class PoolsController(base.BaseController):
Verifies that the pool passed in the url exists, and if so decides
which controller, if any, should control be passed.
"""
session = db_api.get_session()
context = pecan.request.context.get('octavia_context')
if pool_id and len(remainder) and remainder[0] == 'members':
remainder = remainder[1:]
db_pool = self.repositories.pool.get(session, id=pool_id)
db_pool = self.repositories.pool.get(context.session, id=pool_id)
if not db_pool:
LOG.info(_LI("Pool %s not found."), pool_id)
raise exceptions.NotFound(resource=data_models.Pool._name(),
@ -231,7 +231,7 @@ class PoolsController(base.BaseController):
pool_id=db_pool.id), remainder
if pool_id and len(remainder) and remainder[0] == 'healthmonitor':
remainder = remainder[1:]
db_pool = self.repositories.pool.get(session, id=pool_id)
db_pool = self.repositories.pool.get(context.session, id=pool_id)
if not db_pool:
LOG.info(_LI("Pool %s not found."), pool_id)
raise exceptions.NotFound(resource=data_models.Pool._name(),

View File

@ -18,14 +18,14 @@ from octavia.common import context
class ContextHook(hooks.PecanHook):
@staticmethod
def on_route(state):
def on_route(self, state):
user_id = state.request.headers.get('X-User-Id')
user_id = state.request.headers.get('X-User', user_id)
project = state.request.headers.get('X-Tenant-Id')
project = state.request.headers.get('X-Tenant', project)
project = state.request.headers.get('X-Project-Id', project)
project = state.request.headers.get('X-Project', project)
auth_token = state.request.headers.get('X-Auth-Token')
state.request.context = context.Context(user_id=user_id,
project_id=project,
auth_token=auth_token)
state.request.context['octavia_context'] = context.Context(
user_id=user_id, project_id=project, auth_token=auth_token)

View File

@ -28,6 +28,7 @@ class HealthMonitorResponse(base.BaseType):
url_path = wtypes.wsattr(wtypes.text)
expected_codes = wtypes.wsattr(wtypes.text)
enabled = wtypes.wsattr(bool)
project_id = wtypes.wsattr(wtypes.UuidType())
class HealthMonitorPOST(base.BaseType):
@ -41,6 +42,7 @@ class HealthMonitorPOST(base.BaseType):
url_path = wtypes.wsattr(wtypes.text)
expected_codes = wtypes.wsattr(wtypes.text)
enabled = wtypes.wsattr(bool, default=True)
project_id = wtypes.wsattr(wtypes.UuidType())
class HealthMonitorPUT(base.BaseType):

View File

@ -37,6 +37,7 @@ class ListenerResponse(base.BaseType):
connection_limit = wtypes.wsattr(wtypes.IntegerType())
tls_certificate_id = wtypes.wsattr(wtypes.StringType(max_length=255))
sni_containers = [wtypes.StringType(max_length=255)]
project_id = wtypes.wsattr(wtypes.UuidType())
class ListenerPOST(base.BaseType):
@ -51,6 +52,7 @@ class ListenerPOST(base.BaseType):
tls_certificate_id = wtypes.wsattr(wtypes.StringType(max_length=255))
tls_termination = wtypes.wsattr(TLSTermination)
sni_containers = [wtypes.StringType(max_length=255)]
project_id = wtypes.wsattr(wtypes.UuidType())
class ListenerPUT(base.BaseType):

View File

@ -33,6 +33,7 @@ class LoadBalancerResponse(base.BaseType):
operating_status = wtypes.wsattr(wtypes.StringType())
enabled = wtypes.wsattr(bool)
vip = wtypes.wsattr(VIP)
project_id = wtypes.wsattr(wtypes.UuidType())
class LoadBalancerPOST(base.BaseType):
@ -42,10 +43,11 @@ class LoadBalancerPOST(base.BaseType):
description = wtypes.wsattr(wtypes.StringType(max_length=255))
enabled = wtypes.wsattr(bool, default=True)
vip = wtypes.wsattr(VIP, mandatory=True)
project_id = wtypes.wsattr(wtypes.UuidType())
class LoadBalancerPUT(base.BaseType):
"""Defines attributes that are acceptable of a PUT request."""
name = wtypes.wsattr(wtypes.StringType(max_length=255))
description = wtypes.wsattr(wtypes.StringType(max_length=255))
enabled = wtypes.wsattr(bool)
enabled = wtypes.wsattr(bool)

View File

@ -26,6 +26,7 @@ class MemberResponse(base.BaseType):
protocol_port = wtypes.wsattr(wtypes.IntegerType())
weight = wtypes.wsattr(wtypes.IntegerType())
subnet_id = wtypes.wsattr(wtypes.UuidType())
project_id = wtypes.wsattr(wtypes.UuidType())
class MemberPOST(base.BaseType):
@ -36,6 +37,7 @@ class MemberPOST(base.BaseType):
protocol_port = wtypes.wsattr(wtypes.IntegerType(), mandatory=True)
weight = wtypes.wsattr(wtypes.IntegerType(), default=1)
subnet_id = wtypes.wsattr(wtypes.UuidType())
project_id = wtypes.wsattr(wtypes.UuidType())
class MemberPUT(base.BaseType):

View File

@ -45,6 +45,7 @@ class PoolResponse(base.BaseType):
protocol = wtypes.wsattr(wtypes.text)
lb_algorithm = wtypes.wsattr(wtypes.text)
session_persistence = wtypes.wsattr(SessionPersistenceResponse)
project_id = wtypes.wsattr(wtypes.UuidType())
class PoolPOST(base.BaseType):
@ -56,6 +57,7 @@ class PoolPOST(base.BaseType):
protocol = wtypes.wsattr(wtypes.text, mandatory=True)
lb_algorithm = wtypes.wsattr(wtypes.text, mandatory=True)
session_persistence = wtypes.wsattr(SessionPersistencePOST)
project_id = wtypes.wsattr(wtypes.UuidType())
class PoolPUT(base.BaseType):

View File

@ -22,6 +22,7 @@ class Context(common_context.RequestContext):
super(Context, self).__init__(tenant=project_id, auth_token=auth_token,
is_admin=is_admin, user=user_id)
self._session = None
self.project_id = project_id
@property
def session(self):

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_utils import uuidutils
from octavia.common import constants
from octavia.tests.functional.api.v1 import base
@ -74,6 +76,15 @@ class TestHealthMonitor(base.BaseAPITest):
self.listener.get('id'),
constants.ACTIVE, constants.ONLINE)
def test_create_with_project_id(self):
pid = uuidutils.generate_uuid()
api_hm = self.create_health_monitor(self.lb.get('id'),
self.listener.get('id'),
self.pool.get('id'),
constants.HEALTH_MONITOR_HTTP,
1, 1, 1, 1, project_id=pid)
self.assertEqual(pid, api_hm.get('project_id'))
def test_bad_create(self):
hm_json = {'name': 'test1'}
self.post(self.hm_path, hm_json, status=400)

View File

@ -80,7 +80,8 @@ class TestListener(base.BaseAPITest):
'enabled': False, 'protocol': constants.PROTOCOL_HTTP,
'protocol_port': 80, 'connection_limit': 10,
'tls_certificate_id': uuidutils.generate_uuid(),
'sni_containers': [sni1, sni2]}
'sni_containers': [sni1, sni2],
'project_id': uuidutils.generate_uuid()}
lb_listener.update(optionals)
response = self.post(self.listeners_path, lb_listener)
listener_api = response.json
@ -108,6 +109,9 @@ class TestListener(base.BaseAPITest):
def test_create_with_id(self):
self.test_create(id=uuidutils.generate_uuid())
def test_create_with_project_id(self):
self.test_create(project_id=uuidutils.generate_uuid())
def test_create_with_duplicate_id(self):
listener = self.create_listener(self.lb.get('id'),
constants.PROTOCOL_HTTP,
@ -121,7 +125,7 @@ class TestListener(base.BaseAPITest):
def test_create_defaults(self):
defaults = {'name': None, 'description': None, 'enabled': True,
'connection_limit': None, 'tls_certificate_id': None,
'sni_containers': []}
'sni_containers': [], 'project_id': None}
lb_listener = {'protocol': constants.PROTOCOL_HTTP,
'protocol_port': 80}
response = self.post(self.listeners_path, lb_listener)

View File

@ -52,6 +52,9 @@ class TestLoadBalancer(base.BaseAPITest):
lb_json = {'name': 'test1'}
self.post(self.LB_PATH, lb_json, status=400)
def test_create_with_project_id(self):
self.test_create(project_id=uuidutils.generate_uuid())
def test_get_all(self):
lb1 = self.create_load_balancer({}, name='lb1')
lb2 = self.create_load_balancer({}, name='lb2')
@ -64,6 +67,26 @@ class TestLoadBalancer(base.BaseAPITest):
self.assertIn((lb2.get('id'), lb2.get('name')), lb_id_names)
self.assertIn((lb3.get('id'), lb3.get('name')), lb_id_names)
def test_get_all_by_project_id(self):
project1_id = uuidutils.generate_uuid()
project2_id = uuidutils.generate_uuid()
lb1 = self.create_load_balancer({}, name='lb1', project_id=project1_id)
lb2 = self.create_load_balancer({}, name='lb2', project_id=project1_id)
lb3 = self.create_load_balancer({}, name='lb3', project_id=project2_id)
project1_path = "{0}?project_id={1}".format(self.LBS_PATH, project1_id)
response = self.get(project1_path)
lbs = response.json
lb_id_names = [(lb.get('id'), lb.get('name')) for lb in lbs]
self.assertEqual(2, len(lbs))
self.assertIn((lb1.get('id'), lb1.get('name')), lb_id_names)
self.assertIn((lb2.get('id'), lb2.get('name')), lb_id_names)
project2_path = "{0}?project_id={1}".format(self.LBS_PATH, project2_id)
response = self.get(project2_path)
lbs = response.json
lb_id_names = [(lb.get('id'), lb.get('name')) for lb in lbs]
self.assertEqual(1, len(lbs))
self.assertIn((lb3.get('id'), lb3.get('name')), lb_id_names)
def test_get(self):
vip = {'ip_address': '10.0.0.1',
'port_id': uuidutils.generate_uuid(),

View File

@ -109,6 +109,14 @@ class TestMember(base.BaseAPITest):
'10.0.0.1', 80, id=mid)
self.assertEqual(mid, api_member.get('id'))
def test_create_with_project_id(self):
pid = uuidutils.generate_uuid()
api_member = self.create_member(self.lb.get('id'),
self.listener.get('id'),
self.pool.get('id'),
'10.0.0.1', 80, project_id=pid)
self.assertEqual(pid, api_member.get('project_id'))
def test_create_with_duplicate_id(self):
member = self.create_member(self.lb.get('id'),
self.listener.get('id'),

View File

@ -96,6 +96,15 @@ class TestPool(base.BaseAPITest):
id=pid)
self.assertEqual(pid, api_pool.get('id'))
def test_create_with_project_id(self):
pid = uuidutils.generate_uuid()
api_pool = self.create_pool(self.lb.get('id'),
self.listener.get('id'),
constants.PROTOCOL_HTTP,
constants.LB_ALGORITHM_ROUND_ROBIN,
project_id=pid)
self.assertEqual(pid, api_pool.get('project_id'))
def test_create_with_duplicate_id(self):
pool = self.create_pool(self.lb.get('id'),
self.listener.get('id'),