def test_iaas_auth(provider_id, auth_token):
    status = {
        "command": "test_iaas_auth",
        "status": False,
        "message": "FALSE",
        'provider_id': provider_id
    }

    # Verify Provider
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + provider_id
    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status
    provider_type = get_provider_row['type']

    if provider_type == 1:
        # DigitalOcean Provider. Test token.
        regions = do.get_do_regions(provider_id, auth_token)
        if regions is False:
            status['message'] = "Unable to get DigitalOcean regions"
            return status

    status['message'] = "Success"
    status['status'] = True

    return status
def detach_client(client_id):
    status = {
        'command': 'detach_gw',
        'status': False,
        'message': "Fail",
        "client": client_id
    }

    # Get client, make sure it's legit, die otherwise
    db_conn = wgm_db.connect()
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    get_client_sql = "SELECT * FROM clients WHERE id=" + client_id
    cur.execute(get_client_sql)
    get_client_ret = cur.fetchone()
    if get_client_ret is None:
        status['message'] = "Failed to fetch client"
        return status

    detach_cmd = 'ssh ' + SSH_USER + '@' + get_client_ret[
        'gw_addr'] + ' "wg set wg0 peer ' + get_client_ret[
            'pub_key'] + ' remove"'
    print(detach_cmd)
    p = subprocess.Popen(detach_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    detach_out = p.communicate()[1]
    wg_detach_message = str(detach_out)[2:-1]

    status['message'] = wg_detach_message
    status['status'] = True

    return status
def attach_client(client_id):
    status = {
        'command': 'attach_gw',
        'status': False,
        'message': "Fail",
        "client": client_id
    }

    # Get client, make sure it's legit, die otherwise
    db_conn = wgm_db.connect()
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    get_client_sql = "SELECT * FROM clients WHERE id=" + client_id
    cur.execute(get_client_sql)
    get_client_ret = cur.fetchone()
    if get_client_ret is None:
        status['message'] = "Failed to fetch client"
        return status

    # Client is legit. Let's attach it to the server
    attach_cmd = 'ssh ' + SSH_USER + '@' + get_client_ret[
        'gw_addr'] + ' "wg set wg0 peer ' + get_client_ret[
            'pub_key'] + ' allowed-ips ' + get_client_ret[
                'ipv4_addr'] + '/32,' + get_client_ret['ipv6_addr'] + '/128"'
    #print(attach_cmd)
    p = subprocess.Popen(attach_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    attach_out = p.communicate()[1]
    wg_attach_message = str(attach_out)[2:-1]

    # Client is attached, let's setup it's config. For now we wont touch the <PRIVATEKEY> section
    # the client should already know it's <PRIVATEKEY>
    get_config_sql = "SELECT * FROM templates WHERE name='" + DEFAULT_CLIENT_CONFIG_TEMPLATE + "'"
    cur.execute(get_config_sql)
    get_config_ret = cur.fetchone()
    if get_config_ret is None:
        status['message'] = "Failed to get default config"
        return status

    # Now let's fill the config with our variables
    #print(get_config_ret['data'])
    step1 = get_config_ret['data'].replace('<IPV4>',
                                           get_client_ret['ipv4_addr'])
    step2 = step1.replace('<V4MASK>', '/32')
    step3 = step2.replace('<IPV6>', get_client_ret['ipv6_addr'])
    step4 = step3.replace('<V6MASK>', '/128')
    step5 = step4.replace('<DNS>', get_client_ret['dns_ip'])
    step6 = step5.replace('<GWKEY>', get_client_ret['gw_key'])
    step7 = step6.replace('<GWADDR>', get_client_ret['gw_addr'])
    step8 = step7.replace('<GWPORT>', get_client_ret['gw_port'])
    # Insert Config in DB
    insert_config_sql = "UPDATE clients set client_config='" + step8 + "' WHERE id=" + client_id
    cur.execute(insert_config_sql)
    db_conn.commit()

    status['message'] = wg_attach_message
    status['status'] = True

    return status
def detach_gw(gw, loc):
    status = {
        'command': 'attach_gw',
        'status': False,
        'message': "Fail",
        "gw": gw,
        "loc": loc
    }

    # First make sure this is a valid gateway and location
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_gw_sql = "SELECT * FROM gw_servers WHERE id=" + gw
    cur.execute(get_gw_sql)
    get_gw_ret = cur.fetchone()
    # make sure we have a legit gw
    if get_gw_ret is None:
        status['message'] = "GW Does Not Exist"
        return status

    get_loc_sql = "SELECT * FROM locations WHERE id=" + loc
    cur.execute(get_loc_sql)
    get_loc_ret = cur.fetchone()
    if get_loc_ret is None:
        status['message'] = "Location Does Not Exist"
        return status

    # Stop WireGuard, delete config
    stop_wg_cmd = 'ssh %s %s@%s "wg-quick down wg0"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(stop_wg_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    stop_wg_out = p.communicate()[1]
    delete_config_cmd = 'ssh %s %s@%s "rm -rf /etc/wireguard/wg0.conf"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(delete_config_cmd, shell=True, stdout=subprocess.PIPE)
    delete_config_out = p.communicate()[0]
    #print(gen_key_out)

    status['message'] = str(stop_wg_out)[2:-1]
    status['status'] = True

    return status
def test_dns_auth(provider_id, auth_token):
    status = {"command": "test_dns_auth", "status": False, "message": "FALSE"}

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM dns_providers WHERE id=%s;" % provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']
    #print("Provider Type: "+provider_type)

    if provider_type == "1":
        #print("Cloudflare DNS Provider")

        result = cf.test_cf_auth(auth_token)
        if result['success'] != True:
            status['message'] = "Not an active Cloudflare token"
            return status
        else:
            if result['result']['status'] != "active":
                status['message'] = "Not an active Cloudflare token"
                return status

    else:
        status['message'] = "Unsupported DNS Provider"
        return status

    status['status'] = True
    status['message'] = "Success"

    return status
def setup_dns_records(provider_id):
    status = {
        "command": "setup_dns_records",
        "status": False,
        "message": "FALSE"
    }

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM dns_providers WHERE id=%s;" % provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']
    #print("Provider Type: "+provider_type)

    if provider_type == "1":
        #print("Cloudflare DNS Provider")
        # get auth_token
        get_auth_sql = "SELECT auth_key0 FROM dns_auth_configs WHERE provider=" + str(
            provider_id)
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Can't get Auth Token for Provider"
            return status

        # Auth Acquired
        auth_token = get_auth_row['auth_key0']

        # foreach provider zone, update A records
        get_zones_sql = "SELECT id, value FROM dns_zones WHERE provider=" + str(
            provider_id)
        cur.execute(get_zones_sql)
        #print("Getting Records")
        get_zones_result = cur.fetchall()
        # Foreach zone, get records
        for res in get_zones_result:
            #print("Zone: "+res['value'])
            #print("ID: "+str(res['id']))
            zone_id = str(res['id'])

            # Delete all records for current zone, the unique ids from the provider should remain the same so this doesn't impact current configured servers
            delete_zone_records_sql = "DELETE FROM dns_zone_records WHERE zone=" + zone_id
            cur.execute(delete_zone_records_sql)
            db_conn.commit()

            zone_records = cf.get_dns_records(res['value'], auth_token)
            # foreach record, make entry in DB
            for record in zone_records:
                uid = wgm_db.get_unique_id(64, 'dns_zone_records', db_conn)
                insert_records_sql = "INSERT INTO dns_zone_records (name, type, content, zone, ttl, unique_id, provider_uid) VALUES (%s, %s, %s, %s, %s, %s, %s)"
                cur.execute(insert_records_sql,
                            (record['name'], record['type'], record['content'],
                             res['id'], record['ttl'], uid, record['id']))
                db_conn.commit()

    status['status'] = True
    status['message'] = "Success"
    return status
예제 #7
0
def add_dns_record(zone_id, name, rtype, content, ttl):
    record_name = name
    record_type = rtype
    record_content = content
    record_ttl = ttl
    status = {
        "command": "add_dns_record",
        "status": False,
        "message": "False",
        "record_uid": ""
    }

    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    print("Zone id: %s" % zone_id)
    # Find out Zone specific information
    get_zone_sql = "SELECT * FROM dns_zones WHERE id=" + zone_id
    cur.execute(get_zone_sql)
    get_zone_row = cur.fetchone()
    if get_zone_row is None:
        #print("Zone Not Found")
        status['message'] = "Zone Not Found"
        return status

    # Setup Zone provider_uid
    zone_uid = get_zone_row['value']
    #print("Zone value: "+zone_uid)

    # Find out Provider Specific Information
    get_provider_sql = "SELECT p.type,p.id FROM dns_providers AS p JOIN dns_zones AS z ON z.provider=p.id WHERE z.id=" + zone_id
    # query db for zone
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        #print("Provider Does Not Exist")
        status['message'] = "Provider Does Not Exist"
        return status

    # Set up provider variables
    provider_id = str(get_provider_row['id'])
    provider_type = get_provider_row['type']

    if provider_type == "1":  ## ADD A RECORD FOR A CLOUDFLARE DNS PROVIDER TYPE
        #print("Cloudflare DNS Provider")
        #print("Unique Provider ID: "+provider_id)
        # Now we can get the auth_token
        get_auth_sql = "SELECT auth_key0 FROM dns_auth_configs WHERE provider=" + provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            #print("Auth Token Unavailable")
            status['message'] = "Auth Token Unavailable"
            return status

        # Setup Auth token
        auth_token = get_auth_row['auth_key0']

        # We should have everything we need now to create the record in Cloudflare
        #print("Creating Record in Cloudflare")
        record_uid = cf.add_dns_record(zone_uid, auth_token, record_name,
                                       record_type, record_content, record_ttl)
        if record_uid != "FALSE":
            #print("Successfully created record in Cloudflare with uid: "+record_uid)
            #print("---SUCCESS---")
            #print("Updating Database")
            new_unique_id = wgm_db.get_unique_id(64, 'dns_zone_records',
                                                 db_conn)
            sql = "INSERT INTO dns_zone_records (name, type, content, zone, ttl, unique_id, provider_uid) VALUES (%s, %s, %s, %s, %s, %s, %s)"
            cur.execute(sql, (record_name, record_type, record_content,
                              zone_id, record_ttl, new_unique_id, record_uid))
            db_conn.commit()
            #print("DB Updated")
        else:
            #print("---FAILED---")
            status['message'] = "Failed to Create DNS Record"
            return status

    else:
        #print("Unknown Provider Type, Failing")
        status['message'] = "Unknown Provider Type"
        return status

    status['message'] = "Success"
    status['status'] = True
    status['record_uid'] = record_uid
    return status
예제 #8
0
def update_dns_record(zone_id, record_id, name, rtype, content, ttl):
    record_name = name
    record_type = rtype
    record_content = content
    record_ttl = ttl
    status = {
        "command": "update_dns_record",
        "status": False,
        "message": "False"
    }

    # Should have everything we need. Let's find out what type of provider this is.
    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Zone id: %s" % zone_id)
    # Find out Zone specific information
    get_zone_sql = "SELECT * FROM dns_zones WHERE id=" + zone_id
    cur.execute(get_zone_sql)
    get_zone_row = cur.fetchone()
    if get_zone_row is None:
        status['message'] = "Zone Not Found"
        return status

    # Setup Zone provider_uid
    zone_uid = get_zone_row['value']
    #print("Zone value: "+zone_uid)

    # Find out Provider Specific Information
    get_provider_sql = "SELECT p.type,p.id FROM dns_providers AS p JOIN dns_zones AS z ON z.provider=p.id WHERE z.id=" + zone_id
    # query db for zone
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    # Set up provider variables
    provider_id = str(get_provider_row['id'])
    provider_type = get_provider_row['type']

    # Find out Record UID
    get_record_sql = "SELECT provider_uid FROM dns_zone_records WHERE id=" + record_id
    cur.execute(get_record_sql)
    get_record_row = cur.fetchone()
    if get_record_row is None:
        status['message'] = "Record has no uid"
        return status

    # Setup record variables
    record_uid = get_record_row['provider_uid']

    if provider_type == "1":  ## UPDATE A RECORD FOR A CLOUDFLARE DNS PROVIDER TYPE
        #print("Cloudflare DNS Provider")
        #print("Unique Provider ID: "+provider_id)
        # Now we can get the auth_token
        get_auth_sql = "SELECT auth_key0 FROM dns_auth_configs WHERE provider=" + provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Auth Token Unavailable"
            return status

        # Setup Auth Token
        auth_token = get_auth_row['auth_key0']

        success = cf.update_dns_record(zone_uid, record_uid, auth_token,
                                       record_name, record_type,
                                       record_content, record_ttl)

        if success == True:
            #print("---SUCCESS---")
            #print("Updating db")
            update_rec_sql = "UPDATE dns_zone_records SET name = %s, type = %s, content = %s, ttl = %s WHERE id = %s"
            cur.execute(update_rec_sql,
                        (record_name, record_type, record_content, record_ttl,
                         record_id))
            db_conn.commit()
            #print("DB Updated")

        else:
            status['message'] = "Failed to update DNS record"
            return status

    else:
        status['message'] = "Provider Type Unknown"
        return status

    status['status'] = True
    status['message'] = "Success"

    return status
예제 #9
0
def delete_dns_record(zone_id, record_id):
    status = {
        "command": "delete_dns_record",
        "status": False,
        "message": "False"
    }

    # Find out what kind of provider this is.
    # Should have everything we need. Let's find out what type of provider this is.
    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Zone id: %s" % zone_id)
    # Find out Zone specific information
    get_zone_sql = "SELECT * FROM dns_zones WHERE id=" + str(zone_id)
    cur.execute(get_zone_sql)
    get_zone_row = cur.fetchone()
    if get_zone_row is None:
        #print("Zone Not Found")
        status['message'] = "Zone Not Found"
        return status

    # Setup Zone provider_uid
    zone_uid = get_zone_row['value']
    #print("Zone value: "+zone_uid)

    # Find out Provider Specific Information
    get_provider_sql = "SELECT p.type,p.id FROM dns_providers AS p JOIN dns_zones AS z ON z.provider=p.id WHERE z.id=" + str(
        zone_id)
    # query db for zone
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    # Set up provider variables
    provider_id = str(get_provider_row['id'])
    provider_type = get_provider_row['type']

    # Find Record provider_uid
    get_record_sql = "SELECT provider_uid FROM dns_zone_records WHERE id=" + str(
        record_id)
    cur.execute(get_record_sql)
    get_record_row = cur.fetchone()
    if get_record_row is None:
        status['message'] = "Provider uid does not exist"
        return status

    record_uid = get_record_row['provider_uid']

    if provider_type == "1":  ## DELETE A RECORD FOR A CLOUDFLARE DNS PROVIDER TYPE
        #print("Cloudflare provider")
        #print("Unique Provider ID: "+provider_id)
        # Now we can get the auth_token
        get_auth_sql = "SELECT auth_key0 FROM dns_auth_configs WHERE provider=" + str(
            provider_id)
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Auth Token Unavailable"
            return status

        # Setup Auth Token
        auth_token = get_auth_row['auth_key0']

        # Deleting DNS Record
        #print("Deleting Record in Cloudflare")
        success = cf.delete_dns_record(zone_uid, record_uid, auth_token)

        if success == True:
            #print("---SUCCESS---")
            #print("Deleting from DB")
            delete_rec_sql = "DELETE FROM dns_zone_records WHERE id=" + str(
                record_id)
            cur.execute(delete_rec_sql)
            db_conn.commit()
        else:
            status['Message'] = "Failed to delete DNS Record"
            return status

    else:
        status['message'] = "Unknown Provider"
        return status

    status['status'] = True
    status['message'] = "Success"

    return status
def destroy_dns_server(dns_server_id):
    status = {"status": False, "message": "FALSE"}

    # Make sure this is a valid server_id
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    get_dns_server_sql = "SELECT * FROM dns_servers WHERE id=" + dns_server_id
    cur.execute(get_dns_server_sql)
    get_dns_server_row = cur.fetchone()
    if get_dns_server_row is None:
        status['message'] = "Invalid DNS Server ID"
        return status

    provider_id = get_dns_server_row['provider']
    provider_uid = get_dns_server_row['provider_uid']

    print("Provider: " + str(provider_id))
    print("Provider UID: " + provider_uid)

    # Now let's make sure this is a legit provider and get type
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + str(
        provider_id)
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    if get_provider_row is None:
        status['message'] = "Provider is invalid"
        return status

    provider_type = get_provider_row['type']

    print("Provider Type: " + str(provider_type))

    if provider_type == 1:
        print("DigitalOcean DNS Server")
        # Get Auth Token
        get_auth_sql = "SELECT auth_key0 FROM iaas_auth_configs WHERE provider=" + str(
            provider_id)
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Failed to get Auth Token"
            return status

        auth_token = get_auth_row['auth_key0']

        result = do.destroy_do_droplet(provider_uid, auth_token)
        if result == False:
            status['message'] = "Failed to destroy DNS Server"
            return status

    else:
        status['message'] = "Unknown IaaS Provider"
        return status

    # Update DB
    delete_dns_sql = "DELETE FROM dns_servers WHERE id=" + str(dns_server_id)
    cur.execute(delete_dns_sql)
    db_conn.commit()

    status['status'] = True
    status['message'] = "Success"
    return status
def create_dns_server(name, dns_type, provider_id, provider_image,
                      provider_zone):
    status = {"status": False, "message": "FALSE"}

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']

    # Now check to make sure provider image is valid, die quickly otherwise.
    get_image_sql = "SELECT * FROM iaas_vm_images WHERE provider=%s AND id=%s"
    cur.execute(get_image_sql, (provider_id, provider_image))
    get_image_row = cur.fetchone()
    if get_image_row is None:
        status['message'] = "Image does not exist"
        return status

    image_value = get_image_row['value']

    # Now check to make sure provider zone is valid, die quickly otherwise.
    get_zone_sql = "SELECT * FROM iaas_zones WHERE id=%s AND provider=%s"
    cur.execute(get_zone_sql, (provider_zone, provider_id))
    get_zone_row = cur.fetchone()
    if get_zone_row is None:
        status['message'] = "Image does not exist"
        return status

    zone_value = get_zone_row['value']

    if provider_type == 1:
        #print("DigitalOcean IaaS Provider")
        # THERE ARE SOME DEFAULTS ASSUMED AT THE MOMENT
        ipv6 = True
        backups = False
        size = "s-1vcpu-2gb"
        tags = ["wgm", "dns"]

        # Get Auth token
        get_auth_sql = "SELECT * FROM iaas_auth_configs WHERE provider=" + provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Unable to get Auth Token"
            return status

        auth_token = get_auth_row['auth_key0']

        db_keys = [
            get_auth_row['ssh_key0'], get_auth_row['ssh_key1'],
            get_auth_row['ssh_key2']
        ]
        config_keys = []
        for key in db_keys:
            if key != "-":
                ssh = sshpubkeys.SSHKey(key)
                config_keys.append(ssh.hash_md5().replace('MD5:', ''))

        config = {
            "token": auth_token,
            "name": name,
            "region": zone_value,
            "image": image_value,
            "size": size,
            "ssh_keys": config_keys,
            "tags": tags,
            "ipv6": ipv6,
            "backups": ipv6
        }

        #print(config)
        print("Deploying DNS Server")
        result = do.create_do_droplet(config)
        server = result['droplet']
        if server is None:
            status['message'] = result['message']
            return status

    else:
        print("Unknown IaaS Provider")
        status['message'] = "Unknown IaaS Provider"
        return status

    # Update DB
    new_unique_id = wgm_db.get_unique_id(64, 'dns_servers', db_conn)
    new_dns_server_sql = "INSERT INTO dns_servers (dns_name,type,ipv4_addr,ipv6_addr,unique_id,provider,provider_uid) VALUES (%s, %s, %s, %s, %s, %s, %s)"
    cur.execute(new_dns_server_sql,
                (name, dns_type, server.ip_address, server.ip_v6_address,
                 new_unique_id, provider_id, str(server.id)))
    db_conn.commit()

    status['status'] = True
    status['message'] = "Success"
    return status
def create_gw_server(name, dns_zone, provider_id, provider_image,
                     provider_zone):
    status = {
        "command": "create_gw_server",
        "status": False,
        "message": "FALSE"
    }
    vm_exists = False

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']

    # Now check to make sure dns_zone is valid, die quickly otherwise
    get_dns_zone_sql = "SELECT * FROM dns_zones WHERE id=" + dns_zone
    cur.execute(get_dns_zone_sql)
    get_dns_zone_ret = cur.fetchone()
    if get_dns_zone_ret is None:
        status['message'] = "DNS Zone Does Not Exist"
        return status

    # Now check to makesure the dns_provider is valid, die quickly otherwise
    get_dns_provider_sql = "SELECT * FROM dns_providers WHERE id=" + str(
        get_dns_zone_ret['provider'])
    cur.execute(get_dns_provider_sql)
    get_dns_provider_ret = cur.fetchone()
    if get_dns_provider_ret is None:
        status['message'] = "DNS Provider Does Not Exist"
        return status

    dns_provider_id = str(get_dns_zone_ret['provider'])
    dns_provider_type = get_dns_provider_ret['type']

    # Now check to make sure provider image is valid, die quickly otherwise.
    get_image_sql = "SELECT * FROM iaas_vm_images WHERE provider=%s AND id=%s"
    cur.execute(get_image_sql, (provider_id, provider_image))
    get_image_row = cur.fetchone()
    if get_image_row is None:
        status['message'] = "Image does not exist"
        return status

    image_value = get_image_row['value']

    # Now check to make sure provider zone is valid, die quickly otherwise.
    get_zone_sql = "SELECT * FROM iaas_zones WHERE id=%s AND provider=%s"
    cur.execute(get_zone_sql, (provider_zone, provider_id))
    get_zone_row = cur.fetchone()
    if get_zone_row is None:
        status['message'] = "Image does not exist"
        return status

    zone_value = get_zone_row['value']

    if provider_type == 1:
        print("DigitalOcean IaaS Provider")
        #print("DigitalOcean IaaS Provider")
        # THERE ARE SOME DEFAULTS ASSUMED AT THE MOMENT
        ipv6 = True
        backups = False
        size = "s-1vcpu-2gb"
        tags = ["wgm", "wg", "vpn"]

        # Get Auth token
        get_auth_sql = "SELECT * FROM iaas_auth_configs WHERE provider=" + provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Unable to get Auth Token"
            return status

        auth_token = get_auth_row['auth_key0']

        db_keys = [
            get_auth_row['ssh_key0'], get_auth_row['ssh_key1'],
            get_auth_row['ssh_key2']
        ]
        config_keys = []
        for key in db_keys:
            if key != "-":
                ssh = sshpubkeys.SSHKey(key)
                config_keys.append(ssh.hash_md5().replace('MD5:', ''))

        config = {
            "token": auth_token,
            "name": name,
            "region": zone_value,
            "image": image_value,
            "size": size,
            "ssh_keys": config_keys,
            "tags": tags,
            "ipv6": ipv6,
            "backups": ipv6
        }
        #print(config)

        # Build Server
        #print("Deploying GW Server")
        result = do.create_do_droplet(config)
        server = result['droplet']
        if result['droplet'] is None:
            status['message'] = result['message']
            return status

    else:
        status['message'] = "Unsupported IaaS Provider"
        return status

    # Server is deployed, let's setup DNS
    if dns_provider_type == "1":
        print("Cloudflare DNS Provider")
        # Some Defaults are Assumed
        rtype = "A"
        ttl = "120"

        #def add_dns_record(zone_id,name,rtype,content,ttl)
        record_status = dns.add_dns_record(dns_zone, name, rtype,
                                           server.ip_address, ttl)
        if record_status['status'] == False:
            status['message'] = "Failed to Create DNS Record"
            # Failed to create the DNS Record, let's destroy the droplet
            result = do.destroy_do_droplet(str(server.id), auth_token)
            if result == False:
                status[
                    'message'] = "Failed to create the DNS Record, Also Failed to Destroy DigitalOcean Droplet"
                return status

        #print(record_status['record_uid'])

    else:
        status['message'] = "Unsupported DNS Provider"

    # Okay, server was successfully deployed and the DNS record was successfully created. Let's update the DB
    new_unique_id = wgm_db.get_unique_id(64, 'gw_servers', db_conn)
    new_gw_server_sql = "INSERT INTO gw_servers (name,pub_ipv4_addr,pub_ipv6_addr,dns_record_uid,provider,provider_uid,dns_zone, unique_id, dns_provider) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"
    cur.execute(new_gw_server_sql,
                (name, server.ip_address, server.ip_v6_address,
                 record_status['record_uid'], provider_id, server.id, dns_zone,
                 new_unique_id, dns_provider_id))
    db_conn.commit()

    status['message'] = "Success"
    status['status'] = True

    return status
				if int(result.group(1)) <= 4:
					connected_count += 1

	print('has connected: ' + str(has_connected_count))
	print('still connected: ' + str(connected_count))

	new_list = [net,location,server,peer_count,has_connected_count,connected_count]
	wg_usage_table.append(new_list)

	return


# Get Network Servers
for net in NETWORKS:
	# Get client, make sure it's legit, die otherwise
	db_conn = wgm_db.connect()
	cur1 = db_conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
	# cur2 = db_conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
	get_network_servers_sql = "SELECT * FROM gw_servers gw JOIN rel_net_loc_gw rel ON rel.gw_id=gw.id JOIN locations loc ON rel.loc_id=loc.id WHERE rel.net_id="+str(net)
	cur1.execute(get_network_servers_sql)
	server = cur1.fetchone()

	while server:
		print("-----------------------")
		print("| SERVER "+str(server['id'])+": "+server['name'].upper()+" : "+server['pub_ipv4_addr']+" |")
		print("-----------------------")
		cmd = os.system("ssh root@%s \"wg\" > %s" % (server['pub_ipv4_addr'], wg_output_path))
		parsewg(str(net),str(server['geo_name']),str(server['pub_ipv4_addr']),wg_output_path,wg_usage_table)

		# Next Server
		server = cur1.fetchone()
def attach_gw(gw, loc):
    status = {
        'command': 'attach_gw',
        'status': False,
        'message': "Fail",
        "gw": gw,
        "pub_key": ""
    }

    #print("attaching gw")
    # First make sure this is a valid gateway and location
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_gw_sql = "SELECT * FROM gw_servers WHERE id=" + gw
    cur.execute(get_gw_sql)
    get_gw_ret = cur.fetchone()
    # make sure we have a legit gw
    if get_gw_ret is None:
        status['message'] = "GW Does Not Exist"
        return status

    get_loc_sql = "SELECT * FROM locations WHERE id=" + loc
    cur.execute(get_loc_sql)
    get_loc_ret = cur.fetchone()
    if get_loc_ret is None:
        status['message'] = "Location Does Not Exist"
        return status

    # Location and GW exist. Get IP Addresses for GW
    get_net_sql = "SELECT * FROM networks WHERE id=" + str(
        get_loc_ret['network_id'])
    cur.execute(get_net_sql)
    get_net_ret = cur.fetchone()
    if get_net_ret is None:
        status['message'] = "Failed to find network"
        return status

    #mask_pattern = re.compile("(/\d{1,3})")
    ipv4_address = get_net_ret['ipv4_gateway']
    v4_network = get_net_ret['ipv4_netmask']
    m = re.search(r'(/\d{1,3})', v4_network)
    v4_mask = m.groups()[0]

    ipv6_address = get_net_ret['ipv6_gateway']
    v6_network = get_net_ret['ipv6_netmask']
    m = re.search(r'(/\d{1,3})', v6_network)
    v6_mask = m.groups()[0]

    # Should have all the network info we need. Now let's generate the initial wireguard keys
    gen_keys = 'ssh %s %s@%s "wg genkey | tee private.key | wg pubkey > public.key"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(gen_keys, shell=True, stdout=subprocess.PIPE)
    gen_key_out = p.communicate()[0]
    #print(gen_key_out)
    get_priv_key = 'ssh %s %s@%s "cat /root/private.key"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(get_priv_key, shell=True, stdout=subprocess.PIPE)
    get_priv_key_out = p.communicate()[0]
    priv_key = str(get_priv_key_out)[2:-3]
    #print("Private: "+str(get_priv_key_out))
    #print("Private: "+priv_key)

    get_pub_key = 'ssh %s %s@%s "cat /root/public.key"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(get_pub_key, shell=True, stdout=subprocess.PIPE)
    get_pub_key_out = p.communicate()[0]
    pub_key = str(get_pub_key_out)[2:-3]
    #print("Public: "+str(get_pub_key_out))
    #print("Public: "+pub_key)

    # Now get the wg_gw_config_template from the DB
    get_config_sql = "SELECT * FROM templates WHERE name='" + DEFAULT_CONFIG_TEMPLATE + "'"
    cur.execute(get_config_sql)
    get_config_ret = cur.fetchone()
    if get_config_ret is None:
        status['message'] = "Failed to get default config"
        return status

    # Now let's fill the config with our variables
    #print(get_config_ret['data'])
    step1 = get_config_ret['data'].replace('<IPV4>', ipv4_address)
    step2 = step1.replace('<V4MASK>', v4_mask)
    step3 = step2.replace('<IPV6>', ipv6_address)
    step4 = step3.replace('<V6MASK>', v6_mask)
    step5 = step4.replace('<LISTENPORT>', GW_PORT)
    step6 = step5.replace('<PRIVATEKEY>', priv_key)

    #print(step6)
    temp = open(TEMP_CONFIG_FILE, "w")
    temp.write(step6)
    temp.write('\r\n')
    temp.close()

    # Write config file and start the interface
    write_config_cmd = 'scp %s %s@%s:/etc/wireguard/wg0.conf' % (
        TEMP_CONFIG_FILE, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(write_config_cmd, shell=True, stdout=subprocess.PIPE)
    write_out = p.communicate()[0]
    #print(str(write_out))
    start_wg_cmd = 'ssh %s %s@%s "wg-quick up wg0"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(start_wg_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    start_out = p.communicate()[1]
    wg_start_message = str(start_out)[2:-1]
    #print(wg_start_message)
    os.remove(TEMP_CONFIG_FILE)

    # Make sure WireGuard starts at boot
    systemd_cmd = 'ssh %s %s@%s "systemctl enable wg-quick@wg0"' % (
        SSH_OPTS, SSH_USER, get_gw_ret['pub_ipv4_addr'])
    p = subprocess.Popen(systemd_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    systemd_out = p.communicate()[1]

    # Update GW in database with port, ipv4, ipv6, and public key
    update_gw_sql = "UPDATE gw_servers SET port='" + GW_PORT + "', ipv4_addr='" + ipv4_address + "', ipv6_addr='" + ipv6_address + "', pub_key='" + pub_key + "' WHERE id=" + gw
    cur.execute(update_gw_sql)
    db_conn.commit()

    status['status'] = True
    status['message'] = wg_start_message
    status['pub_key'] = pub_key

    return status
def setup_iaas_images(provider_id):
    status = {
        "command": "setup_iaas_images",
        "status": False,
        "message": "FALSE",
        'provider_id': provider_id
    }

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']

    if provider_type == 1:
        #print("DigitalOcean IaaS Provider")

        # provider is digitalocean type, let's get the token
        get_auth_sql = "SELECT auth_key0 FROM iaas_auth_configs WHERE provider=%s" % provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "No Auth Token Found"
            return status
        auth_token = get_auth_row['auth_key0']

        # Get current images
        current_images = dict()
        get_cur_images_sql = "SELECT * FROM iaas_vm_images"
        cur.execute(get_cur_images_sql)
        get_cur_images_ret = cur.fetchall()
        for image in get_cur_images_ret:
            current_images[image['id']] = image['value']
            #print(image['value'])

        #print(current_images)

        # Let's get the relevant available images and update the database
        new_images = do.get_do_images(provider_id, auth_token)
        new_image_values = list()
        for image in new_images:
            new_image_values.append(str(image.id))
            matching_record = False
            for key in current_images:
                if current_images[key] == str(image.id):
                    matching_record = True
                    # This is an image we already know about. Update name
                    #print("Image Name: "+image.name)
                    #print("Record ID: "+str(key))
                    update_image_sql = "UPDATE iaas_vm_images SET name = %s WHERE id=%s"
                    cur.execute(update_image_sql, (image.name, key))
                    db_conn.commit()
            if matching_record is False:
                # No matching record currently, make a new one
                new_uid = wgm_db.get_unique_id(64, 'iaas_vm_images', db_conn)
                new_image_sql = "INSERT INTO iaas_vm_images (name,value,unique_id,provider) VALUES (%s, %s, %s, %s)"
                cur.execute(new_image_sql,
                            (image.name, str(image.id), new_uid, provider_id))
                db_conn.commit()

        # Now let's cleanup the old images
        for key in current_images:
            if current_images[key] not in new_image_values:
                # Old image, delete it
                delete_image_sql = "DELETE FROM iaas_vm_images WHERE id=" + str(
                    key)
                cur.execute(delete_image_sql)
                db_conn.commit()

    status['status'] = True
    status['message'] = "Success"
    return status
def destroy_gw_server(server_id):
    status = {
        "commad": "destroy_gw_server",
        "status": False,
        "message": "FALSE"
    }

    # Get the server information
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    get_server_sql = "SELECT * FROM gw_servers WHERE id=" + server_id
    cur.execute(get_server_sql)
    get_server_ret = cur.fetchone()
    if get_server_ret is None:
        status['message'] = "Failed to find GW Server"
        return status

    # Delete the Server in IaaS
    # Get Provider Type
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + str(
        get_server_ret['provider'])
    cur.execute(get_provider_sql)
    get_provider_ret = cur.fetchone()
    if get_provider_ret is None:
        status['message'] = "Failed to find IaaS Provider"
        return status

    provider_type = get_provider_ret['type']

    if provider_type == 1:
        print("DigitalOcean Provider")
        # get Auth
        get_auth_sql = "SELECT auth_key0 FROM iaas_auth_configs WHERE provider=" + str(
            get_server_ret['provider'])
        cur.execute(get_auth_sql)
        get_auth_ret = cur.fetchone()
        if get_auth_ret is None:
            status['message'] = "Failed to get Auth Token"

        auth_token = get_auth_ret['auth_key0']

        # Delete DO VM
        result = do.destroy_do_droplet(get_server_ret['provider_uid'],
                                       auth_token)
        print(result)
        if result is False:
            status['message'] = "Failed to destroy DigitalOcean Droplet"
            return status

    else:
        status['message'] = "Unsupported IaaS Provider"
        return status

    # Delete the DNS record
    # Get record id
    get_dns_record_sql = "SELECT * FROM dns_zone_records WHERE provider_uid='" + get_server_ret[
        'dns_record_uid'] + "' AND zone=" + str(get_server_ret['dns_zone'])
    cur.execute(get_dns_record_sql)
    get_dns_record_ret = cur.fetchone()
    if get_dns_record_ret is None:
        status['message'] = "Failed to get DNS Record"
        return status

    dns_result = dns.delete_dns_record(get_dns_record_ret['zone'],
                                       get_dns_record_ret['id'])
    print(dns_result)
    if dns_result['status'] is False:
        status['message'] = "Failed to delete DNS Record"
        return status

    # VM and DNS record removed Update DB
    delete_server_sql = "DELETE FROM gw_servers WHERE id=" + server_id
    cur.execute(delete_server_sql)
    db_conn.commit()

    status['message'] = "Success"
    status['status'] = True

    return status
def setup_dns_zones(provider_id):
    status = {
        "command": "setup_dns_zones",
        "status": False,
        "message": "FALSE"
    }

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM dns_providers WHERE id=%s;" % provider_id

    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status

    provider_type = get_provider_row['type']
    #print("Provider Type: "+provider_type)

    if provider_type == "1":
        #print("Cloudflare Provider")
        current_zones = list()
        # Get current zones
        get_cur_zones_sql = "SELECT * FROM dns_zones WHERE provider=" + str(
            provider_id)
        cur.execute(get_cur_zones_sql)
        get_cur_zones_ret = cur.fetchall()
        #print(len(get_cur_zones_ret))
        for cur_zone in get_cur_zones_ret:
            #print(cur_zone['name'])
            current_zones.append(cur_zone['value'])

        #print(current_zones)

        get_auth_sql = "SELECT auth_key0 FROM dns_auth_configs WHERE provider=%s" % provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "Can't get Auth Token for Provider"
            return status

        # Auth Acquired
        auth_token = get_auth_row['auth_key0']
        # Get Zones from DNS Provider
        zones = cf.get_dns_zones(auth_token)

        # Update with New Zones Only
        new_zones = list()
        for zone in zones:
            new_zones.append(zone['id'])
            if zone['id'] not in current_zones:
                uid = wgm_db.get_unique_id(64, 'dns_zones', db_conn)
                #print("Found Zone: "+zone['name'])
                insert_zone_sql = "INSERT INTO dns_zones (name, value, unique_id, provider) VALUES(%s, %s, %s, %s)"
                cur.execute(insert_zone_sql,
                            (zone['name'], zone['id'], uid, provider_id))
                db_conn.commit()

        # Cleanup Old Zones
        for zone in current_zones:
            if zone not in new_zones:
                print("Old Zone")
                get_zone_id_sql = "SELECT id FROM dns_zones WHERE value='" + zone + "'"
                cur.execute(get_zone_id_sql)
                get_zone_id_ret = cur.fetchone()
                zid = get_zone_id_ret['id']
                delete_zone_records_sql = "DELETE FROM dns_zone_records WHERE zone=" + str(
                    zid)
                cur.execute(delete_zone_records_sql)
                db_conn.commit()
                cur.execute("DELETE FROM dns_zones WHERE id=" + str(zid))
                db_conn.commit()

    else:
        status['message'] = "Provider type unsupported"
        return status

    status['status'] = True
    status['message'] = "Success"

    return status
def setup_iaas_zones(provider_id):
    status = {
        "command": "setup_iaas_zones",
        "status": False,
        "message": "FALSE",
        'provider_id': provider_id
    }

    # Now check to make sure provider id is valid, die quickly otherwise.
    db_conn = wgm_db.connect()
    #print("DB Connection Open")
    cur = db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    #print("Provider id: %s" % provider_id)
    get_provider_sql = "SELECT * FROM iaas_providers WHERE id=" + provider_id
    # query db for provider
    cur.execute(get_provider_sql)
    get_provider_row = cur.fetchone()
    # make sure we have a legit digitalocean provider
    if get_provider_row is None:
        status['message'] = "Provider Does Not Exist"
        return status
    provider_type = get_provider_row['type']

    if provider_type == 1:
        #print("DigitalOcean IaaS Provider")

        # provider is digitalocean type, let's get the token
        get_auth_sql = "SELECT auth_key0 FROM iaas_auth_configs WHERE provider=" + provider_id
        cur.execute(get_auth_sql)
        get_auth_row = cur.fetchone()
        if get_auth_row is None:
            status['message'] = "No Auth Token Found"
            return status
        auth_token = get_auth_row['auth_key0']

        # Get current zones(regions) to check against
        get_cur_zones = "SELECT * FROM iaas_zones WHERE provider=" + provider_id
        cur.execute(get_cur_zones, (provider_id))
        get_cur_zones_ret = cur.fetchall()

        cur_zones = list()
        for zone in get_cur_zones_ret:
            cur_zones.append(zone['value'])
        #print(cur_zones)

        # Let's get the available regions and update the database
        regions = do.get_do_regions(provider_id, auth_token)
        new_slugs = list()
        for region in regions:
            new_slugs.append(region.slug)
            if region.slug not in cur_zones:
                # This is a new slug, add it to the DB
                new_uid = wgm_db.get_unique_id(64, 'iaas_zones', db_conn)
                new_slug_sql = "INSERT INTO iaas_zones (name, value,unique_id,provider) VALUES (%s, %s, %s, %s)"
                cur.execute(new_slug_sql,
                            (region.name, region.slug, new_uid, provider_id))
                db_conn.commit()

        # Great, now let's delete zones that don't exist anymore
        for zone in cur_zones:
            if zone not in new_slugs:
                #print(zone)
                delete_zone_sql = "DELETE FROM iaas_zones WHERE value='" + zone + "' AND provider=" + provider_id
                cur.execute(delete_zone_sql)
                db_conn.commit()

    else:
        status['message'] = "Provider Type Unknown"
        return status

    status['status'] = True
    status['message'] = "Success"
    return status