import json import time import sys import requests from hcloud import Client from hcloud.load_balancer_types.domain import LoadBalancerType from hcloud.load_balancers.domain import LoadBalancerAlgorithm, LoadBalancerServiceHttp, LoadBalancerHealthCheck, LoadBalancerService, LoadBalancerHealtCheckHttp, LoadBalancerTarget from hcloud.networks.domain import NetworkSubnet from hcloud.locations.domain import Location from hcloud.images.domain import Image from hcloud.server_types.domain import ServerType from hcloud.volumes.domain import Volume from checker import test class Client_MS: def __init__(self, json_config) -> None: self.config = self.load_config(json_config) self.client = self.get_client() self.ssh_key = self.get_ssh() self.network = self.create_network() self.servers = [] for i in range(int(self.config["server-number"])): self.servers.append(self.create_virual(i)) self.loadBalancer = self.create_load_balancer() def load_config(self, json_config): with open(json_config) as json_file: return json.load(json_file) def get_client(self): try: return Client(token=self.config["token-hetzner"]) except: return None def get_ssh(self): if(self.client.ssh_keys.get_by_name(self.config["ssh-name"])): print("SSHKEY: Key exists.") return self.client.ssh_keys.get_by_name(self.config["ssh-name"]) else: print("SSHKEY: Creating ssh_key.") return self.client.ssh_keys.create(name=self.config["ssh-name"], public_key=self.config["ssh-public"]) def create_virual(self, i): with open("webservice.yml", "r") as f: vs = f.read() if(self.client.servers.get_by_name(str(self.config["server-name"] + "-" + str(i)))): print("SERVER %s: Server exists." % (str(i))) server = self.client.servers.get_by_name( str(self.config["server-name"] + "-" + str(i))) print( f"\tName: {server.data_model.name}\n\tIP: {server.data_model.public_net.ipv4.ip}") return server else: print("SERVER %s: Creating server." % (str(i))) server = self.client.servers.create( name=str(self.config["server-name"] + "-" + str(i)), server_type=ServerType(self.config["server-type"]), image=Image(name=self.config["server-image"]), ssh_keys=[self.ssh_key], location=Location(self.config["location"]), networks=[self.network], user_data=vs) server.action.wait_until_finished() print( f"\tName: {server.server.data_model.name}\n\tIP: {server.server.data_model.public_net.ipv4.ip}") return server.server def create_network(self): if(self.client.networks.get_by_name(self.config["network"])): print("NETWORK: Network exists.") return self.client.networks.get_by_name(self.config["network"]) else: print("NETWORK: Creating network.") return self.client.networks.create( name=self.config["network"], ip_range=self.config["network-ip"], subnets=[ NetworkSubnet(ip_range=self.config["network-ip"], network_zone="eu-central", type="cloud") ] ) def create_load_balancer(self): if(self.client.load_balancers.get_by_name(self.config["load-balancer-name"])): print("LOADBALANCER: Load balancer exists.") loadBalancer = self.client.load_balancers.get_by_name( self.config["load-balancer-name"]) print( f"\tName: {loadBalancer.data_model.name}\n\tIP: {loadBalancer.data_model.public_net.ipv4.ip}") return loadBalancer else: print("LOADBALANCER: Creating load balancer.") targets = [] for server in self.servers: targets.append(LoadBalancerTarget( type="server", server=server, use_private_ip=True )) loadBalancer = self.client.load_balancers.create( name=self.config["load-balancer-name"], load_balancer_type=LoadBalancerType( name=self.config["load-balancer-type"]), location=Location(self.config["location"]), services=[ LoadBalancerService( protocol="http", listen_port=8080, destination_port=8080, proxyprotocol=False, health_check=LoadBalancerHealthCheck( protocol="http", port="8080", interval=15, timeout=10, retries=3, http=LoadBalancerHealtCheckHttp( path="/factors/10", status_codes=["2??", "3??"], tls=False ) ) ) ], targets=targets, public_interface=True, network=self.network ) loadBalancer.action.wait_until_finished() ip = self.client.load_balancers.get_by_name( self.config["load-balancer-name"]).data_model.public_net.ipv4.ip print( f"\tName: {loadBalancer.load_balancer.data_model.name}\n\tIP: {ip}") return loadBalancer.load_balancer def print_info(self): print("\n----- Server info -----") print( f"Webservice dostępny pod adresem: {self.get_ip()}\n") def get_ip(self): return str("http://" + self.client.load_balancers.get_by_name( self.config["load-balancer-name"]).data_model.public_net.ipv4.ip + ":8080") def delete_all(self): for i, server in enumerate(self.servers): print("SERVER%s: Deleted." % (str(i))) server.delete() self.loadBalancer.delete() print("LOADBALANCER: Deleted.") if __name__ == '__main__': if(len(sys.argv) != 2): print("Podaj ścieżkę do pliku konfiguracyjnego.") else: c = Client_MS(sys.argv[1]) c.print_info() # Test creation try: for remaining in range(30, 0, -1): sys.stdout.write("\r") sys.stdout.write( "Testing server starts in: {:2d}. Press Ctrl + C to stop.".format(remaining)) sys.stdout.flush() time.sleep(1) print("") test(c.get_ip()) except KeyboardInterrupt: pass # Delete assets try: for remaining in range(60, 0, -1): sys.stdout.write("\r") sys.stdout.write( "Deleting server starts in: {:2d}. Press Ctrl + C to stop.".format(remaining)) sys.stdout.flush() time.sleep(1) print("") except KeyboardInterrupt: sys.exit() c.delete_all()