diff --git a/rally_ovs/plugins/ovs/context/datapath.py b/rally_ovs/plugins/ovs/context/datapath.py index 104ae71..7cb1a59 100644 --- a/rally_ovs/plugins/ovs/context/datapath.py +++ b/rally_ovs/plugins/ovs/context/datapath.py @@ -90,6 +90,7 @@ def setup(self): "lswitches": lswitches, } self.context["ovs-internal-ports"] = {} + self.context["ovn-nb-lbs"] = {} def cleanup(self): pass # Not implemented diff --git a/rally_ovs/plugins/ovs/context/ovn_nb.py b/rally_ovs/plugins/ovs/context/ovn_nb.py index 017fae3..3db315d 100644 --- a/rally_ovs/plugins/ovs/context/ovn_nb.py +++ b/rally_ovs/plugins/ovs/context/ovn_nb.py @@ -41,8 +41,10 @@ def setup(self): ovn_nbctl = self._get_ovn_controller(self.install_method) lswitches = ovn_nbctl.show() + load_balancers = ovn_nbctl.lb_list() self.context["ovn-nb"] = lswitches + self.context["ovn-nb-lbs"] = load_balancers self.context["ovs-internal-ports"] = {} @logging.log_task_wrapper(LOG.info, _("Exit context: `ovn_nb`")) diff --git a/rally_ovs/plugins/ovs/ovnclients.py b/rally_ovs/plugins/ovs/ovnclients.py index 8a7694b..748e4f9 100644 --- a/rally_ovs/plugins/ovs/ovnclients.py +++ b/rally_ovs/plugins/ovs/ovnclients.py @@ -75,8 +75,12 @@ def _create_lswitches(self, lswitch_create_args, num_switches=-1): if start_cidr: cidr = start_cidr.next(i) name = "lswitch_%s" % cidr + lb_backend = '{}:4242'.format(netaddr.IPAddress(cidr) + 1) + self._add_lswitch_load_balancers(lb_backend) + lbs = list(self.context["ovn-nb-lbs"].keys()) else: name = self.generate_random_name() + lbs = [] other_cfg = { 'mcast_snoop': mcast_snoop, @@ -84,7 +88,7 @@ def _create_lswitches(self, lswitch_create_args, num_switches=-1): 'mcast_table_size': mcast_table_size } - lswitch = ovn_nbctl.lswitch_add(name, other_cfg) + lswitch = ovn_nbctl.lswitch_add(name, other_cfg, lbs) if start_cidr: lswitch["cidr"] = cidr @@ -101,6 +105,15 @@ def _create_lswitches(self, lswitch_create_args, num_switches=-1): ovn_nbctl.enable_batch_mode(False) return lswitches + def _add_lswitch_load_balancers(self, backend): + lbs = [] + for lb_name, (lb_vip, lb_backends) in self.context["ovn-nb-lbs"].items(): + new_backends = self._add_load_balancer_backend(lb_name, lb_vip, lb_backends, backend) + lbs.append((lb_name, lb_vip, new_backends)) + + for lb_name, lb_vip, new_backends in lbs: + self.context["ovn-nb-lbs"][lb_name] = (lb_vip, new_backends) + def _create_routers(self, router_create_args): self.RESOURCE_NAME_FORMAT = "lrouter_XXXXXX_XXXXXX" diff --git a/rally_ovs/plugins/ovs/ovsclients.py b/rally_ovs/plugins/ovs/ovsclients.py index 9025320..1a81b9b 100644 --- a/rally_ovs/plugins/ovs/ovsclients.py +++ b/rally_ovs/plugins/ovs/ovsclients.py @@ -172,6 +172,29 @@ def parse_lswitch_list(lswitch_data): lswitches.append({"name": line.split(" ")[1].strip('()')}) return lswitches +def get_lb_info(info): + lbs = {} + + lb_name = None + for line in info.splitlines(): + line = line.strip() + if len(line) == 0: + continue + + if not lb_name: + lb_name = line + else: + tokens = line.split('=') + if len(tokens) == 0: + lb_name = None + continue + lb_vip = tokens[0] + lb_backends = tokens[1] if len(tokens) == 2 else '' + lbs[lb_name] = (lb_vip, lb_backends) + lb_name = None + + return lbs + def set_colval_args(*col_values): args = [] for entry in col_values: diff --git a/rally_ovs/plugins/ovs/ovsclients_impl.py b/rally_ovs/plugins/ovs/ovsclients_impl.py index bd13096..e43bf17 100644 --- a/rally_ovs/plugins/ovs/ovsclients_impl.py +++ b/rally_ovs/plugins/ovs/ovsclients_impl.py @@ -163,11 +163,11 @@ def lrouter_nat_add(self, lrouter, nat_type, external_ip, logical_ip): params = [lrouter, nat_type, external_ip, logical_ip] self.run("lr-nat-add", args=params) - def lswitch_add(self, name, other_cfg={}): - params = [name] - + def lswitch_add(self, name, other_cfg={}, lbs=[]): + self.run("ls-add", args=[name]) - self.run("ls-add", args=params) + for lb in lbs: + self.run("ls-lb-add", args=[name, lb]) for cfg, val in other_cfg.items(): param_cfg = 'other_config:{c}="{v}"'.format(c=cfg, v=val) @@ -282,6 +282,26 @@ def port_group_del(self, port_group): params = [port_group] self.run("pg-del", [], params) + def lb_add(self, lb_name, lb_vip, lb_proto): + params = [lb_name, lb_vip, '\'\'', lb_proto] + self.run("lb-add", [], params) + + def lb_set_vip_backends(self, lb_name, lb_vip, lb_backends): + vips_set='vips=\'\"{}\"=\"{}\"\''.format(lb_vip, lb_backends) + params = ['Load_Balancer', lb_name, vips_set] + self.run('set', args=params) + + def lb_list(self, lb_name=None): + opts = ['--bare', '--columns', 'name,vips'] + params = ['Load_Balancer'] + if lb_name: + params.append(lb_name) + stdout = StringIO() + self.run('list', opts=opts, args=params, stdout=stdout) + output = stdout.getvalue() + + return get_lb_info(output) + def show(self, lswitch=None): params = [lswitch] if lswitch else [] stdout = StringIO() diff --git a/rally_ovs/plugins/ovs/scenarios/ovn.py b/rally_ovs/plugins/ovs/scenarios/ovn.py index 730ac3a..3839933 100644 --- a/rally_ovs/plugins/ovs/scenarios/ovn.py +++ b/rally_ovs/plugins/ovs/scenarios/ovn.py @@ -705,6 +705,25 @@ def _get_address_set(self, set_name): ovn_nbctl = self._get_ovn_controller(self.install_method) return ovn_nbctl.get("Address_Set", set_name, 'addresses') + @atomic.action_timer("ovn.create_load_balancer") + def _create_load_balancer(self, lb_name, lb_vip, lb_proto): + LOG.info('Create load balancer method: %s' % self.install_method) + ovn_nbctl = self._get_ovn_controller(self.install_method) + ovn_nbctl.lb_add(lb_name, lb_vip, lb_proto) + self.context["ovn-nb-lbs"][lb_name] = lb_vip + + @atomic.action_timer("ovn.add_load_balancer_backend") + def _add_load_balancer_backend(self, lb_name, lb_vip, lb_backends, lb_backend): + LOG.info('Add load balancer backend method: %s' % self.install_method) + + if lb_backends != '': + backends = '{},{}'.format(lb_backends, lb_backend) + else: + backends = '{}'.format(lb_backend) + ovn_nbctl = self._get_ovn_controller(self.install_method) + ovn_nbctl.lb_set_vip_backends(lb_name, lb_vip, backends) + return backends + def runCmd(self, ssh, cmd="", pid_opt="", pid="", background_opt=False): ssh.enable_batch_mode(False) diff --git a/rally_ovs/plugins/ovs/scenarios/ovn_fake_multinode.py b/rally_ovs/plugins/ovs/scenarios/ovn_fake_multinode.py index 2ca599c..6f2fccc 100644 --- a/rally_ovs/plugins/ovs/scenarios/ovn_fake_multinode.py +++ b/rally_ovs/plugins/ovs/scenarios/ovn_fake_multinode.py @@ -418,6 +418,11 @@ def setup_switch_per_node(self, fake_multinode_args = {}, lport_create_args = {}, port_bind_args = {}, create_mgmt_port = True): + # TODO: figure out how to not reload the context? + ovn_nbctl = self._get_ovn_controller(self.install_method) + lswitches = ovn_nbctl.show() + self.context["ovn-nb-lbs"] = ovn_nbctl.lb_list() + self.connect_chassis_nodes(fake_multinode_args) self.wait_chassis_nodes(fake_multinode_args) diff --git a/rally_ovs/plugins/ovs/scenarios/ovn_nb.py b/rally_ovs/plugins/ovs/scenarios/ovn_nb.py index 9564001..793c19d 100644 --- a/rally_ovs/plugins/ovs/scenarios/ovn_nb.py +++ b/rally_ovs/plugins/ovs/scenarios/ovn_nb.py @@ -198,13 +198,17 @@ def configure_routed_lport(self, lswitch, lport_create_args, port_bind_args, network_cidr = lswitch.get("cidr", None) if network_cidr: ip_list = netaddr.IPNetwork(network_cidr.ip + ip_start_index).iter_hosts() - ipaddr = str(next(ip_list)) + ip = next(ip_list) else: - ipaddr = "" + ip = None + ipaddr = "" for i in range(batch): lport = lports[i] index = batch * self.context["iteration"] + i + if ip: + ipaddr = str(ip) + ip += 1 # create/update network policy network_policy_index = index / network_policy_size @@ -410,4 +414,6 @@ def create_and_remove_address_set(self, name, address_list): self._create_address_set(name, address_list) self._remove_address_set(name) - + @scenario.configure(context={}) + def create_load_balancer(self, lb_name, lb_vip, lb_proto): + self._create_load_balancer(lb_name, lb_vip, lb_proto)