2023-01-13 08:10:59 +01:00
|
|
|
#!/bin/python3
|
|
|
|
from hcloud import Client
|
|
|
|
from hcloud.images.domain import Image
|
|
|
|
from hcloud.networks.domain import NetworkSubnet
|
|
|
|
from hcloud.server_types.domain import ServerType
|
|
|
|
from hcloud.locations.domain import Location
|
|
|
|
from hcloud.load_balancer_types.domain import LoadBalancerType
|
|
|
|
from hcloud.load_balancers.domain import (
|
|
|
|
LoadBalancerHealthCheck,
|
|
|
|
LoadBalancerService,
|
|
|
|
LoadBalancerHealtCheckHttp,
|
2023-01-13 10:48:25 +01:00
|
|
|
LoadBalancerTarget,
|
2023-01-13 08:10:59 +01:00
|
|
|
)
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
CLIENT_ID = "s478841"
|
2023-01-13 10:48:25 +01:00
|
|
|
SERVERS_NO = 5
|
|
|
|
TARGET_PORT = 8080
|
2023-01-13 08:10:59 +01:00
|
|
|
key_name = f"ssh-{CLIENT_ID}"
|
|
|
|
net_name = f"webservice-net-{CLIENT_ID}"
|
|
|
|
server_name = f"webservice-server-{CLIENT_ID}"
|
|
|
|
load_balancer_name = f"webservice-load-balancer-{CLIENT_ID}"
|
|
|
|
location = Location("hel1")
|
|
|
|
|
|
|
|
ci_webservice = r"""#cloud-config
|
|
|
|
runcmd:
|
|
|
|
- cd /home
|
|
|
|
- git clone https://git.wmi.amu.edu.pl/s478841/DPZC-Hetzner.git
|
|
|
|
- cd DPZC-Hetzner/webservice-balancer
|
|
|
|
- chmod +x ./webservice
|
|
|
|
- ./webservice
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def create_client(creds_path):
|
|
|
|
with open(creds_path, "r") as f:
|
|
|
|
token = str(f.readline()).strip()
|
|
|
|
client = Client(token=token)
|
|
|
|
print("The CLIENT has been CREATED")
|
|
|
|
return client
|
|
|
|
|
|
|
|
|
|
|
|
def load_key(pub_key_path):
|
|
|
|
print(f"\t\tUsing the {pub_key_path} file")
|
|
|
|
with open(pub_key_path) as f:
|
|
|
|
key = f.readline()
|
|
|
|
print("\t\tThe SSH KEY has been LOADED")
|
|
|
|
return key
|
|
|
|
|
|
|
|
|
|
|
|
def create_key(client, key_name, pub_key_path):
|
|
|
|
print("The SSH KEY has been...")
|
2023-01-13 10:48:25 +01:00
|
|
|
key = client.ssh_keys.get_by_name(key_name) or None
|
|
|
|
if not key:
|
|
|
|
key_of_power = load_key(pub_key_path)
|
|
|
|
key = client.ssh_keys.create(name=key_name, public_key=key_of_power)
|
2023-01-13 08:10:59 +01:00
|
|
|
print("\tCREATED")
|
|
|
|
return key
|
|
|
|
|
|
|
|
|
|
|
|
def remove_key(client, key_name):
|
|
|
|
print("The KEY has been...", end="")
|
|
|
|
try:
|
|
|
|
action = client.ssh_keys.delete(client.ssh_keys.get_by_name(key_name))
|
|
|
|
action.wait_until_finished()
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
print("DELETED")
|
|
|
|
|
|
|
|
|
|
|
|
def create_network(client, net_name, ip_range):
|
2023-01-13 10:48:25 +01:00
|
|
|
print(f"The NETWORK {net_name} has been...", end="")
|
|
|
|
net = client.networks.get_by_name(net_name) or None
|
|
|
|
if not net:
|
|
|
|
net = client.networks.create(
|
|
|
|
name=net_name,
|
|
|
|
ip_range=ip_range,
|
|
|
|
subnets=[
|
|
|
|
NetworkSubnet(
|
|
|
|
ip_range=ip_range, network_zone="eu-central", type="cloud"
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2023-01-13 08:10:59 +01:00
|
|
|
print("CREATED")
|
|
|
|
return net
|
|
|
|
|
|
|
|
|
|
|
|
def remove_network(client, net_name):
|
2023-01-13 10:48:25 +01:00
|
|
|
print(f"The NETWORK {net_name} has been...", end="")
|
2023-01-13 08:10:59 +01:00
|
|
|
try:
|
|
|
|
action = client.networks.delete(client.networks.get_by_name(net_name))
|
|
|
|
action.wait_until_finished()
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
print("DELETED")
|
|
|
|
|
|
|
|
|
|
|
|
def create_server(client, server_name, ssh_key, vnet, location, user_data):
|
2023-01-13 10:48:25 +01:00
|
|
|
webserver = client.servers.get_by_name(server_name) or None
|
|
|
|
if webserver is not None:
|
|
|
|
print(f"The WEBSERVICE {server_name} already exists")
|
|
|
|
else:
|
|
|
|
print(f"The WEBSERVICE {server_name}has been CREATED:", end=" ")
|
|
|
|
webserver = client.servers.create(
|
|
|
|
name=server_name,
|
|
|
|
server_type=ServerType("cx11"),
|
|
|
|
image=Image(name="ubuntu-22.04"),
|
|
|
|
ssh_keys=[ssh_key],
|
|
|
|
networks=[vnet],
|
|
|
|
location=location,
|
|
|
|
user_data=user_data,
|
|
|
|
)
|
|
|
|
webserver.action.wait_until_finished()
|
|
|
|
print(webserver.action.complete)
|
|
|
|
return server_name
|
2023-01-13 08:10:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
def remove_server(client, server_name):
|
2023-01-13 10:48:25 +01:00
|
|
|
print(f"The WEBSERVICE {server_name} has been...", end="")
|
2023-01-13 08:10:59 +01:00
|
|
|
try:
|
|
|
|
action = client.servers.delete(client.servers.get_by_name(server_name))
|
|
|
|
action.wait_until_finished()
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
print("DELETED")
|
|
|
|
|
|
|
|
|
|
|
|
def create_load_balancer(client, name, location, vnet, servers):
|
2023-01-13 10:48:25 +01:00
|
|
|
targets = [
|
|
|
|
LoadBalancerTarget(
|
|
|
|
type="server",
|
|
|
|
server=client.servers.get_by_name(server),
|
|
|
|
use_private_ip=True,
|
|
|
|
)
|
|
|
|
for server in servers
|
|
|
|
]
|
|
|
|
print(f"The LOAD BALANCER {name} has been CREATED:", end=" ")
|
2023-01-13 08:10:59 +01:00
|
|
|
lb = client.load_balancers.create(
|
|
|
|
name=name,
|
|
|
|
load_balancer_type=LoadBalancerType("lb11"),
|
|
|
|
location=location,
|
|
|
|
services=[
|
|
|
|
LoadBalancerService(
|
|
|
|
protocol="http",
|
2023-01-13 10:48:25 +01:00
|
|
|
listen_port=TARGET_PORT,
|
|
|
|
destination_port=TARGET_PORT,
|
2023-01-13 08:10:59 +01:00
|
|
|
proxyprotocol=False,
|
|
|
|
health_check=LoadBalancerHealthCheck(
|
|
|
|
protocol="http",
|
2023-01-13 10:48:25 +01:00
|
|
|
port=TARGET_PORT,
|
|
|
|
interval=15,
|
2023-01-13 08:10:59 +01:00
|
|
|
timeout=10,
|
|
|
|
retries=3,
|
|
|
|
http=LoadBalancerHealtCheckHttp(
|
2023-01-13 10:48:25 +01:00
|
|
|
path="/factors/6", status_codes=["2??", "3??"], tls=False
|
2023-01-13 08:10:59 +01:00
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
2023-01-13 10:48:25 +01:00
|
|
|
targets=targets,
|
2023-01-13 08:10:59 +01:00
|
|
|
public_interface=True,
|
|
|
|
network=vnet,
|
|
|
|
)
|
|
|
|
lb.action.wait_until_finished()
|
|
|
|
print(lb.action.complete)
|
2023-01-13 10:48:25 +01:00
|
|
|
return client.load_balancers.get_by_name(name)
|
2023-01-13 08:10:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
def remove_load_balancer(client, name):
|
2023-01-13 10:48:25 +01:00
|
|
|
print(f"The LOAD BALANCER {name} has been...", end="")
|
2023-01-13 08:10:59 +01:00
|
|
|
try:
|
|
|
|
action = client.load_balancers.delete(client.load_balancers.get_by_name(name))
|
|
|
|
action.wait_until_finished()
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
print("DELETED")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
client = create_client("../tokens/token_file")
|
|
|
|
|
|
|
|
ssh_path = sys.argv[-2]
|
|
|
|
action = sys.argv[-1]
|
|
|
|
|
|
|
|
if action == "--create":
|
|
|
|
ssh_key = create_key(client, key_name, ssh_path)
|
|
|
|
vnet = create_network(client, net_name, "10.10.10.0/24")
|
|
|
|
|
|
|
|
servers = [
|
|
|
|
create_server(
|
2023-01-13 08:13:48 +01:00
|
|
|
client, f"{i+1}-{server_name}", ssh_key, vnet, location, ci_webservice
|
2023-01-13 08:10:59 +01:00
|
|
|
)
|
|
|
|
for i in range(SERVERS_NO)
|
|
|
|
]
|
|
|
|
|
|
|
|
load_balancer = create_load_balancer(
|
|
|
|
client, load_balancer_name, location, vnet, servers
|
|
|
|
)
|
|
|
|
print(
|
2023-01-13 10:48:25 +01:00
|
|
|
f"\nYour service should be available at:\n\thttp://{load_balancer.data_model.public_net.ipv4.ip}:{TARGET_PORT}\n\n\t\tHave fun!"
|
2023-01-13 08:10:59 +01:00
|
|
|
)
|
|
|
|
elif action == "--clean":
|
|
|
|
remove_load_balancer(client, load_balancer_name)
|
|
|
|
for i in range(SERVERS_NO):
|
2023-01-13 08:13:48 +01:00
|
|
|
remove_server(client, f"{i+1}-{server_name}")
|
2023-01-13 08:10:59 +01:00
|
|
|
remove_network(client, net_name)
|
|
|
|
remove_key(client, key_name)
|
|
|
|
print("\n\n\t\tIt was nice to meet you!")
|
|
|
|
else:
|
|
|
|
print(f"\nSorry, don't know what the'{action}' means...bye!")
|