Merge "Add Octavia support"

This commit is contained in:
Zuul 2019-10-02 15:37:08 +00:00 committed by Gerrit Code Review
commit c94a3fa9fb
7 changed files with 175 additions and 1 deletions

View File

@ -7,13 +7,33 @@
- x/ospurge
- openstack/designate
- openstack/python-designateclient
- openstack/octavia
- openstack/octavia-lib
- openstack/python-octaviaclient
roles:
- zuul: openstack-infra/devstack
vars:
devstack_plugins:
designate: https://opendev.org/openstack/designate
octavia: https://opendev.org/openstack/octavia
devstack_localrc:
DESIGNATE_SERVICE_PORT_DNS: 5322
DISABLE_AMP_IMAGE_BUILD: True
devstack_local_conf:
post-config:
$OCTAVIA_CONF:
controller_worker:
amphora_driver: amphora_noop_driver
compute_driver: compute_noop_driver
network_driver: network_noop_driver
certificates:
cert_manager: local_cert_manager
devstack_services:
octavia: true
o-api: true
o-cw: true
o-hm: false
o-hk: false
tox_envlist: functional
irrelevant-files: &dsvm-irrelevant-files
- ^(test-|)requirements.txt$

View File

@ -0,0 +1,31 @@
# 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 ospurge.resources import base
class LoadBalancers(base.ServiceResource):
ORDER = 10
def list(self):
if not self.cloud.has_service('load-balancer'):
return []
return self.cloud.load_balancer.load_balancers(
project_id=self.cloud.current_project_id)
def delete(self, resource):
self.cloud.load_balancer.delete_load_balancer(
resource['id'], cascade=True)
@staticmethod
def to_str(resource):
return "Octavia LoadBalancer (id='{}', name='{}')".format(
resource['id'], resource['name'])

View File

@ -0,0 +1,28 @@
# 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 typing import Any
from typing import Dict
from typing import Iterable
from ospurge.resources import base
class LoadBalancers(base.ServiceResource):
def list(self) -> Iterable:
...
def delete(self, resource: Dict[str, Any]) -> None:
...
@staticmethod
def to_str(resource: Dict[str, Any]) -> str:
...

View File

@ -0,0 +1,50 @@
# 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.
import unittest
import uuid
import openstack.connection
from ospurge.resources import octavia
from ospurge.tests import mock
class TestLoadBalancers(unittest.TestCase):
def setUp(self):
self.cloud = mock.Mock(spec_set=openstack.connection.Connection)
self.creds_manager = mock.Mock(cloud=self.cloud)
def test_list_without_service(self):
self.cloud.has_service.return_value = False
self.assertEqual(octavia.LoadBalancers(self.creds_manager).list(), [])
self.cloud.load_balancer.load_balancers.assert_not_called()
def test_list_with_service(self):
self.cloud.has_service.return_value = True
my_project = str(uuid.uuid4())
self.cloud.current_project_id = my_project
self.assertIs(
self.cloud.load_balancer.load_balancers.return_value,
octavia.LoadBalancers(self.creds_manager).list())
self.cloud.load_balancer.load_balancers.assert_called_once_with(
project_id=my_project)
def test_delete(self):
lb = mock.MagicMock()
self.assertIsNone(octavia.LoadBalancers(self.creds_manager).delete(lb))
(self.cloud.load_balancer.delete_load_balancer
.assert_called_once_with(lb['id'], cascade=True))
def test_to_string(self):
stack = mock.MagicMock()
self.assertIn("Octavia LoadBalancer",
octavia.LoadBalancers(self.creds_manager).to_str(stack))

View File

@ -7,6 +7,7 @@ sphinx>=1.6.2 # BSD
testrepository>=0.0.18 # Apache-2.0/BSD
python-openstackclient>=3.16.1
python-designateclient
python-octaviaclient
# Python 2.7 dependencies
mock; python_version < '3.0'

View File

@ -82,7 +82,8 @@ if [[ ! "$(openstack flavor list)" =~ 'm1.nano' ]]; then
openstack flavor create --id 42 --ram 64 --disk 1 --vcpus 1 m1.nano
fi
# Allow demo/invisible_to_admin to access the load-balancer service
openstack role add --user demo --project invisible_to_admin load-balancer_member
########################
### Populate
@ -175,3 +176,8 @@ if [[ $(openstack zone list --all-projects | wc -l) -ne 1 ]]; then # This also
echo "Not all zones were cleaned up"
exit 1
fi
if [[ $(openstack loadbalancer list | wc -l) -ne 1 ]]; then
echo "Not all loadbalancers were cleaned up"
exit 1
fi

View File

@ -54,6 +54,21 @@ function wait_for_volume_to_be_available {
done
}
function wait_for_lb_active {
LB_ID=$1
LB_STATUS=$(openstack loadbalancer show ${LB_ID} -c provisioning_status -f value)
while [ $LB_STATUS != "ACTIVE" ]; do
if [ $LB_STATUS == "ERROR" ]; then
echo "Status of LB ${LB_NAME} is $LB_STATUS. Failing." && false
exit_on_failure "Octavia LoadBalancer ${LB_NAME} entered $LB_STATUS status."
fi
echo "Status of LB ${LB_NAME} is $LB_STATUS. Waiting 3 sec"
sleep 3
LB_STATUS=$(openstack loadbalancer show ${LB_ID} -c provisioning_status -f value)
done
}
# Check if needed environment variable OS_PROJECT_NAME is set and non-empty.
: "${OS_PROJECT_NAME:?Need to set OS_PROJECT_NAME non-empty}"
@ -70,6 +85,11 @@ FLAVOR=${FLAVOR:-m1.nano}
VMIMG_NAME=${VMIMG_NAME:-cirros-0.4.0-x86_64-disk}
# Zone name used for the Designate Zone
ZONE_NAME="${UUID//-/}.com."
# LoadBalancer name used for the Octavia LoadBalancer
LB_NAME="lb-${UUID//-/}"
LB_LISTENER_NAME="listener-${UUID//-/}"
# Subnet used for the Octavia LoadBalancer VIP
LB_VIP_SUBNET_ID=${LB_VIP_SUBNET_ID:-$UUID}
@ -191,6 +211,24 @@ openstack zone create --email hostmaster@example.com ${ZONE_NAME}
exit_on_failure "Unable to create Designate Zone ${ZONE_NAME}"
###############################
### Octavia
###############################
# Create Octavia LoadBalancer
LB_ID=$(openstack loadbalancer create --name ${LB_NAME} --vip-subnet-id ${LB_VIP_SUBNET_ID} -f value -c id)
exit_on_failure "Unable to create Octavia LoadBalancer ${LB_NAME} (${LB_ID}) as $OS_USERNAME/$OS_PROJECT_NAME"
# Wait for LB to be active
wait_for_lb_active $LB_ID
# Create Octavia Listener
openstack loadbalancer listener create \
--protocol HTTP --protocol-port 80 --name ${LB_LISTENER_NAME} \
${LB_NAME}
exit_on_failure "Unable to create Octavia Listener ${LB_LISTENER_NAME}"
# Wait for LB to be active
wait_for_lb_active $LB_ID
###############################
### Link resources
###############################