From fc90a9130285c9fbaf06272838506fee01283008 Mon Sep 17 00:00:00 2001 From: Romain Lebbadi-Breteau <romain@lebbadi.fr> Date: Tue, 3 May 2022 14:23:02 -0400 Subject: [PATCH] Add scaling script --- scale.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100755 scale.py diff --git a/scale.py b/scale.py new file mode 100755 index 00000000..aef60196 --- /dev/null +++ b/scale.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 + +import subprocess +import json +import time +from typing import Union +import os + +CLOUD_FLAVOR = "d2-2" +CLOUD_NETWORK = "CaillouNetwork" +CLOUD_IMAGE = "smartcal-v1" +CLOUD_KEYNAME = "utils-vm" +CLOUD_SUBNET = "a55330c5-a987-458d-b36e-29f9d1661ea4" +CLOUD_POOL = "pool-tls" + + +def command_call(command, json_output=True) -> Union[bytes, dict]: + process = subprocess.Popen(command.split(), stdout=subprocess.PIPE) + + result = process.communicate()[0] + if (json_output): + result = json.loads(result) + else: + result = result.decode() + + return result + + +def create_web_server(id="01"): + command = f"openstack server create -f json --network {CLOUD_NETWORK} --flavor {CLOUD_FLAVOR} --image {CLOUD_IMAGE} --key-name {CLOUD_KEYNAME} web-{id}" + return command_call(command)["id"] + + +def delete_web_server(id): + command = f"openstack server delete {id}" + return command_call(command, False) + + +def get_server_ip(id): + command = f"openstack server show -f json {id}" + result = command_call(command) + if result["status"] != "ACTIVE": + print("Waiting 5 seconds for VM") + time.sleep(5) + return get_server_ip(id) + + return result["addresses"][CLOUD_NETWORK][0] + + +def add_load_balancer_member(ip_address): + command = f"openstack loadbalancer member create -f json --subnet-id {CLOUD_SUBNET} --address {ip_address} --protocol-port 80 {CLOUD_POOL}" + return command_call(command) + + +def delete_load_balancer_member(ip_address): + command = f"openstack loadbalancer member list -f json {CLOUD_POOL}" + members: dict = command_call(command) + load_balancers = [ + member for member in members if member["address"] == ip_address] + if len(load_balancers) == 1: + load_balancer = load_balancers[0] + id = load_balancer["id"] + command = f"openstack loadbalancer member delete {CLOUD_POOL} {id}" + return command_call(command, False) + else: + print("Load balancer not found") + + +def get_web_servers(): + command = f"openstack server list -f json" + result = command_call(command) + web_servers = [] + for server in result: + if "web" in server["Name"] and server["Status"] == "ACTIVE": + web_servers.append({ + "id": server["ID"], + "name": server["Name"], + "ip_addr": server["Networks"][CLOUD_NETWORK][0], + "index": int(server["Name"].split("-")[1]) + }) + + return web_servers + + +def full_add_server(): + web_servers = get_web_servers() + if len(web_servers) > 0: + max_index = max(web_servers, key=lambda server: server["index"]) + index = str(max_index["index"]+1).zfill(2) + else: + index = "01" + server_id = create_web_server(index) + server_ip = get_server_ip(server_id) + add_load_balancer_member(server_ip) + print(f"Server web-{index} was added successfully") + + +def full_del_server(server_id): + server_ip = get_server_ip(server_id) + delete_load_balancer_member(server_ip) + delete_web_server(server_id) + print(f"Server {server_id} was deleted successfully") + + +def monitoring(): + servers = get_web_servers() + loads = [] + for server in servers: + address = server["ip_addr"] + command = f"ssh -o StrictHostKeyChecking=no ubuntu@{address} uptime" + result = command_call(command, False) + try: + load_text = result.split("load average: ")[1].split(",")[0] + loads.append(float(load_text)) + except IndexError: + name = server["name"] + print(f"Could not retrieve information from {name}") + + if len(loads) > 0: + average = sum(loads)/len(loads) + if average > 0.80 and len(loads) < 5: + print(f"High average load : {average}, adding new server") + full_add_server() + elif average < 0.20 and len(loads) > 1: + print(f"Low average load : {average}, removing server") + max_index = max(servers, key=lambda server: server["index"]) + full_del_server(max_index["id"]) + + + +if __name__ == "__main__": + # ip = getServerIp("49bcdbc9-a891-4c22-b1dd-0e8d93b19356") + # print(f"IP : {ip}") + # print(add_server_to_load_balancer(ip)) + #full_add_server() + # delete_load_balancer_member("10.0.1.57") + full_del_server("web-02") + #monitoring() -- GitLab