Beispiel #1
0
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
Beispiel #2
0
class Startup:
    def __init__(self):
        self.provider_db = ProviderDb()

    def start(self):
        if self.provider_db.create_tables():
            return True
        else:
            return False
Beispiel #3
0
 def __init__(self):
     self.db = ProviderDb()
     self.SOUTHBOUND_DIRECTORY = 'overlay_south'
     self.bgp_config = []
Beispiel #4
0
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
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #9
0
 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
            }
Beispiel #11
0
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!