Beispiel #1
0
def verify_forward_reference(data, resource, schema, idl):
    """
    converts the forward reference URIs to corresponding Row references
    Parameters:
        data - post/put data
        resource - Resource object being accessed
        schema = restparser schema object
        idl - ovs.db.idl.Idl object
    """
    reference_keys = schema.ovs_tables[resource.table].references
    verified_references = {}

    # check for invalid keys
    for key in reference_keys:
        if key in data:
            category = reference_keys[key].category
            relation = reference_keys[key].relation

            if category != OVSDB_SCHEMA_CONFIG or \
                    relation == 'parent':
                        error = "Invalid reference: %s" % key
                        raise DataValidationFailed(error)

    for key in reference_keys:
        if key in data:
            # this is either a URI or list of URIs
            _refdata = data[key]
            notList = False
            if type(_refdata) is not types.ListType:
                notList = True
                _refdata = [_refdata]

            # check range
            _min = reference_keys[key].n_min
            _max = reference_keys[key].n_max
            if len(_refdata) < _min or len(_refdata) > _max:
                error = "Reference list is out of range for key %s" % key
                raise DataValidationFailed(error)

            references = []
            for uri in _refdata:
                verified_resource = parse.parse_url_path(uri, schema, idl)
                if verified_resource is None:
                    error = "Reference %s could not be identified" % uri
                    raise DataValidationFailed(error)

                # get the Row instance of the reference we are adding
                while verified_resource.next is not None:
                    verified_resource = verified_resource.next
                row = utils.get_row_from_resource(verified_resource, idl)
                references.append(row)

            if notList:
                references = references[0]
            verified_references[key] = references

    return verified_references
Beispiel #2
0
def _get_row_from_uri(uri, schema, idl):

    verified_resource = parse.parse_url_path(uri, schema, idl)
    if verified_resource is None:
        error = "Reference %s could not be identified" % uri
        raise DataValidationFailed(error)

    # get the Row instance of the reference we are adding
    while verified_resource.next is not None:
        verified_resource = verified_resource.next
    row = utils.get_row_from_resource(verified_resource, idl)
    return row
Beispiel #3
0
def delete_resource(resource, schema, txn, idl):

    if resource.next is None:
        return None

    # get the last resource pair
    while True:
        if resource.next.next is None:
            break
        resource = resource.next

    # Check for invalid resource deletion
    if verify.verify_http_method(resource, schema,
                                 REQUEST_TYPE_DELETE) is False:
        raise MethodNotAllowed

    try:
        utils.exec_validators_with_resource(idl, schema, resource,
                                            REQUEST_TYPE_DELETE)
    except ValidationError as e:
        app_log.debug("Custom validations failed:")
        app_log.debug(e.error)
        raise DataValidationFailed(e.error)

    if resource.relation == OVSDB_SCHEMA_CHILD:

        if resource.next.row is None:
            raise MethodNotAllowed

        row = utils.delete_reference(resource.next, resource, schema, idl)
        row.delete()

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        row = utils.get_row_from_resource(resource.next, idl)
        row.delete()

    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        utils.delete_all_references(resource.next, schema, idl)

    result = txn.commit()
    return OvsdbTransactionResult(result)
Beispiel #4
0
def delete_resource(resource, schema, txn, idl):

    if resource.next is None:
        return None

    # get the last resource pair
    while True:
        if resource.next.next is None:
            break
        resource = resource.next

    # Check for invalid resource deletion
    if verify.verify_http_method(resource, schema,
                                 REQUEST_TYPE_DELETE) is False:
        raise MethodNotAllowed

    try:
        utils.exec_validators_with_resource(idl, schema, resource,
                                            REQUEST_TYPE_DELETE)
    except ValidationError as e:
        app_log.debug("Custom validations failed:")
        app_log.debug(e.error)
        raise DataValidationFailed(e.error)

    if resource.relation == OVSDB_SCHEMA_CHILD:
        if resource.next.row is None:
            parent = idl.tables[resource.table].rows[resource.row]
            rows = parent.__getattr__(resource.column)
            if isinstance(rows, dict):
                rows = rows.values()
                parent.__setattr__(resource.column, {})
            elif isinstance(rows, ovs.db.idl.Row):
                rows = [rows]
                parent.__setattr__(resource.column, None)
            else:
                parent.__setattr__(resource.column, [])

            # delete rows from the table
            while len(rows):
                row = rows.pop()
                row.delete()
        else:
            row = utils.delete_reference(resource.next, resource, schema, idl)
            row.delete()

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        if resource.next.row is None:
            refcol = None
            parent = idl.tables[resource.table].rows[resource.row]
            refkeys = schema.ovs_tables[resource.next.table].references
            for key, value in refkeys.iteritems():
                if (value.relation == OVSDB_SCHEMA_PARENT
                        and value.ref_table == resource.table):
                    refcol = key
                    break

            children = []
            for row in idl.tables[resource.next.table].rows.itervalues():
                if row.__getattr__(refcol) == parent:
                    children.append(row.uuid)

            for child in children:
                row = idl.tables[resource.next.table].rows[child]
                row.delete()
        else:
            row = utils.get_row_from_resource(resource.next, idl)
            row.delete()
    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        row = utils.delete_all_references(resource.next, schema, idl)

        # Check if the table is a top-level root table that is not referenced
        # and explicitly delete.
        resource_table = resource.next.table
        if resource_table not in schema.reference_map.values():
            if schema.ovs_tables[resource_table].is_root:
                row.delete()

    result = txn.commit()
    return OvsdbTransactionResult(result)