36a2d685d8
Change-Id: I651f32f7264eda20dabd6022cbb47eac38492856
146 lines
6.3 KiB
Python
146 lines
6.3 KiB
Python
# 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 io
|
|
import logging
|
|
import time
|
|
|
|
from rally_openstack.common import consts
|
|
from rally.utils import sshutils
|
|
from rally_openstack.task.scenarios.vm import utils as vm_utils
|
|
from rally_openstack.task.scenarios.neutron import utils as neutron_utils
|
|
from rally_openstack.task.scenarios.octavia import utils as octavia_utils
|
|
from rally.task import scenario
|
|
from rally.task import types
|
|
from rally.task import validation
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
@types.convert(image={"type": "glance_image"}, flavor={"type": "nova_flavor"})
|
|
@validation.add("image_valid_on_flavor", flavor_param="flavor", image_param="image")
|
|
@validation.add("required_services", services=[consts.Service.NEUTRON,
|
|
consts.Service.NOVA,
|
|
consts.Service.OCTAVIA])
|
|
@validation.add("required_platform", platform="openstack", users=True)
|
|
@validation.add("required_contexts", contexts=["network"])
|
|
@scenario.configure(context={"cleanup@openstack": ["octavia", "neutron", "nova"],
|
|
"keypair@openstack": {}, "allow_ssh@openstack": None},
|
|
name="BrowbeatPlugin.OctaviaFullyPopulatedLoadbalancer", platform="openstack")
|
|
class OctaviaFullyPopulatedLoadbalancer(vm_utils.VMScenario, neutron_utils.NeutronScenario,
|
|
octavia_utils.OctaviaBase):
|
|
|
|
def create_client(self, image, flavor, num_lb, project_id, user_data_file):
|
|
addresses = []
|
|
subnet_ids = []
|
|
network = self._create_network({'project_id': project_id})
|
|
subnets = self._create_subnets(network, None, None, int(num_lb))
|
|
LOG.info(subnets)
|
|
kwargs = {}
|
|
kwargs["nics"] = []
|
|
subnet_address = {}
|
|
for subnet in subnets:
|
|
port_create_args = {}
|
|
port_create_args["port_security_enabled"] = False
|
|
port_create_args["fixed_ips"] = [{'subnet_id': subnet["subnet"]["id"]}]
|
|
port_create_args["network_id"] = network["network"]["id"]
|
|
port = self._create_port(network, port_create_args)
|
|
kwargs["nics"].append({'port-id': port['port']['id']})
|
|
addresses.append(port['port']['fixed_ips'][0]['ip_address'])
|
|
subnet_ids.append(subnet["subnet"]["id"])
|
|
subnet_address[subnet["subnet"]["id"]] = port['port']['fixed_ips'][0]['ip_address']
|
|
userdata = None
|
|
try:
|
|
userdata = io.open(user_data_file, "r")
|
|
kwargs["userdata"] = userdata
|
|
except Exception as e:
|
|
LOG.info("couldn't add user data %s", e)
|
|
self._boot_server(image, flavor, key_name=self.context["user"]["keypair"]["name"], **kwargs)
|
|
if hasattr(userdata, 'close'):
|
|
userdata.close()
|
|
LOG.info(addresses)
|
|
return subnet_address
|
|
|
|
def run(self, image, flavor, vip_subnet_id, num_lb, user_data_file,
|
|
jump_host_ip, user, password=None, **kwargs):
|
|
project_id = self.context["tenant"]["id"]
|
|
subnet_address = self.create_client(image, flavor, num_lb,
|
|
project_id, user_data_file)
|
|
loadbalancers = []
|
|
protocol = "HTTP"
|
|
protocol_port = 80
|
|
# https://docs.openstack.org/octavia/
|
|
# latest/_modules/octavia/api/v2/controllers/load_balancer.html
|
|
for subnet_id, mem_addr in subnet_address.items():
|
|
lb_name = self.generate_random_name()
|
|
listener_name = self.generate_random_name()
|
|
pool_name = self.generate_random_name()
|
|
LOG.info("Creating load balancer %s", lb_name)
|
|
pool_args = {
|
|
"name": pool_name,
|
|
"protocol": protocol,
|
|
"lb_algorithm": "ROUND_ROBIN",
|
|
"members": [
|
|
{
|
|
"address": mem_addr,
|
|
"subnet_id": subnet_id,
|
|
"protocol_port": 80
|
|
}
|
|
]
|
|
}
|
|
listener_args = {
|
|
"name": listener_name,
|
|
"protocol": protocol,
|
|
"protocol_port": protocol_port,
|
|
"default_pool": pool_args
|
|
}
|
|
lb_args = {
|
|
"name": lb_name,
|
|
"description": None,
|
|
"listeners": [listener_args],
|
|
"provider": None,
|
|
"admin_state_up": True,
|
|
"project_id": project_id,
|
|
"vip_subnet_id": vip_subnet_id,
|
|
"vip_qos_policy_id": None,
|
|
}
|
|
|
|
lb = self.octavia._clients.octavia().load_balancer_create(
|
|
json={"loadbalancer": lb_args})["loadbalancer"]
|
|
loadbalancers.append(lb)
|
|
|
|
for loadbalancer in loadbalancers:
|
|
LOG.info("Waiting for the load balancer to be active")
|
|
self.octavia.wait_for_loadbalancer_prov_status(loadbalancer)
|
|
LOG.info("Loadbalancer %s is active", loadbalancer)
|
|
time.sleep(90)
|
|
# ssh and ping the vip
|
|
lb_ip = loadbalancer["vip_address"]
|
|
LOG.info("Load balancer IP: {}".format(lb_ip))
|
|
jump_ssh = sshutils.SSH(user, jump_host_ip, 22, None, None)
|
|
# check for connectivity
|
|
self._wait_for_ssh(jump_ssh)
|
|
cmd = "curl -s {}:{}".format(lb_ip, 80)
|
|
max_attempts = 10
|
|
attempts = 0
|
|
while attempts < max_attempts:
|
|
test_exitcode, stdout_test, stderr = jump_ssh.execute(cmd, timeout=60)
|
|
LOG.info("cmd: {}, stdout:{}".format(cmd, stdout_test))
|
|
if stdout_test != '1':
|
|
LOG.error("ERROR with HTTP response {}".format(cmd))
|
|
attempts += 1
|
|
time.sleep(30)
|
|
else:
|
|
LOG.info("cmd: {} succesful".format(cmd))
|
|
break
|