class ConfigHandler: def __init__(self): self.db = ProviderDb() def clean_start(self): output = {} clean_start = args["cleanStart"] print("inside clean start") # run all delete ansiblee scripts phy_result = self.clean_physically() # on script success...restart the db tables if phy_result["success"] == True: db_result = self.clean_db() if db_result["success"] == True: output["success"] = True else: output["success"] = False output["notice"] = db_result else: output["success"] = False output["notice"] = phy_result def clean_physically(self): result = {} result["success"] = True # TODO: Fix this! print("Inside clean physically") return result def clean_db(self): result["success"] = False if self.db.delete_all_tables(): create_ok = self.db.create_tables() if create_ok: result[ "message"] = "Succesfully deleted all tables and re-created them" result["success"] = True else: result[ "message"] = "Succesfully deleted all tables but failed to re-create them" result["success"] = False else: result["message"] = "Failed to delete all tables" result["success"] = False return result
class Startup: def __init__(self): self.provider_db = ProviderDb() def start(self): if self.provider_db.create_tables(): return True else: return False
def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' self.bgp_config = []
class TransitHandler: def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' self.bgp_config = [] def create_transit(self, args): # customer_id = args["customerId"] host = args["host"] reliability_factor = int( args["reliabilityFactor"]) # must be an integer! # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} # Only 1 transit per customer transit = self.db.get_transit(customer_id) if transit != None: return {"message": "A transit (id = {0}) already exists for customer '{1}'!".format(transit.transit_id, customer_id), "success": False} # get db id for transit transit_id = self.db.get_next_transit_id() if transit_id < 0: return {"message": "A SQL error occured in creating the transit", "success": False} # create bgp config for i in range(int(reliability_factor)): config_obj = cfg.config_utils() asnum = "1%s%s" % (transit_id, i) config_as = cfg.AS(asnum) config_obj.add_as(config_as) self.bgp_config.append(config_obj) filename = "edge-%s-%s.conf" % (transit_id, i) config_obj.write_config_to(filename) if self.create_physically(transit_id, customer_id, host, reliability_factor): # save in db if successful return self.create_in_db(customer_id, host, reliability_factor) else: return {"message": "Unable to physically create the transit routers", "success": False} def create_physically(self, transit_id, customer_id, host, reliability_factor): print("Inside transit_handler.create_physically") # call the playbook create-transit.yml result = False host = host.lower() transit = self.db.get_next_transit_id() # if subnet_id < 0: # return {"message": "A SQL error occured in creating subnet '{0}'".format(ip_address), "success": False} try: json_obj = {} json_obj["reliability_factor"] = reliability_factor json_obj["transit_id"] = transit_id vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-transit.yml", "-l {0}".format(host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-transit.yml' for transit '{0}' for customer '{1}'\r\n".format(transit_id, customer_id)) return False # add routes to remote for i in range(reliability_factor): json_obj = {} json_obj["router_number"] = i json_obj['transit_id'] = transit_id vars_json = json.dumps(json_obj) other_host = 'host1' if host == 'host1': other_host = 'host2' commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "transit-route-to-host.yml", "-l {0}".format(other_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-transit.yml' for transit '{0}' for customer '{1}'\r\n".format(transit_id, customer_id)) return False result = True except Exception as e: print( "\r\nUnable to physically create the transit '{0}' for customer id '{1}'\r\nException below:\r\n{2}".format(transit_id, customer_id, e)) result = False return result def create_in_db(self, customer_id, host, reliability_factor) -> list: transitId = self.db.create_transit( customer_id, host, reliability_factor) if int(transitId) < 0: return {"message": "failed to create transit for customer '{0}'".format( customer_id), "success": False} else: return {"message": "Created transit '{0}' for customer '{1}'. Can call '.../tunnel' to add VPCs to this transit.".format( transitId, customer_id), "success": True} def get_transit(self, args): customer_id = args["customerId"] # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} transit = self.db.get_transit(customer_id) if transit == None: return {"message": "No transit found for customer {0}".format(customer_id), "success": False} else: # have to format Tunnel class into dict here... tunnels = [] for tun in transit.tunnels: tunnels.append( {"tunnelId": tun.tunnel_id, "vpcId": tun.vpc_id, "tunnelType": tun.tunnel_type}) return { "message": { "transitId": transit.transit_id, "host": transit.host, "reliabiltyFactor": transit.reliability_factor, "tunnels": tunnels }, "success": True } def delete_transit(self, args): customer_id = args["customerId"] # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id,), "success": False} res = self.db.get_transit(customer_id) if not res: return {"message": "No transit found for the customer {1}".format(customer_id,), "success": False} tunnels = res.tunnels if len(tunnels) != 0: tunnels_id_list = [] for tunnel in tunnels: tunnels_id_list.append(tunnel.tunnel_id) return {"message": "For customer '{0}'...Please delete these tunnels (id shown)".format(customer_id), "tunnelIdList": tunnels_id_list, "success": False} else: ok = self.delete_physically(res.transit_id, customer_id, res.host, res.reliability_factor) if ok and self.db.delete_transit(customer_id): return {"message": "For customer '{0}'...successfully deleted your transit.".format(customer_id), "success": True} else: return {"message": "For customer '{0}'...failed to delete your transit.".format(customer_id), "success": False} def delete_physically(self, transit_id, customer_id, host, reliability_factor): print("Inside transit_handler.create_physically") result = False host = host.lower() try: json_obj = {} json_obj["reliability_factor"] = reliability_factor json_obj["transit_id"] = transit_id vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "delete-transit.yml", "-l {0}".format(host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'delete-transit.yml' for transit '{0}' for customer '{1}'\r\n".format(transit_id, customer_id)) return False #####TODO creation vars in transit route add also for i in range(reliability_factor): json_obj = {} json_obj["creation_vars"] = [{ "router_number": i, "transit_id": transit_id }] vars_json = json.dumps(json_obj) other_host = 'host1' if host == 'host1': other_host = 'host2' commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "delete-transit-route-to-host.yml", "-l {0}".format(other_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() result = True except Exception as e: print( "\r\nUnable to physically delete the transit '{0}' for customer id '{1}'\r\nException below:\r\n{2}".format(transit_id, customer_id, e)) result = False return result
class SubnetHandler: def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' def get_all_subnets(self, args) -> list: customer_id = args["customerId"] vpc_id_list = self.db.get_all_vpcs(customer_id) ret_list = [] for vpc_id in vpc_id_list: vpc = self.db.get_vpc_by_id(vpc_id, customer_id) subnets = self.db.get_all_subnets(vpc_id) sub_list = [] for subnet in subnets: s = {} s["subnetId"] = subnet.subnetId s["vpcId"] = subnet.vpcId s["ipAddress"] = subnet.ipAddress s["subnetName"] = subnet.subnetName sub_list.append(s) ret_list.append( {"vpcId": vpc_id, "vpcName": vpc.vpcName, "host": vpc.host, "subnets": sub_list}) return {"message": ret_list, "success": True} def create_subnet(self, args): global bgp_vpc_map customer_id = args["customerId"] vpc_id = args["vpcId"] subnet_str = args["subnet"] if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} # get vpc vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if(vpc == None): return {"message": "No vpc found with id '{0}' for customer '{1}'".format(vpc_id, customer_id), "success": False} # convert str to dict subnet_str = subnet_str.replace("\'", "\"") subnet = json.loads(subnet_str) ip_address = subnet["ipAddress"] subnet_name = subnet["subnetName"] # verify valid ip NETWORK address ip_ok, ip_error = self.ensure_valid_ip_network(ip_address) if not ip_ok and ip_error == None: return {"message": "Invalid ip given! Fix this --> '{0}' ".format(ip_address), "success": False} if not ip_ok and ip_error != None: return {"message": "Invalid ip NETWORK address given! The network address is: '{0}'! Fix this --> '{1}' ".format(ip_error, ip_address), "success": False} # check db to see if subnet exists if(self.db.get_subnet(ip_address, vpc_id) != None): return { "message": "subnet '{0}' for vpc {1} (id '{2}') already exists".format( ip_address, vpc.vpcName, vpc_id), "success": False } else: # save in db if successful if self.create_physically(ip_address, vpc_id, vpc.host, vpc.scaleFactor): subnetId = self.create_in_db(vpc_id, ip_address, subnet_name) # restart bgp service in the edges bgp_configurations = bgp_vpc_map[vpc_id] # for all configs, update it with new network and restart vpc for i in range(len(bgp_configurations)): config = bgp_configurations[i] config.autonomus_systems[0].add_network(ip_address) filename = "edge-%s-%s.conf" % (vpc_id, i) config.write_config_to(filename) # restart the edge for i in vpc.scaleFactor: ns = "V%sE%s" % (vpc_id, i)
class VPCHandler(): def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' self.bgpConfig = [] def get_vpc_by_hosts(self, args): customerId = args["customerId"] print(args) print("\r\nThe customer Id is: {0}\r\n".format(customerId)) output = {} vpc_list = self.db.get_all_vpcs(customerId) print("\r\n THe vpc_list is: {0}\r\n".format(vpc_list)) output["message"] = "The list of VPC IDs are: '{0}'".format(vpc_list) output["success"] = True return output def create_vpc(self, args): vpcName = args["vpcName"] customerId = args["customerId"] host = args["host"] scaleFactor = args["scaleFactor"] if (self.db.get_customer_by_id(customerId) == None): return { "message": "No customer found with id '{0}'".format(customerId), "success": False } if (self.db.get_vpc(vpcName, customerId, host) != None): return { "message": "vpc '{0}' already exists for host '{1}'".format( vpcName, host), "success": False } vpc_id = self.db.get_next_vpc_id() if vpc_id < 0: return { "message": "A SQL error occured in creating vpc '{0}'".format(vpcName), "success": False } self.bgp_config = [cfg.config_utils()] * scaleFactor for i in range(scaleFactor): config_obj = cfg.config_utils() config_as = cfg.AS(int("1{1}{2}".format(vpc_id, i))) config_obj.add_as(config_as) self.bgp_config.append(config_obj) config_obj.write_config_to("edge-{1}-{2}.conf".format(vpc_id, i)) if self.create_physically(vpc_id, host, scaleFactor): # save in db if successful db_result = self.create_in_db(vpcName, customerId, host, scaleFactor) return db_result # TODO: Remove this below! # db_result = self.create_in_db( # vpcName, customerId, host, scaleFactor) # return db_result return { "message": "failed to create vpc {0}".format(vpcName), "success": False } def create_in_db(self, vpcName, customerId, host, scaleFactor): # create vpc in db vpcId_str = self.db.create_vpc(vpcName, customerId, host, scaleFactor) if (vpcId_str != None): return { "message": "vpc created. Id is '{0}'".format(vpcId_str), "success": True } else: return { "message": "failed to create vpc '{0}'".format(vpcName), "success": False } def delete_vpc(self, args): vpc_id = args["vpcId"] customer_id = args["customerId"] # ensure customer is valid if (self.db.get_customer_by_id(customer_id) == None): return { "message": "No customer found with id '{0}'".format(customer_id), "success": False } # get vpc id vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if (vpc == None): return { "message": "No vpc found with id '{0}' for customer '{1}'".format( vpc_id, customer_id), "success": False } # get a list of subnets subnet_ip_list = self.db.get_all_subnets_ip(vpc_id) if len(subnet_ip_list) > 0: return { "message": "Please delete these subnets from vpc '{0}'".format(vpc_id), "ipList": subnet_ip_list, "success": False } else: # delete vpc vpc_del_ok = self.delete_physically( vpc.vpcId, vpc.scaleFactor, vpc.host) and self.db.delete_vpc( vpc.vpcId) if not vpc_del_ok: return { "message": "Failed to delete vpc '{0}'. Does it exist?".format( vpc_id), "success": False } else: return { "message": "Successfully deleted vpc '{0}'.".format(vpc_id), "success": True } # might have to change the names of the south -bound scripts def create_physically(self, vpc_id, host, scale_factor): scale_factor = int(scale_factor) for i in range(scale_factor): json_obj = {} json_obj["creation_vars"] = [{"vpc_id": vpc_id, "edge_number": i}] vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "create-edges.yml", "-i", "hosts.ini", "-e", vars_json, "-l {0}".format(host.lower()) ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-edges.yml' in vpc_handler.create_physically\r\n" ) return False other_host = 'host2' if host == 'Host1' else 'host1' commands = [ "sudo", "ansible-playbook", "edge-route-to-host.yml", "-i", "hosts.ini", "-e", vars_json, "-l {0}".format(other_host) ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'edge-route-to-host.yml' in vpc_handler.create_physically\r\n" ) return False return True def delete_physically(self, vpc_id, scaleFactor, host): for i in range(scaleFactor): json_obj = {} json_obj["creation_vars"] = [{"vpc_id": vpc_id, "edge_number": i}] vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "delete-edges.yml", "-i", "hosts.ini", "-e", vars_json, "-l {0}".format(host.lower()) ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'delete-edges.yml' in vpc_handler.delete_physically\r\n" ) return False other_host = 'host2' if host == 'Host1' else 'host1' commands = [ "sudo", "ansible-playbook", "delete-routes-to-edges.yml", "-i", "hosts.ini", "-e", vars_json, "-l {0}".format(other_host) ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'delete-routes-to-edges.yml' in vpc_handler.delete_physically\r\n" ) return False return True
class CustomerHandler: def __init__(self): self.SOUTHBOUND_DIRECTORY = 'overlay_south' self.db = ProviderDb() def create_customer(self, args): customerName = args["customerName"] db_result = self.create_in_db(customerName) return db_result def create_in_db(self, customer_name): # check db to see if vpc exists... if (self.db.get_customer(customer_name) != None): return { "message": "customer '{0}' already exists".format(customer_name), "success": False } # create customer in db customerId_str = self.db.create_customer(customer_name) if (customerId_str != None): return { "message": "customer created. Id is '{0}'".format(customerId_str), "success": True } else: return { "message": "failed to create customer '{0}'".format(customer_name), "success": False } def get_all_customers(self): # No args required... return self.db.get_all_customers() def delete_customer(self, args): customer_name = args["customerName"] customer = self.db.get_customer(customer_name) if (customer == None): return { "message": "No customer with name '{0}' found".format(customer_name), "success": False } errors = {} # This should delete VPCs, Subnets, VMs, the whole works! # get ALL the vpc for customer vpc_list = self.db.get_all_vpcs(customer.customerId) if len(vpc_list) > 0: return { "message": "Please delete these VPCs first! --> '{0}'".format(vpc_list), "success": False } # delete customer if not self.db.delete_customer(customer.customerId): mess = { "message": "Failed to delete customer with id '{0}'".format( customer.customerId) } errors.append(mess) if len(errors) == 0: return { "message": "Successfully deleted customer '{0}'".format( customer.customerName), "success": True, "notice": "Customer '{0}' does not exist anymore!".format( customer.customerName) } else: return { "message": "Failed to delete ALL of customer '{0}'".format( customer.customerName), "success": False, "errors": errors }
class VMHandler(): def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' def create_vm(self, args): customer_id = args['customerId'] vpc_id = args['vpcId'] subnet_id = args['subnetId'] vm_name = args['vmName'] # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return { "message": "No customer found with id '{0}'".format(customer_id), "success": False } # verify vpc id vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if (vpc == None): return { "message": "No vpc found with id '{0}' for customer '{1}'".format( vpc_id, customer_id), "success": False } # verify subnet id subnet = self.db.get_subnet_by_id(subnet_id, vpc_id) if (subnet == None): return { "message": "failed to get subnet id '{0}' for vpc id '{1}'".format( subnet_id, vpc_id), "success": False } # check db to see if VM exists... if (self.db.get_vm(vm_name, subnet_id) != None): return { "message": "vm '{0}' already exists in subnet '{1}'".format( vm_name, subnet_id), "success": False } # ...NO VM exists at this point... # create MAC address mac_addr = self.generate_mac_addr() # create IP address do_not_use_ip_list = self.db.get_all_vm_ip_addrs(subnet_id) ip_addr = self.generate_ip_addr(subnet.ipAddress, do_not_use_ip_list) if ip_addr == None: return { "message": "No more ip addresses available for subnet '{0}' (id: '{1}') in vpc '{2}'" .format(subnet.ipAddress, subnet.subnetId, vpc.vpcName), "success": False } # create unique vm name vm_id = self.db.get_next_vm_id() if vm_id < 0: return { "message": "A SQL error occured in creating VM '{0}'".format(vm_name), "success": False } unique_vm_name = "{0}_{1}".format(vm_name, str(vm_id)) # create vm physically phy_result = self.create_physically(vm_id, unique_vm_name, mac_addr, ip_addr, subnet_id, vpc_id, vpc.host) # save in db if successful if phy_result: return self.create_in_db(unique_vm_name, mac_addr, ip_addr, subnet_id, vpc_id) else: return { "message": "Unable to physically create vm '{0}' for subnet {1}".format( vm_name, subnet_id), "success": False } def create_physically(self, vmId, vmName, macAddr, ipAddr, subnetId, vpcId, host): # # TODO: Fix this! # return True args = { "guests": [{ "name": vmName, "subnet_id": subnetId, "vpc_id": vpcId, "vm_id": vmId, "mac_address": macAddr }] } commands = [ "sudo", "ansible-playbook", "create-vms.yml", "-i", "hosts.ini", "-e", json.dumps(args), "-l {0}".format(host.lower()) ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-vms.yml' in vm_handler.create_physically\r\n" ) return False else: return True def generate_mac_addr(self) -> str: mac = [ 0x08, 0x00, 0x22, random.randint(0x00, 0x7f), random.randint(0x00, 0xff), random.randint(0x00, 0xff) ] return ':'.join(map(lambda x: "%02x" % x, mac)) def generate_ip_addr(self, subnet_ip: str, do_not_use_ip_list: list) -> str: # subnet_ip ex: "192.168.2.0/28" ip_range = ipaddress.IPv4Network(subnet_ip) network_addr = str(ip_range.network_address) broadcast_addr = str(ip_range.broadcast_address) the_ip_addr = None for ip in ip_range.hosts(): ip_str = str(ip) if ip_str == network_addr: print("Network IP '{0}' cannot be used".format(ip_str)) continue # do not return an already used IP! if ip_str in do_not_use_ip_list: print("IP '{0}' is already used".format(ip_str)) continue if ip_str == broadcast_addr: print("Broadcast IP '{0}' cannot be used".format(ip_str)) continue print("IP to be assigned to vm is: '{0}'\r\n".format(ip_str)) return ip_str def create_in_db(self, vm_name, mac_addr, ip_addr, subnet_id, vpc_id): vm_id_str = self.db.create_vm(vm_name, mac_addr, ip_addr, subnet_id, vpc_id) if (vm_id_str != None): return { "message": "Vm '{0}' (ID '{1}', ip '{2}') created in subnet '{3}'.". format(vm_name, vm_id_str, ip_addr, subnet_id), "success": True } else: return { "message": "failed to add in db the vm '{0}' (ip '{1}') in subnet '{2}'". format(vm_name, ip_addr, subnet_id), "success": False } def delete_vm(self, args): customer_name = args['customerName'] vmNames = args['vmNames'] # a list output = {} output["notice"] = [] output["success"] = False for vm_str_obj in vmNames: # convert str to dict vm_str_obj = vm_str_obj.replace("\'", "\"") vm = json.loads(vm_str_obj) print(vm) host = vm["host"] vm_name = vm["vmName"] vm_ip = vm["vmIp"] subnet_ip = vm["subnetIp"] vpc_name = vm["vpcName"] # get vpc vpc = self.db.get_vpc(vpc_name, customer_name, host) if vpc == None: output["notice"].append({ "message": "No vpc found with name '{0}' for customer '{1}' in host '{2}'" .format(vpc_name, customer_name, host), "success": False }) continue else: vpc_id = vpc.vpcId # get subnet subnet = self.db.get_subnet(subnet_ip, vpc_id) if subnet == None: output["notice"].append({ "message": "No subnet '{0}' found in vpc '{1}' (vpc id={2}) in host '{3}'" .format(subnet_ip, vpc.vpcName, vpc.vpcId, host), "success": False }) continue else: subnet_id = subnet.subnetId vm = self.db.get_vm(vm_name, subnet.subnetId) if (vm == None): output["notice"].append({ "message": "No VM '{0}' found in subnet '{1}' (subnet id={2}) in vpc '{3}'" .format(vm_name, subnet_ip, subnet.subnetId, vpc.vpcName), "success": False }) continue else: vm_id = vm.vmId phy_result = self.delete_physically(host, vm_name, vm_ip) if phy_result: db_result = self.delete_in_db(vm_id, vm_name, subnet_ip, vpc_name) if db_result: output["notice"].append({ "message": "Successfully deleted vm {0} in subnet '{1}' (subnet id={2}) in vpc '{3}'" .format(vm_name, subnet_ip, subnet.subnetId, vpc.vpcName), "dbMessage": db_result, "success": True }) output["success"] = True else: output["notice"].append({ "message": "Failed to delete vm {0} in subnet '{1}' (subnet id={2}) in vpc '{3}'" .format(vm_name, subnet_ip, subnet.subnetId, vpc.vpcName), "dbMessage": db_result, "success": False }) output["success"] = False else: output["notice"].append({ "message": "Failed to physically delete VM {0} with ip {1} in host {2}" .format(vm_name, vm_ip, host), "success": False }) output["success"] = False return output def delete_physically(self, host, vm_name, vm_ip): return True # TODO: Fix this! def delete_in_db(self, vm_id, vm_name, subnet_ip, vpc_name): delete_ok = self.db.delete_vm(vm_id) if (delete_ok): results = { "message": "vm '{0}' is deleted from subnet '{1}' in vpc {2}".format( vm_name, subnet_ip, vpc_name), "success": True } else: results = { "message": "Failed to delete vm '{0}' from subnet '{1}' in vpc {2}". format(vm_name, subnet_ip, vpc_name), "success": False } return results
def __init__(self): self.db = ProviderDb()
class SubnetHandler: def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' def get_all_subnets(self, args) -> list: customer_id = args["customerId"] vpc_id_list = self.db.get_all_vpcs(customer_id) ret_list = [] for vpc_id in vpc_id_list: vpc = self.db.get_vpc_by_id(vpc_id, customer_id) subnets = self.db.get_all_subnets(vpc_id) sub_list = [] for subnet in subnets: s = {} s["subnetId"] = subnet.subnetId s["vpcId"] = subnet.vpcId s["ipAddress"] = subnet.ipAddress s["subnetName"] = subnet.subnetName sub_list.append(s) ret_list.append( {"vpcId": vpc_id, "vpcName": vpc.vpcName, "host": vpc.host, "subnets": sub_list}) return {"message": ret_list, "success": True} def create_subnet(self, args): customer_id = args["customerId"] vpc_id = args["vpcId"] subnet_str = args["subnet"] if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} # get vpc vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if(vpc == None): return {"message": "No vpc found with id '{0}' for customer '{1}'".format(vpc_id, customer_id), "success": False} # convert str to dict subnet_str = subnet_str.replace("\'", "\"") subnet = json.loads(subnet_str) ip_address = subnet["ipAddress"] subnet_name = subnet["subnetName"] # verify valid ip NETWORK address ip_ok, ip_error = self.ensure_valid_ip_network(ip_address) if not ip_ok and ip_error == None: return {"message": "Invalid ip given! Fix this --> '{0}' ".format(ip_address), "success": False} if not ip_ok and ip_error != None: return {"message": "Invalid ip NETWORK address given! The network address is: '{0}'! Fix this --> '{1}' ".format(ip_error, ip_address), "success": False} # check db to see if subnet exists if(self.db.get_subnet(ip_address, vpc_id) != None): return { "message": "subnet '{0}' for vpc {1} (id '{2}') already exists".format( ip_address, vpc.vpcName, vpc_id), "success": False } else: # save in db if successful if self.create_physically(ip_address, vpc_id, vpc.host, vpc.scaleFactor): subnetId = self.create_in_db(vpc_id, ip_address, subnet_name) return { "subnet_id":subnetId, "message": "Successfully created a physical subnet '{0}'for vpc '{1}' in host '{2}'".format(ip_address, vpc_id, vpc.host), #"dbMessage": db_result, "success": True } else: return { "message": "Unable to physically create subnet '{0}' for vpc {1} (id is {2})".format(ip_address, vpc.vpcName, vpc_id), "success": False } def ensure_valid_ip_network(self, subnet_str): try: valid_ip_network = ipaddress.IPv4Interface(subnet_str).network print(valid_ip_network) print(subnet_str) if str(valid_ip_network) != subnet_str: return False, valid_ip_network else: return True, None except Exception as e: traceback.print_exception(type(e), e, e.__traceback__) return False, None def create_physically(self, ip_address, vpc_id, host, scaleFactor): result = False host = host.lower() subnet_id = self.db.get_next_subnet_id() if subnet_id < 0: return {"message": "A SQL error occured in creating subnet '{0}'".format(ip_address), "success": False} try: json_obj = {} json_obj["subnet_id"] = subnet_id json_obj["vpc_id"] = vpc_id json_obj["edge_count"] = scaleFactor if ip_address: json_obj["ip_address"] = ip_address vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-subnet.yml", "-l {0}".format(host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() # print("stderr", stderr) # print("retcode =", p.returncode) if p.returncode != 0: print( "\r\nUnable to run ansible 'create-subnet.yml' for subnet '{0}' in VPC '{1}'\r\n".format(ip_address, vpc_id)) return False result = True except Exception as e: print( "\r\nUnable to physically create the subnet '{0}' for vpc id '{1}'\r\nException below:\r\n{2}".format(ip_address, vpc_id, e)) result = False return result def create_in_db(self, vpc_id, ip_address, subnet_name) -> int: # create vpc in db subnetId_str = self.db.create_subnet(ip_address, subnet_name, vpc_id) if(subnetId_str != None): return int(subnetId_str) else: return -1 def delete_subnet(self, args): customer_id = args["customerId"] vpc_id = args["vpcId"] subnet_id = args["subnetId"] # ensure valid customer if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} # ensure valid vpc vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if(vpc == None): return {"message": "No vpc found with id '{0}' for customer '{1}'".format(vpc_id, customer_id), "success": False} # get subnet subnet = self.db.get_subnet_by_id(subnet_id, vpc_id) if subnet == None: return {"message": "No subnet found with id '{0}' for vpc '{1}'".format(subnet_id, vpc_id), "success": False} # Check for no VMs ...and then delete subnets vm_list = self.db.get_all_vms(subnet_id) if len(vm_list) > 0: return { "vmList": vm_list, "message": "Please delete these VMs (id list given) first!", "success": False } # ...NO VMs were found... # delete subnet physically phy_result = self.delete_physically(subnet.subnetId, vpc_id, vpc.host) # save in db if successful if phy_result: return self.delete_in_db(subnet_id, subnet.ipAddress, vpc_id, vpc.host) else: return { "message": "Unable to physically delete subnet '{0}' for vpc '{1}' in host '{2}'".format(subnet.ipAddress, vpc_id, vpc.host), "success": False } def delete_physically(self, subnet_id, vpc_id, host): # call southbound to delete subnet result = False host = host.lower() try: json_obj = {} json_obj["subnet_id"] = subnet_id json_obj["vpc_id"] = vpc_id vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "delete-subnet.yml", "-l {0}".format(host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() # print("stderr", stderr) # print("retcode =", p.returncode) if p.returncode != 0: print( "\r\nUnable to run ansible 'delete-subnet.yml' for subnet '{0}' in VPC '{1}'\r\n".format(subnet_id, vpc_id)) return False result = True except Exception as e: print( "\r\nUnable to physically create the subnet '{0}' for vpc id '{1}'\r\nException below:\r\n{2}".format(subnet_id, vpc_id, e)) result = False return result def delete_in_db(self, subnet_id, ip_address, vpc_id, host): # delete subnet in db delete_ok = self.db.delete_subnet(subnet_id) if(delete_ok): return { "message": "subnet '{0}' is deleted from host '{1}'".format( ip_address, host), "success": True } else: return { "message": "failed to delete subnet '{0}' from host '{1}'".format( ip_address, host), "success": False }
class TunnelHandler: def __init__(self): self.db = ProviderDb() self.SOUTHBOUND_DIRECTORY = 'overlay_south' def create_tunnel(self, args): customer_id = args["customerId"] vpc_id = args["vpcId"] tunnel_type = str(args["tunnelType"]).lower() # "l2" or "l3" if tunnel_type != "l3" and tunnel_type != "l2": return {"message": "Invalid tunnelType. Either 'l2' or 'l3'. Fix this --> {0}".format(tunnel_type), "success": False} # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} # verify vpc id vpc = self.db.get_vpc_by_id(vpc_id, customer_id) if(vpc == None): return {"message": "No vpc found with id '{0}' for customer '{1}'".format(vpc_id, customer_id), "success": False} # verify transit id transit = self.db.get_transit(customer_id) if(transit == None): return {"message": "No transit found for customer '{0}'".format(customer_id), "success": False} # get db id for transit router tunnel_id = self.db.get_next_tunnel_id() if tunnel_id < 0: return {"message": "A SQL error occured in creating ({0}) tunnel between transit and vpc (id = {1})".format(tunnel_type, vpc_id), "success": False} if tunnel_type == 'l3': if self.create_physically_l3(vpc, transit, customer_id): # save in db if successful return self.create_in_db(transit.transit_id, vpc_id, tunnel_type) else: return {"message": "Unable to physically create the ({0}) tunnel between transit and vpc (id = {1})".format(tunnel_type, vpc_id), "success": False} elif tunnel_type == 'l2': if self.create_physically_l2(vpc, transit, customer_id): # save in db if successful return self.create_in_db(transit.transit_id, vpc_id, tunnel_type) else: return {"message": "Unable to physically create the ({0}) tunnel between transit and vpc (id = {1})".format(tunnel_type, vpc_id), "success": False} def create_physically_l2(self, vpc, transit, customer_id): print("Inside tunnel_handler.create_physically") result = False vpc_host = vpc.host.lower() transit_host = transit.host.lower() # transit = self.db.get_next_transit_id() # if subnet_id < 0: # return {"message": "A SQL error occured in creating subnet '{0}'".format(ip_address), "success": False} try: json_obj = {} json_obj['vpc_id'] = vpc.vpcId json_obj['scalability_factor'] = vpc.scaleFactor json_obj["reliability_factor"] = transit.reliability_factor json_obj["transit_id"] = transit.transit_id vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-vxlan-at-edge.yml", "-l {0}".format(vpc_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-vxlan-at-edge.yml' for transit '{0}' for customer '{1}'\r\n".format(transit.transit_id, customer_id)) return False commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-vxlan-at-transit.yml", "-l {0}".format(transit_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-vxlan-at-transit.yml' for transit '{0}' and vpc '{1}'\r\n".format(transit.transit_id, vpc.vpcId)) return False result = True except Exception as e: print( "\r\nUnable to physically create the tunnel for transit '{0}' and vpc '{1}'\r\nException below:\r\n{2}".format(transit.transit_id, vpc.vpcId, e)) result = False return result def create_physically_l3(self, vpc, transit, customer_id): print("Inside tunnel_handler.create_physically") result = False vpc_host = vpc.host.lower() transit_host = transit.host.lower() # transit = self.db.get_next_transit_id() # if subnet_id < 0: # return {"message": "A SQL error occured in creating subnet '{0}'".format(ip_address), "success": False} try: json_obj = {} json_obj['vpc_id'] = vpc.vpcId json_obj['scalability_factor'] = vpc.scaleFactor json_obj["reliability_factor"] = transit.reliability_factor json_obj["transit_id"] = transit.transit_id vars_json = json.dumps(json_obj) commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-gre-at-edge.yml", "-l {0}".format(vpc_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-gre-at-edge.yml' for transit '{0}' for customer '{1}'\r\n".format(transit.transit_id, customer_id)) return False commands = [ "sudo", "ansible-playbook", "-i", "hosts.ini", "create-gre-at-transit.yml", "-l {0}".format(transit_host), "-e", vars_json ] p = subprocess.Popen(commands, cwd=self.SOUTHBOUND_DIRECTORY) p.wait() if p.returncode != 0: print( "\r\nUnable to run ansible 'create-gre-at-transit.yml' for transit '{0}' and vpc '{1}'\r\n".format(transit.transit_id, vpc.vpcId)) return False result = True except Exception as e: print( "\r\nUnable to physically create the tunnel for transit '{0}' and vpc '{1}'\r\nException below:\r\n{2}".format(transit.transit_id, vpc.vpcId, e)) result = False return result # return True # TODO: Fix this! def create_in_db(self, transit_id, vpc_id, tunnel_type): tunnel_id = self.db.create_tunnel( transit_id, vpc_id, tunnel_type) if tunnel_id < 0: return {"message": "failed to create ({0}) tunnel between transit (id={1}) and vpc (id={2}). Tunnel id is '{3}'".format( tunnel_type, transit_id, vpc_id, tunnel_id), "success": False} else: return {"message": "Created ({0}) tunnel between transit (id={1}) and vpc (id={2}). Tunnel id is '{3}'".format( tunnel_type, transit_id, vpc_id, tunnel_id), "success": True} def delete_tunnel(self, args): customer_id = args["customerId"] tunnel_id = args["tunnelId"] # verify customer id if (self.db.get_customer_by_id(customer_id) == None): return {"message": "No customer found with id '{0}'".format(customer_id), "success": False} tunnel = self.db.get_tunnel(tunnel_id) if tunnel == None: return {"message": "No tunnel found with id '{0}'".format(tunnel_id), "success": False} else: if self.delete_physically_l3(): if self.db.delete_tunnel(tunnel_id): return {"message": "Successfully deleted Tunnel with id '{0}' ".format(tunnel_id), "success": True} else: return {"message": "Failed to delete from db Tunnel with id '{0}' ".format(tunnel_id), "success": False} else: return {"message": "Failed to physically delete Tunnel with id '{0}' ".format(tunnel_id), "success": False} def delete_physically_l3(self): print("Inside tunnel_handler.delete_physically") return True # TODO: Fix this!