Esempio n. 1
0
def subnet_delete_api(subnetid=None):
    """
    Implementation Notes
      Deletes a subnet.

    Response Messages (Status 200)

    Parameters
      subnetId (string, required): The subnet uuid to act on.
    """
    try:
        if not subnetid:
            return err_return('subnetId is required', 'ParameterInvalid', '',
                              HTTP_BAD_REQUEST)
        cidr = subnet_db_get_one('cidr', id=subnetid)
        if not cidr:
            return err_return('subnetId does not exist', 'ParameterInvalid',
                              '', HTTP_NOT_FOUND)

        if port_ip_db_get_all(subnet_id=subnetid):
            return err_return('subnet in use', 'ParameterInvalid', '',
                              HTTP_BAD_REQUEST)
        networkid = subnetid_to_networkid(subnetid)
        external = network_db_get_one('external', id=networkid)
        log.debug('external=%s' % external)
        if external:
            ret, desc = delete_subnet_by_networkid(networkid)
            if not ret:
                return err_return(desc, 'SubnetDeleteFail', '',
                                  HTTP_BAD_REQUEST)
            return Response(), HTTP_OK
        vl2lcid = yynetworkid_to_lcvl2id(networkid)
        nets = [{
            "prefix": VFW_TOR_LINK_NET_PRE,
            "netmask": VFW_TOR_LINK_NET_MASK
        }]
        subnets = get_subnets_by_network(networkid)
        for subnet in subnets:
            if str(subnet['id']) == subnetid:
                continue
            cidr = subnet['cidr'].split('/')
            nets.append({"prefix": cidr[0], "netmask": int(cidr[1])})
        nw_name = network_db_get_one('name', id=networkid)
        payload = json.dumps({"name": nw_name, "nets": nets})
        r = lcapi.patch(conf.livecloud_url + '/v1/vl2s/%s' % vl2lcid,
                        data=payload)
        if r.status_code != HTTP_OK:
            err = r.json()['DESCRIPTION']
            log.error(r.json()['DESCRIPTION'])
            return err_return(err, 'Fail', '', HTTP_BAD_REQUEST)
        subnet_db_delete(id=subnetid)
        return Response(), HTTP_OK
    except Exception as e:
        log.error(e)
        return Response(json.dumps(NEUTRON_500)), HTTP_INTERNAL_SERVER_ERROR
Esempio n. 2
0
def yynetworkid_to_lcvl2id(networkid):
    lcuuid = network_db_get_one('lcuuid', id=networkid)
    if not lcuuid:
        return None
    log.debug('vl2lcuuid=%s' % lcuuid)
    r = lcapi.get(conf.livecloud_url + '/v1/vl2s?lcuuid=' + lcuuid)
    log.debug('get vl2 ret=%s' % r.json())
    data = r.json().get('DATA')
    if not data:
        return None
    else:
        return data.get('ID', None)
Esempio n. 3
0
def delete_subnet_by_networkid(networkid):
    try:
        network = network_db_get_one("*", id=networkid)
        if not network:
            return False, 'Network not found'
        if not network['external']:
            subnet_db_delete(network_id=networkid)
            return True, ''
        alloc_pools = subnet_db_get_one("allocation_pools",
                                        network_id=networkid)
        if not alloc_pools:
            return True, ''
        alloc_pools = json.loads(alloc_pools)
        ips = alloc_pools_to_ip_list(alloc_pools)
        sql = "SELECT ip FROM ip_resource_v2_2 WHERE vifid!=0 AND ip in ('-1',"
        for ip in ips:
            sql += "'%s'," % ip
        sql = sql[:-1]
        sql += ")"
        log.debug('sql=%s' % sql)
        with MySQLdb.connect(**LCDB_INFO) as cursor:
            cursor.execute(sql)
            items = cursor.fetchall()
        if items:
            return False, 'Some IP in use'
        sql = "UPDATE ip_resource_v2_2 SET userid=0 WHERE ip in ('-1',"
        for ip in ips:
            sql += "'%s'," % ip
        sql = sql[:-1]
        sql += ")"
        log.debug('sql=%s' % sql)
        with MySQLdb.connect(**LCDB_INFO) as cursor:
            cursor.execute(sql)
        subnet_db_delete(network_id=networkid)
        return True, ''
    except Exception as e:
        log.error(e)
        return False, 'Internal server error'
Esempio n. 4
0
def subnet_create_api():
    """
    Implementation Notes
      Creates a subnet on a network.

    Response Class (Status 201)
      Subnet {
        subnetId (string, optional): Subnet uuid.
        subnetName (string, optional): Subnet name, a user readable name.
        networkId (string, optional): Network uuid.
        cidr (string, optional): The CIDR of subnet.
        allocation_pools (Array[inline_model], optional):
          The start and end addresses for the allocation pools.
        gatewayIp (string, required): The gateway IP address.
        dnsNameservers (Array[string], optional):
          A list of DNS name servers for the subnet.
      }
      inline_model {
        start (string, optional): Start IP address. ,
        end (string, optional): End IP address.
      }

    Parameters
      Subnet (body, required): Subnet description
    """
    try:
        req = models.Subnet(request.json)
        req.validate()
    except Exception as e:
        return err_return('Parameter Invalid', 'ParameterInvalid', '',
                          HTTP_BAD_REQUEST)
    try:
        if not req.network_id:
            return err_return('networkid is required', 'ParameterInvalid', '',
                              HTTP_BAD_REQUEST)
        if not req.subnet_id:
            req_id = str(uuid.uuid4())
        else:
            req_id = req.subnet_id
            sb_name = subnet_db_get_one('name', id=req_id)
            if sb_name:
                return err_return('id(%s) in use by %s' % (req_id, sb_name),
                                  'ParameterInvalid', '', HTTP_BAD_REQUEST)
        if req.subnet_name:
            if len(req.subnet_name) > NAME_MAX_LEN:
                return err_return('Length of name must be less than 255',
                                  'ParameterInvalid', '', HTTP_BAD_REQUEST)
        else:
            req.subnet_name = ''

        external = network_db_get_one('external', id=req.network_id)
        if external is None:
            return err_return("networkid does not exist", "ParameterInvalid",
                              "", HTTP_BAD_REQUEST)
        if not req.dns_nameservers:
            req.dns_nameservers = []
        if not req.allocation_pools:
            req.allocation_pools = []
        allocation_pools = []
        for all_pool in req.allocation_pools:
            allocation_pools.append(all_pool.to_primitive())
        req.allocation_pools = allocation_pools
        for pool in req.allocation_pools:
            if ip_to_bin(pool['start']) > ip_to_bin(pool['end']):
                return err_return("end_ip must be more than start_ip",
                                  "IPRangeError", "", HTTP_BAD_REQUEST)

        if external == 0:
            if not req.cidr:
                return err_return('cidr is required', 'ParameterInvalid', '',
                                  HTTP_BAD_REQUEST)
            if not validate_cidr(req.cidr):
                return err_return('cidr invalid', 'ParameterInvalid', '',
                                  HTTP_BAD_REQUEST)
            if not req.gateway_ip:
                return err_return('gateway ip is required', 'ParameterInvalid',
                                  '', HTTP_BAD_REQUEST)
            vl2lcid = yynetworkid_to_lcvl2id(req.network_id)
            log.debug('vl2lcid=%s' % vl2lcid)
            nets = [{
                "prefix": VFW_TOR_LINK_NET_PRE,
                "netmask": VFW_TOR_LINK_NET_MASK
            }]
            cidr = str(req.cidr).split('/')
            new_prf = cidr[0]
            new_mask = int(cidr[1])
            subnets = get_subnets_by_network(req.network_id)
            for subnet in subnets:
                cidr = subnet['cidr'].split('/')
                old_prf = cidr[0]
                old_mask = int(cidr[1])
                if subnet_equ(new_prf, old_prf, new_mask, old_mask):
                    log.error('cidr is the same')
                    return err_return('subnet already exist',
                                      'ParameterInvalid', '', HTTP_BAD_REQUEST)
                nets.append({"prefix": old_prf, "netmask": old_mask})
            nets.append({"prefix": new_prf, "netmask": new_mask})
            log.debug('nets=%s' % nets)
            nw_name = network_db_get_one('name', id=req.network_id)
            payload = json.dumps({"name": nw_name, "nets": nets})
            r = lcapi.patch(conf.livecloud_url + '/v1/vl2s/%s' % vl2lcid,
                            data=payload)
            if r.status_code != HTTP_OK:
                return Response(json.dumps(NEUTRON_400)), HTTP_NOT_FOUND
            nets = r.json()['DATA']['NETS']
            for net in nets:
                if subnet_equ(net['PREFIX'], new_prf, net['NETMASK'],
                              new_mask):
                    sb_lcuuid = net['LCUUID']
                    sb_idx = net['NET_INDEX']
                    break
            else:
                log.error('sb_lcuuid no found')
                sb_lcuuid = 'sb_lcuuid no found'
                sb_idx = -1
        else:
            subnetid = subnet_db_get_one('id', network_id=req.network_id)
            if subnetid:
                return err_return('subnet(%s) already exists' % subnetid,
                                  'Fail', '', HTTP_BAD_REQUEST)
            # ISP
            if not req.allocation_pools:
                return err_return('allocation_pools can not be empty',
                                  'ParameterInvalid', '', HTTP_BAD_REQUEST)
            id = subnet_db_get_one('id', network_id=req.network_id)
            if id:
                return subnet_get(subnetid=id)
            lcuuid = network_db_get_one('lcuuid', id=req.network_id)
            isp = lc_vl2_db_get_one('isp', lcuuid=lcuuid)
            items = lc_ip_res_db_get_all(req='ip, netmask, gateway, userid',
                                         isp=isp)
            if not items:
                return err_return("No ISP IP found", "BadRequest",
                                  "Please add ISP IP to system first",
                                  HTTP_BAD_REQUEST)
            req.gateway_ip = items[0]['gateway']
            req.cidr = ip_mask_to_cidr(items[0]['ip'], items[0]['netmask'])
            isp_all_ips = []
            ip_to_userid = {}
            for it in items:
                isp_all_ips.append(it['ip'])
                ip_to_userid[it['ip']] = it['userid']
            req_ips = alloc_pools_to_ip_list(req.allocation_pools)
            for req_ip in req_ips:
                if req_ip not in isp_all_ips:
                    return err_return("%s does not exist" % req_ip,
                                      "IPInvalid", "", HTTP_BAD_REQUEST)
                if ip_to_userid[req_ip] != 0:
                    return err_return("%s in use" % req_ip, "IPInUse", "",
                                      HTTP_BAD_REQUEST)
            sb_lcuuid = str(uuid.uuid4())
            sb_idx = -1

        sql = ("INSERT INTO neutron_subnets "
               "VALUES('%s','%s','%s','%s','%s','%s','%s','%s',%d)" %
               (req_id, req.subnet_name, req.network_id, req.cidr,
                json.dumps(req.allocation_pools), req.gateway_ip,
                json.dumps(req.dns_nameservers), sb_lcuuid, sb_idx))
        log.debug('add subnet sql=%s' % sql)
        with MySQLdb.connect(**DB_INFO) as cursor:
            cursor.execute(sql)
        if external:
            sql = "UPDATE ip_resource_v2_2 SET userid=%s WHERE ip in ('-1',"
            for req_ip in req_ips:
                sql += "'%s'," % req_ip
            sql = sql[:-1]
            sql += ")"
            log.debug('sql=%s' % sql)
            with MySQLdb.connect(**LCDB_INFO) as cursor:
                cursor.execute(sql, conf.livecloud_userid)

        resp, code = subnet_get(subnetid=req_id)
        return resp, HTTP_CREATED

    except Exception as e:
        log.error(e)
        return Response(json.dumps(NEUTRON_500)), HTTP_INTERNAL_SERVER_ERROR
Esempio n. 5
0
def subnet_put_api(subnetid=None):
    """
    Implementation Notes
      Updates existing subnet.

    Response Class (Status 200)
      Subnet {
        subnetId (string, optional): Subnet uuid.
        subnetName (string, optional): Subnet name, a user readable name.
        networkId (string, optional): Network uuid.
        cidr (string, optional): The CIDR of subnet.
        allocation_pools (Array[inline_model], optional):
          The start and end addresses for the allocation pools.
        gatewayIp (string, optional): The gateway IP address.
        dnsNameservers (Array[string], optional):
          A list of DNS name servers for the subnet.
      }
      inline_model {
        start (string, optional): Start IP address. ,
        end (string, optional): End IP address.
      }

    Parameters
      subnetId (string, optional): The subnet uuid to act on
      Subnet (body, required): Subnet description
    """
    try:
        if not subnetid:
            return err_return('subnetId is required', "ParameterInvalid", "",
                              HTTP_BAD_REQUEST)
        db_subnet = subnet_db_get_one('*', id=subnetid)
        if not db_subnet:
            return err_return('subnetId does not exist', "ParameterInvalid",
                              "", HTTP_NOT_FOUND)
        cidr = db_subnet['cidr']
        try:
            req = models.Subnet(request.json)
            req.validate()
        except Exception as e:
            log.error(e)
            return err_return('Parameter Invalid', "ParameterInvalid", "",
                              HTTP_BAD_REQUEST)
        with MySQLdb.connect(**DB_INFO) as cursor:
            if req.subnet_name is not None:
                if len(req.subnet_name) > NAME_MAX_LEN:
                    return err_return('Length of name must be less than 255',
                                      'ParameterInvalid', '', HTTP_BAD_REQUEST)
                sql = "UPDATE neutron_subnets SET name=%s WHERE id=%s"
                cursor.execute(sql, (req.subnet_name, subnetid))
            if req.dns_nameservers is not None:
                sql = ("UPDATE neutron_subnets SET "
                       "dns_nameservers=%s WHERE id=%s")
                cursor.execute(sql,
                               (json.dumps(req.dns_nameservers), subnetid))
        if req.allocation_pools is not None:
            allocation_pools = []
            for all_pool in req.allocation_pools:
                allocation_pools.append(all_pool.to_primitive())
            req.allocation_pools = allocation_pools
            for pool in req.allocation_pools:
                if ip_to_bin(pool['start']) > ip_to_bin(pool['end']):
                    return err_return("end_ip must be more than start_ip",
                                      "IPRangeError", "", HTTP_BAD_REQUEST)
        networkid = subnetid_to_networkid(subnetid)
        db_network = network_db_get_one('*', id=networkid)
        external = db_network['external']
        log.debug('external=%s' % external)
        if external:
            if req.allocation_pools is not None:
                old_alloc_pools = json.loads(db_subnet['allocation_pools'])
                old_alloc_ips = alloc_pools_to_ip_list(old_alloc_pools)
                new_alloc_ips = alloc_pools_to_ip_list(req.allocation_pools)
                tmp_nips = copy.deepcopy(new_alloc_ips)
                for new_ip in tmp_nips:
                    if new_ip in old_alloc_ips:
                        new_alloc_ips.remove(new_ip)
                        old_alloc_ips.remove(new_ip)
                isp = lc_vl2_db_get_one('isp', lcuuid=db_network['lcuuid'])
                items = lc_ip_res_db_get_all(req='ip, userid, vifid', isp=isp)
                isp_all_ips = []
                ip_to_userid = {}
                ip_to_vifid = {}
                for it in items:
                    isp_all_ips.append(it['ip'])
                    ip_to_userid[it['ip']] = it['userid']
                    ip_to_vifid[it['ip']] = it['vifid']
                for new_alloc_ip in new_alloc_ips:
                    if new_alloc_ip not in isp_all_ips:
                        return err_return("%s invalid" % new_alloc_ip,
                                          "IPInvalid", "", HTTP_BAD_REQUEST)
                    if ip_to_userid[new_alloc_ip] != 0:
                        return err_return("%s in use" % new_alloc_ip,
                                          "IPInUse", "", HTTP_BAD_REQUEST)
                for old_alloc_ip in old_alloc_ips:
                    if ip_to_vifid[old_alloc_ip] != 0:
                        return err_return("%s in use" % old_alloc_ip,
                                          "IPInUse", "", HTTP_BAD_REQUEST)
                sql = ("UPDATE neutron_subnets SET allocation_pools='%s' "
                       "WHERE id='%s'" %
                       (json.dumps(req.allocation_pools), subnetid))
                with MySQLdb.connect(**DB_INFO) as cursor:
                    cursor.execute(sql)
                sql = ("UPDATE ip_resource_v2_2 SET userid=0 "
                       "WHERE ip in ('-1',")
                for ip in old_alloc_ips:
                    sql += "'%s'," % ip
                sql = sql[:-1]
                sql += ")"
                sql2 = ("UPDATE ip_resource_v2_2 SET userid=%s "
                        "WHERE ip in ('-1',")
                for ip in new_alloc_ips:
                    sql2 += "'%s'," % ip
                sql2 = sql2[:-1]
                sql2 += ")"
                with MySQLdb.connect(**LCDB_INFO) as cursor:
                    cursor.execute(sql)
                    cursor.execute(sql2, conf.livecloud_userid)
            return subnet_get(subnetid=subnetid)

        if req.gateway_ip is not None:
            with MySQLdb.connect(**DB_INFO) as cursor:
                sql = "UPDATE neutron_subnets SET gateway_ip=%s WHERE id=%s"
                cursor.execute(sql, (req.gateway_ip, subnetid))
        log.debug('old_cidr=%s, new_cidr=%s' % (cidr, req.cidr))
        if req.cidr and cidr != req.cidr:
            vl2lcid = yynetworkid_to_lcvl2id(networkid)
            nets = [{
                "prefix": VFW_TOR_LINK_NET_PRE,
                "netmask": VFW_TOR_LINK_NET_MASK
            }]
            subnets = get_subnets_by_network(networkid)
            for subnet in subnets:
                if str(subnet['id']) == subnetid:
                    continue
                cidr = subnet['cidr'].split('/')
                nets.append({"prefix": cidr[0], "netmask": int(cidr[1])})
            cidr = str(req.cidr).split('/')
            log.debug('netmask=%s' % cidr[1])
            nets.append({"prefix": cidr[0], "netmask": int(cidr[1])})
            nw_name = network_db_get_one('name', id=networkid)
            payload = json.dumps({"name": nw_name, "nets": nets})
            log.debug('patch vl2 data=%s' % payload)
            r = lcapi.patch(conf.livecloud_url + '/v1/vl2s/%s' % vl2lcid,
                            data=payload)
            if r.status_code != HTTP_OK:
                err = r.json()['DESCRIPTION']
                log.error(err)
                return err_return(err, 'Fail', '', HTTP_BAD_REQUEST)
            nets = r.json()['DATA']['NETS']
            for net in nets:
                if subnet_equ(net['PREFIX'], cidr[0], net['NETMASK'],
                              int(cidr[1])):
                    sb_lcuuid = net['LCUUID']
                    sb_idx = net['NET_INDEX']
                    break
            else:
                log.error('sb_lcuuid no found')
                return Response(json.dumps(NEUTRON_500)), \
                    HTTP_INTERNAL_SERVER_ERROR
            if req.allocation_pools is None:
                req.allocation_pools = []
        else:
            req.cidr = db_subnet['cidr']
            sb_lcuuid = db_subnet['lcuuid']
            sb_idx = db_subnet['net_idx']
            if req.allocation_pools is None:
                return subnet_get(subnetid=subnetid)
            new_alloc_ips = alloc_pools_to_ip_list(req.allocation_pools)
            vl2id = lc_vl2_db_get_one('id', lcuuid=sb_lcuuid)
            used_ips = lc_vif_ip_db_get_all('ip',
                                            vl2id=vl2id,
                                            net_index=sb_idx)
            for used_ip in used_ips:
                ip = used_ip['ip']
                if ip not in new_alloc_ips:
                    return err_return('used ip(%s) not in alloc pool' % ip,
                                      'ParameterInvalid', '', HTTP_BAD_REQUEST)

        sql = ("UPDATE neutron_subnets SET cidr='%s', "
               "allocation_pools='%s', lcuuid='%s', net_idx=%s "
               "WHERE id='%s'" % (req.cidr, json.dumps(
                   req.allocation_pools), sb_lcuuid, sb_idx, subnetid))
        log.debug('sql=%s' % sql)
        with MySQLdb.connect(**DB_INFO) as cursor:
            cursor.execute(sql)
        return subnet_get(subnetid=subnetid)
    except Exception as e:
        log.error(e)
        return Response(json.dumps(NEUTRON_500)), HTTP_INTERNAL_SERVER_ERROR