Commit 16247f9b authored by Thomas Goirand's avatar Thomas Goirand

Merge tag '4.0.0' into debian/stein

octavia 4.0.0 release

meta:version: 4.0.0
meta:diff-start: 3.0.0.0rc1
meta:series: stein
meta:release-type: release
meta:pypi: yes
meta:first: yes
meta:release:Author: Sean McGinnis <sean.mcginnis@gmail.com>
meta:release:Commit: Thierry Carrez <thierry@openstack.org>
meta:release:Change-Id: I2717755ff6e525a4075cf5f6397c0c1d1d45e170
meta:release:Code-Review+1: Tom Barron <tpb@dyncloud.net>
meta:release:Code-Review+1: dharmendra kushwaha <dharmendra.kushwaha@india.nec.com>
meta:release:Code-Review+1: Ivan Kolodyazhny <e0ne@e0ne.info>
meta:release:Code-Review+1: Akihiro Motoki <amotoki@gmail.com>
meta:release:Code-Review+1: zhurong <aaronzhu1121@gmail.com>
meta:release:Code-Review+1: Chris Dent <cdent@anticdent.org>
meta:release:Code-Review+1: Graham Hayes <gr@ham.ie>
meta:release:Code-Review+1: Luka Peschke <luka.peschke@objectif-libre.com>
meta:release:Code-Review+1: Pierre Riteau <pierre@stackhpc.com>
meta:release:Code-Review+1: Li Liu <liliueecg@gmail.com>
meta:release:Code-Review+1: Ghanshyam Mann <gmann@ghanshyammann.com>
meta:release:Code-Review+1: Eric Fried <openstack@fried.cc>
meta:release:Code-Review+1: melanie witt <melwittt@gmail.com>
meta:release:Code-Review+1: licanwei <li.canwei2@zte.com.cn>
meta:release:Code-Review+1: XueFeng Liu <liu.xuefeng1@zte.com.cn>
meta:release:Code-Review+1: Renat Akhmerov <renat.akhmerov@gmail.com>
meta:release:Code-Review+1: Colleen Murphy <colleen@gazlene.net>
meta:release:Code-Review+2: Sean McGinnis <sean.mcginnis@gmail.com>
meta:release:Code-Review+2: Doug Hellmann <doug@doughellmann.com>
meta:release:Code-Review+2: Kendall Nelson <kennelson11@gmail.com>
meta:release:Code-Review+2: Jean-Philippe Evrard <jean-philippe@evrard.me>
meta:release:Code-Review+2: Tony Breeds <tony@bakeyournoodle.com>
meta:release:Code-Review+1: Erno Kuvaja <jokke@usr.fi>
meta:release:Code-Review+2: Thierry Carrez <thierry@openstack.org>
meta:release:Workflow+1: Sean McGinnis <sean.mcginnis@gmail.com>
parents 775b40e5 feb640d9
......@@ -2,4 +2,4 @@
host=review.openstack.org
port=29418
project=openstack/octavia.git
defaultbranch=stable/rocky
defaultbranch=stable/stein
......@@ -199,13 +199,29 @@ class BaseOS(object):
return host_routes
@classmethod
def _bring_if_up(cls, interface, what):
def _bring_if_up(cls, interface, what, flush=True):
# Note, we are not using pyroute2 for this as it is not /etc/netns
# aware.
# Work around for bug:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=845121
int_up = "ip netns exec {ns} ip link set {int} up".format(
ns=consts.AMPHORA_NAMESPACE, int=interface)
addr_flush = "ip netns exec {ns} ip addr flush {int}".format(
ns=consts.AMPHORA_NAMESPACE, int=interface)
cmd = ("ip netns exec {ns} ifup {params}".format(
ns=consts.AMPHORA_NAMESPACE, params=interface))
try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
out = subprocess.check_output(int_up.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
if flush:
out = subprocess.check_output(addr_flush.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
out = subprocess.check_output(cmd.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
except subprocess.CalledProcessError as e:
LOG.error('Failed to ifup %s due to error: %s %s', interface, e,
e.output)
......@@ -233,7 +249,7 @@ class BaseOS(object):
cls._bring_if_down(secondary_interface)
cls._bring_if_up(primary_interface, 'VIP')
if secondary_interface:
cls._bring_if_up(secondary_interface, 'VIP')
cls._bring_if_up(secondary_interface, 'VIP', flush=False)
def has_ifup_all(self):
return True
......
......@@ -95,7 +95,7 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
# expects
vip_qos_policy_id = lb_dict.pop('vip_qos_policy_id', None)
if vip_qos_policy_id:
vip_dict = {"vip_qos_policy_id": vip_qos_policy_id}
vip_dict = {"qos_policy_id": vip_qos_policy_id}
lb_dict["vip"] = vip_dict
payload = {consts.LOAD_BALANCER_ID: lb_id,
......
......@@ -547,11 +547,12 @@ class LoadBalancersController(base.BaseController):
self._auth_validate_action(context, db_lb.project_id,
constants.RBAC_PUT)
if (load_balancer.vip_qos_policy_id and
not isinstance(load_balancer.vip_qos_policy_id,
wtypes.UnsetType) and
db_lb.vip.qos_policy_id != load_balancer.vip_qos_policy_id):
validate.qos_policy_exists(load_balancer.vip_qos_policy_id)
if not isinstance(load_balancer.vip_qos_policy_id, wtypes.UnsetType):
network_driver = utils.get_network_driver()
validate.qos_extension_enabled(network_driver)
if load_balancer.vip_qos_policy_id is not None:
if db_lb.vip.qos_policy_id != load_balancer.vip_qos_policy_id:
validate.qos_policy_exists(load_balancer.vip_qos_policy_id)
# Load the driver early as it also provides validation
driver = driver_factory.get_driver(db_lb.provider)
......
......@@ -90,4 +90,7 @@ class BarbicanACLAuth(barbican_common.BarbicanAuth):
user_session = session.Session(auth=user_auth)
# create a special barbican client with our user's session
return barbican_client.Client(session=user_session)
return barbican_client.Client(
session=user_session,
region_name=CONF.certificates.region_name,
interface=CONF.certificates.endpoint_type)
......@@ -342,6 +342,7 @@ def subnet_exists(subnet_id):
def qos_policy_exists(qos_policy_id):
network_driver = utils.get_network_driver()
qos_extension_enabled(network_driver)
try:
qos_policy = network_driver.get_qos_policy(qos_policy_id)
except Exception:
......@@ -350,6 +351,12 @@ def qos_policy_exists(qos_policy_id):
return qos_policy
def qos_extension_enabled(network_driver):
if not network_driver.qos_enabled():
raise exceptions.ValidationException(detail=_(
"VIP QoS policy is not allowed in this deployment."))
def network_exists_optionally_contains_subnet(network_id, subnet_id=None):
"""Raises an exception when a network does not exist.
......
# Copyright 2019 Michael Johnson
#
# 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.
"""Seed the spares_pool table
Revision ID: 46d914b2a5e5
Revises: 6ffc710674ef
Create Date: 2019-04-03 14:03:25.596157
"""
import datetime
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '46d914b2a5e5'
down_revision = '6ffc710674ef'
def upgrade():
# Create temporary table for table data seeding
insert_table = sa.table(
u'spares_pool',
sa.column(u'updated_at', sa.DateTime),
)
# Note: The date/time doesn't matter, we just need to seed the table.
op.bulk_insert(
insert_table,
[
{'updated_at': datetime.datetime.now()}
]
)
......@@ -349,3 +349,10 @@ class AbstractNetworkDriver(object):
:param subnet: The subnet to plug the aap into
"""
pass
@abc.abstractmethod
def qos_enabled(self):
"""Whether QoS is enabled
:return: Boolean
"""
......@@ -27,6 +27,7 @@ from octavia.network.drivers.neutron import utils
LOG = logging.getLogger(__name__)
DNS_INT_EXT_ALIAS = 'dns-integration'
SEC_GRP_EXT_ALIAS = 'security-group'
QOS_EXT_ALIAS = 'qos'
CONF = cfg.CONF
......@@ -46,6 +47,7 @@ class BaseNeutronDriver(base.AbstractNetworkDriver):
self.sec_grp_enabled = self._check_extension_enabled(SEC_GRP_EXT_ALIAS)
self.dns_integration_enabled = self._check_extension_enabled(
DNS_INT_EXT_ALIAS)
self._qos_enabled = self._check_extension_enabled(QOS_EXT_ALIAS)
self.project_id = self.neutron_client.get_auth_info().get(
'auth_tenant_id')
......@@ -248,3 +250,6 @@ class BaseNeutronDriver(base.AbstractNetworkDriver):
def get_qos_policy(self, qos_policy_id):
return self._get_resource('qos_policy', qos_policy_id)
def qos_enabled(self):
return self._qos_enabled
......@@ -26,6 +26,7 @@ class NoopManager(object):
def __init__(self):
super(NoopManager, self).__init__()
self.networkconfigconfig = {}
self._qos_extension_enabled = True
def allocate_vip(self, loadbalancer):
LOG.debug("Network %s no-op, allocate_vip loadbalancer %s",
......@@ -260,6 +261,9 @@ class NoopManager(object):
self.networkconfigconfig[(qos_id, port_id)] = (
qos_id, port_id, 'apply_qos_on_port')
def qos_enabled(self):
return self._qos_extension_enabled
class NoopNetworkDriver(driver_base.AbstractNetworkDriver):
def __init__(self):
......@@ -338,3 +342,6 @@ class NoopNetworkDriver(driver_base.AbstractNetworkDriver):
def unplug_aap_port(self, vip, amphora, subnet):
self.driver.unplug_aap_port(vip, amphora, subnet)
def qos_enabled(self):
return self.driver.qos_enabled()
......@@ -1590,6 +1590,20 @@ class TestLoadBalancer(base.BaseAPITest):
self.put(self.LB_PATH.format(lb_id=lb_dict.get('id')),
lb_json, status=400)
def test_update_with_qos_ext_disabled(self):
project_id = uuidutils.generate_uuid()
lb = self.create_load_balancer(uuidutils.generate_uuid(),
name='lb1',
project_id=project_id)
lb_dict = lb.get(self.root_tag)
self.set_lb_status(lb_dict.get('id'))
vip_qos_policy_id = uuidutils.generate_uuid()
lb_json = self._build_body({'vip_qos_policy_id': vip_qos_policy_id})
with mock.patch("octavia.network.drivers.noop_driver.driver"
".NoopManager.qos_enabled", return_value=False):
self.put(self.LB_PATH.format(lb_id=lb_dict.get('id')),
lb_json, status=400)
def test_update_bad_lb_id(self):
path = self.LB_PATH.format(lb_id='SEAN-CONNERY')
self.put(path, body={}, status=404)
......
......@@ -112,7 +112,7 @@ class TestAmphoraDriver(base.TestRpc):
provider_lb = driver_dm.LoadBalancer(
loadbalancer_id=self.sample_data.lb_id,
vip_qos_policy_id=qos_policy_id)
lb_dict = {'vip': {'vip_qos_policy_id': qos_policy_id}}
lb_dict = {'vip': {'qos_policy_id': qos_policy_id}}
self.amp_driver.loadbalancer_update(old_provider_lb, provider_lb)
payload = {consts.LOAD_BALANCER_ID: self.sample_data.lb_id,
consts.LOAD_BALANCER_UPDATES: lb_dict}
......
......@@ -33,7 +33,7 @@ class TestBarbicanACLAuth(base.TestCase):
# Reset the client
keystone._SESSION = None
self.conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
self.conf.config(group="certificates", region_name=None)
self.conf.config(group="certificates", region_name='RegionOne')
self.conf.config(group="certificates", endpoint_type='publicURL')
@mock.patch('keystoneauth1.session.Session', mock.Mock())
......@@ -91,3 +91,5 @@ class TestBarbicanACLAuth(base.TestCase):
bc = acl_auth_object.get_barbican_client_user_auth(mock.Mock())
self.assertTrue(hasattr(bc, 'containers') and
hasattr(bc.containers, 'register_consumer'))
self.assertEqual('publicURL', bc.client.interface)
self.assertEqual('RegionOne', bc.client.region_name)
......@@ -374,6 +374,18 @@ class TestValidations(base.TestCase):
validate.qos_policy_exists,
qos_policy_id)
def test_qos_extension_enabled(self):
network_driver = mock.Mock()
network_driver.qos_enabled.return_value = True
self.assertIsNone(validate.qos_extension_enabled(network_driver))
def test_qos_extension_disabled(self):
network_driver = mock.Mock()
network_driver.qos_enabled.return_value = False
self.assertRaises(exceptions.ValidationException,
validate.qos_extension_enabled,
network_driver)
def test_check_session_persistence(self):
valid_cookie_name_dict = {'type': 'APP_COOKIE',
'cookie_name': 'chocolate_chip'}
......
......@@ -17,7 +17,7 @@
dest: devstack-gate
EOF
/usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
git://git.openstack.org \
https://git.openstack.org \
openstack-infra/devstack-gate
executable: /bin/bash
chdir: '{{ ansible_user_dir }}/workspace'
......
......@@ -17,7 +17,7 @@
dest: devstack-gate
EOF
/usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
git://git.openstack.org \
https://git.openstack.org \
openstack-infra/devstack-gate
executable: /bin/bash
chdir: '{{ ansible_user_dir }}/workspace'
......
......@@ -17,7 +17,7 @@
dest: devstack-gate
EOF
/usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
git://git.openstack.org \
https://git.openstack.org \
openstack-infra/devstack-gate
executable: /bin/bash
chdir: '{{ ansible_user_dir }}/workspace'
......
---
fixes:
- |
Fixed an issue creating members on networks with IPv6 subnets.
---
upgrade:
- |
To fix the issue with active/standby load balancers or single topology
load balancers with members on the VIP subnet, you need to update the
amphora image.
critical:
- |
Fixed a bug where active/standby load balancers and single topology
load balancers with members on the VIP subnet may fail. An updated
image is required to fix this bug.
---
fixes:
- |
Fixed an issue that prevents spare amphorae to be created.
---
fixes:
- Fixed an error when plugging the VIP on CentOS-based amphorae.
---
fixes:
- Fixed an issue where trying to set a QoS policy on a VIP while the QoS
extension is disabled would bring the load balancer to ERROR. Should the
QoS extension be disabled, the API will now return HTTP 400 to the user.
- Fixed an issue where setting a QoS policy on the VIP would bring the load
balancer to ERROR when the QoS extension is enabled.
......@@ -8,7 +8,7 @@ usedevelop = True
setenv = VIRTUAL_ENV={envdir}
PYTHONWARNINGS=default::DeprecationWarning
install_command =
pip install -U -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
pip install -U -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein} {opts} {packages}
whitelist_externals = find
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
......@@ -21,7 +21,7 @@ basepython = python3
# This environment is called from CI scripts to test and publish
# the API Ref to developer.openstack.org.
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
whitelist_externals = rm
......@@ -90,7 +90,7 @@ whitelist_externals =
[testenv:docs]
basepython = python3
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
whitelist_externals = rm
......@@ -160,7 +160,7 @@ max-line-length = 79
[testenv:releasenotes]
basepython = python3
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
whitelist_externals = rm
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment