Skip to content

Commit 077b3de

Browse files
author
Marc Schöchlin
committed
Add first draft
Signed-off-by: Marc Schöchlin <marc.schoechlin@uhurutec.com>
1 parent 7f37f76 commit 077b3de

File tree

3 files changed

+177
-4
lines changed

3 files changed

+177
-4
lines changed

src/openstack_workload_generator/__main__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
iso_timestamp,
2121
deep_merge_dict,
2222
)
23+
from .entities.loadbalancer import WorkloadGeneratorLoadBalancer
2324

2425

2526
def establish_connection():
@@ -180,6 +181,20 @@ def generated_clouds_yaml():
180181
help="A list of vms to be deleted in the created projects",
181182
)
182183

184+
exclusive_group_load_balancers = parser.add_mutually_exclusive_group(required=False)
185+
exclusive_group_load_balancers.add_argument(
186+
"--create_load_balancers",
187+
action="store_true",
188+
help="Create a load balancer per project",
189+
)
190+
191+
exclusive_group_load_balancers.add_argument(
192+
"--delete_load_balancers",
193+
action="store_true",
194+
help="Delete load balancers per project",
195+
)
196+
197+
183198
args = parser.parse_args()
184199

185200
if args.os_cloud == "":
@@ -217,6 +232,15 @@ def generated_clouds_yaml():
217232
workload_project.get_and_create_machines(
218233
args.create_machines, args.wait_for_machines
219234
)
235+
236+
if args.create_load_balancers:
237+
lb = WorkloadGeneratorLoadBalancer(
238+
workload_project
239+
).get_and_create_load_balancer()
240+
lb.add_members()
241+
if args.delete_load_balancers:
242+
lb = WorkloadGeneratorLoadBalancer(workload_project)
243+
220244
if args.ansible_inventory:
221245
workload_project.dump_inventory_hosts(args.ansible_inventory)
222246

src/openstack_workload_generator/entities/helpers.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class Config:
3232
"verify_ssl_certificate": "false",
3333
"cloud_init_extra_script": """#!/bin/bash\necho "HELLO WORLD"; date > READY; whoami >> READY""",
3434
"wait_for_server_timeout": "300",
35+
"lb_name": "workload-generator-lb",
36+
"lb_listener_name": "workload-generator-listener",
37+
"lb_pool_name": "workload-generator-pool",
38+
"lb_member_tcp_port": "22",
39+
"lb_tcp_port": "22",
3540
}
3641

3742
_file: str | None = None
@@ -142,8 +147,10 @@ def get_number_of_floating_ips_per_project() -> int:
142147
@staticmethod
143148
def get_admin_vm_password() -> str:
144149
if Config.get("admin_vm_password").upper() == "ASK_PASSWORD":
145-
Config._config["admin_vm_password"] = getpass.getpass("Enter the wanted admin_vm_password: ")
146-
return Config.get("admin_vm_password", regex=r".{5,}")
150+
Config._config["admin_vm_password"] = getpass.getpass(
151+
"Enter the wanted admin_vm_password: "
152+
)
153+
return Config.get("admin_vm_password", regex=r".{5,}")
147154

148155
@staticmethod
149156
def get_vm_flavor() -> str:
@@ -180,7 +187,9 @@ def get_admin_vm_ssh_key() -> str:
180187
@staticmethod
181188
def get_admin_domain_password() -> str:
182189
if Config.get("admin_domain_password").upper() == "ASK_PASSWORD":
183-
Config._config["admin_domain_password"] = getpass.getpass("Enter the wanted admin_domain_password: ")
190+
Config._config["admin_domain_password"] = getpass.getpass(
191+
"Enter the wanted admin_domain_password: "
192+
)
184193
return Config.get("admin_domain_password", regex=r".{5,}")
185194

186195
@staticmethod
@@ -216,9 +225,29 @@ def quota(quota_name: str, quota_category: str, default_value: int) -> int:
216225
return default_value
217226

218227
@staticmethod
219-
def get_network_mtu():
228+
def get_network_mtu() -> int:
220229
return int(Config.get("network_mtu", regex=r"\d+"))
221230

231+
@staticmethod
232+
def get_lb_name() -> str:
233+
return Config.get("lb_name", regex=r"\s+")
234+
235+
@staticmethod
236+
def get_lb_listener_name() -> str:
237+
return Config.get("lb_listener_name", regex=r"\s+")
238+
239+
@staticmethod
240+
def get_lb_pool_name() -> str:
241+
return Config.get("lb_pool_name", regex=r"\s+")
242+
243+
@staticmethod
244+
def get_lb_member_tcp_port() -> int:
245+
return int(Config.get("lb_member_tcp_port", regex=r"\d+"))
246+
247+
@staticmethod
248+
def get_lb_tcp_port() -> int:
249+
return int(Config.get("lb_tcp_port", regex=r"\d+"))
250+
222251

223252
class DomainCache:
224253
_domains: dict[str, str] = dict()
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import logging
2+
3+
from openstack.connection import Connection
4+
from . import WorkloadGeneratorProject
5+
from .helpers import Config
6+
7+
LOGGER = logging.getLogger()
8+
9+
10+
class WorkloadGeneratorLoadBalancer:
11+
def __init__(
12+
self,
13+
project: WorkloadGeneratorProject,
14+
):
15+
self.conn: Connection = project.project_conn
16+
self.project = project
17+
self.lb = None
18+
self.listener = None
19+
self.pool = None
20+
self.health_monitor = None
21+
22+
def get_load_balancer_by_name(self, name: str):
23+
for lb in self.conn.load_balancer.load_balancers(name=name):
24+
if lb.name == name:
25+
return lb
26+
return None
27+
28+
def get_listener_by_name(self, name: str):
29+
for listener in self.conn.load_balancer.listeners(name=name):
30+
if listener.name == name:
31+
return listener
32+
return None
33+
34+
def get_pool_by_name(self, name: str):
35+
for pool in self.conn.load_balancer.pools(name=name):
36+
if pool.name == name:
37+
return pool
38+
return None
39+
40+
def get_health_monitor_for_pool(self, pool_id: str):
41+
for hm in self.conn.load_balancer.health_monitors():
42+
if hm.pool_id == pool_id:
43+
return hm
44+
return None
45+
46+
def get_and_create_load_balancer(
47+
self,
48+
):
49+
self.lb = self.get_load_balancer_by_name(Config.get_lb_name())
50+
if self.lb is not None:
51+
LOGGER.info(
52+
f"Load balancer with name {Config.get_lb_name()} already exists"
53+
)
54+
else:
55+
LOGGER.info(f"Create load balancer with name {Config.get_lb_name()}")
56+
self.lb = self.conn.load_balancer.create_load_balancer(
57+
name=Config.get_lb_name(),
58+
vip_subnet_id=self.project.vip_subnet_id,
59+
)
60+
self.conn.load_balancer.wait_for_load_balancer(self.lb.id)
61+
62+
self.listener = self.get_listener_by_name(Config.get_lb_listener_name())
63+
if self.listener is not None:
64+
LOGGER.info(
65+
f"Load balancer listener with name {Config.get_lb_listener_name()} already exists"
66+
)
67+
else:
68+
LOGGER.info(
69+
f"Create load balancer listener with name {Config.get_lb_listener_name()} on tcp port {Config.get_lb_listener_port()}"
70+
)
71+
self.listener = self.conn.load_balancer.create_listener(
72+
name=Config.get_lb_listener_name(),
73+
loadbalancer_id=self.lb.id,
74+
protocol="TCP",
75+
protocol_port=Config.get_lb_member_tcp_port(),
76+
)
77+
self.conn.load_balancer.wait_for_load_balancer(self.lb.id)
78+
79+
self.pool = self.get_pool_by_name(Config.get_lb_pool_name())
80+
if self.pool is not None:
81+
LOGGER.info(
82+
f"Load balancer pool with name {Config.get_lb_pool_name()} already exists"
83+
)
84+
else:
85+
LOGGER.info(
86+
f"Create load balancer pool with name {Config.get_lb_pool_name()}"
87+
)
88+
self.pool = self.conn.load_balancer.create_pool(
89+
name=Config.get_lb_pool_name(),
90+
listener_id=self.listener.id,
91+
protocol="TCP",
92+
lb_algorithm="ROUND_ROBIN",
93+
)
94+
self.conn.load_balancer.wait_for_load_balancer(self.lb.id)
95+
96+
self.health_monitor = self.get_health_monitor_for_pool(self.pool.id)
97+
if self.health_monitor is not None:
98+
LOGGER.info(
99+
f"Health monitor for pool with name {Config.get_lb_pool_name()} already exists"
100+
)
101+
else:
102+
self.conn.load_balancer.create_health_monitor(
103+
self.pool.id, type="TCP", delay=5, timeout=3, max_retries=3
104+
)
105+
106+
def add_member_to_load_balancer(self, ip: str):
107+
if self.lb is None:
108+
raise RuntimeError("Loadbalancer has not been created of gathered")
109+
110+
self.conn.load_balancer.create_member(
111+
self.pool.id,
112+
address=ip,
113+
protocol_port=Config.get_lb_member_tcp_port(),
114+
subnet_id=self.project.vip_subnet_id,
115+
)
116+
117+
def add_members_to_load_balancer(self):
118+
for machine in self.project.workload_machines:
119+
LOGGER.info(f"Adding member to load balancer with ip {machine.internal_ip}")
120+
self.add_member_to_load_balancer(machine.internal_ip)

0 commit comments

Comments
 (0)