Example #1
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)
Example #2
0
def put_resource(data, resource, schema, txn, idl):

    # Allow PUT operation on System table
    if resource is None:
        raise MethodNotAllowed

    # We want to modify System table
    if resource.next is None:
        resource_update = resource
    else:
        while True:
            if resource.next.next is None:
                break
            resource = resource.next
        resource_update = resource.next

    app_log.debug("Resource = Table: %s Relation: %s Column: %s"
                  % (resource.table, resource.relation, resource.column))

    if resource_update is not None:
        app_log.debug("Resource to Update = Table: %s "
                      % resource_update.table)

    if verify.verify_http_method(resource, schema,
                                 REQUEST_TYPE_UPDATE) is False:
        raise MethodNotAllowed

    # verify data
    try:
        verified_data = verify.verify_data(data, resource, schema, idl,
                                           REQUEST_TYPE_UPDATE)
    except DataValidationFailed as e:
        app_log.debug(e)
        raise e

    # We want to modify System table
    if resource.next is None:
        updated_row = utils.update_row(resource, verified_data,
                                       schema, txn, idl)

    elif resource.relation == OVSDB_SCHEMA_CHILD:
        '''
        Updating row from a child table
        Example:
        /system/bridges: PUT is allowed when modifying the bridge child table
        '''
        # update row, populate it with data, add it as a reference to
        # the parent resource
        updated_row = utils.update_row(resource_update,
                                       verified_data, schema, txn, idl)

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        '''
        In this case we only modify the data of the table, but we not modify
        the back reference.
        Example:
        /system/vrfs/vrf_default/bgp_routers: PUT allowed as we are
         modifying a back referenced resource
        '''
        # row for a back referenced item contains the parent's reference
        # in the verified data
        updated_row = utils.update_row(resource_update, verified_data,
                                       schema, txn, idl)

    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        '''
        Updating row when we have a relationship with a top_level table
        Is not allowed to update the references in other tables.
        Example:
        /system/ports: PUT allowed as we are modifying Port to top level table
        '''
        updated_row = utils.update_row(resource_update, verified_data,
                                       schema, txn, idl)

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

    result = txn.commit()
    return OvsdbTransactionResult(result)
Example #3
0
def post_resource(data, resource, schema, txn, idl):
    """
    /system/bridges: POST allowed as we are adding a new Bridge
                     to a child table
    /system/ports: POST allowed as we are adding a new Port to
                   top level table
    /system/vrfs/vrf_default/bgp_routers: POST allowed as we
                   are adding a back referenced resource
    /system/bridges/bridge_normal/ports: POST NOT allowed as we
    are attemtping to add a Port as a reference on bridge
    """

    if resource is None or resource.next is None:
        app_log.info("POST is not allowed on System table")
        raise MethodNotAllowed

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

    if verify.verify_http_method(resource, schema, REQUEST_TYPE_CREATE) is False:
        raise MethodNotAllowed

    # verify data
    try:
        verified_data = verify.verify_data(data, resource, schema, idl, REQUEST_TYPE_CREATE)
    except DataValidationFailed as e:
        app_log.debug(e)
        raise e

    app_log.debug("adding new resource to " + resource.next.table + " table")

    if resource.relation == OVSDB_SCHEMA_CHILD:
        # create new row, populate it with data
        # add it as a reference to the parent resource
        new_row = utils.setup_new_row(resource.next, verified_data, schema, txn, idl)

        ref = schema.ovs_tables[resource.table].references[resource.column]
        if ref.kv_type:
            keyname = ref.column.keyname
            utils.add_kv_reference(verified_data[keyname], new_row, resource, idl)
        else:
            utils.add_reference(new_row, resource, idl)

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        # row for a back referenced item contains the parent's reference
        # in the verified data
        new_row = utils.setup_new_row(resource.next, verified_data, schema, txn, idl)

    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        new_row = utils.setup_new_row(resource.next, verified_data, schema, txn, idl)

        # a non-root table entry MUST be referenced elsewhere
        if OVSDB_SCHEMA_REFERENCED_BY in verified_data:
            for reference in verified_data[OVSDB_SCHEMA_REFERENCED_BY]:
                utils.add_reference(new_row, reference, idl)

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

    result = txn.commit()
    return OvsdbTransactionResult(result)
Example #4
0
def patch_resource(data, resource, schema, txn, idl, uri):

    # Allow PATCH operation on System table
    if resource is None:
        raise MethodNotAllowed

    app_log.debug("Resource = Table: %s Relation: %s Column: %s" %
                  (resource.table, resource.relation, resource.column))

    # We want to modify System table
    if resource.next is None:
        resource_update = resource
    else:
        while True:
            if resource.next.next is None:
                break
            resource = resource.next
        resource_update = resource.next

    utils.update_resource_keys(resource_update, schema, idl)

    if resource_update is None or resource_update.row is None or \
            verify.verify_http_method(resource, schema,
                                      REQUEST_TYPE_PATCH) is False:
        app_log.debug("Failed http_method verification")
        raise MethodNotAllowed

    needs_update = False

    # Create and verify patch
    (patch, needs_update) = create_patch(data)

    # Get the JSON to patch
    row_json = yield get_current_row(resource_update, uri, schema, idl)

    # Now apply the patch to that JSON
    patched_row_json = apply_patch(patch, row_json, resource_update, schema)

    # If at least one PATCH operation changed the row,
    # since a valid patch can contain just a PATCH_OP_TEST,
    # validate the patched row and update row with IDL
    if needs_update:

        # Validate and prepare final JSON to send to IDL
        new_row_json = prepare_data(patch, patched_row_json, resource,
                                    resource_update, schema, idl)

        app_log.debug("New row -> %s" % new_row_json)

        # Update resource with the patched JSON
        # System: resource.next is None
        # All other rows: resource.relation is not None
        if resource.next is None or resource.relation is not None:
            app_log.debug("Updating row...")
            # updated_row is not used for now but eventually will be returned
            updated_row = utils.update_row(resource_update, new_row_json,
                                           schema, txn, idl)

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

    result = txn.commit()
    raise gen.Return(OvsdbTransactionResult(result))
Example #5
0
def post_resource(data, resource, schema, txn, idl):
    """
    /system/bridges: POST allowed as we are adding a new Bridge
                     to a child table
    /system/ports: POST allowed as we are adding a new Port to
                   top level table
    /system/vrfs/vrf_default/bgp_routers: POST allowed as we
                   are adding a back referenced resource
    /system/bridges/bridge_normal/ports: POST NOT allowed as we
    are attemtping to add a Port as a reference on bridge
    """

    if resource is None or resource.next is None:
        app_log.info("POST is not allowed on System table")
        raise MethodNotAllowed

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

    utils.update_resource_keys(resource.next, schema, idl,
                               data[OVSDB_SCHEMA_CONFIG])

    if verify.verify_http_method(resource, schema,
                                 REQUEST_TYPE_CREATE) is False:
        raise MethodNotAllowed

    # verify data
    try:
        verified_data = verify.verify_data(data, resource, schema, idl,
                                           REQUEST_TYPE_CREATE)
    except DataValidationFailed as e:
        app_log.debug(e)
        raise e

    app_log.debug("adding new resource to " + resource.next.table + " table")

    if resource.relation == OVSDB_SCHEMA_CHILD:
        # create new row, populate it with data
        # add it as a reference to the parent resource
        new_row = utils.setup_new_row_by_resource(resource.next, verified_data,
                                                  schema, txn, idl)

        ref = schema.ovs_tables[resource.table].references[resource.column]
        if ref.kv_type:
            keyname = ref.keyname
            utils.add_kv_reference(verified_data[keyname], new_row, resource,
                                   idl)
        else:
            utils.add_reference(new_row, resource, idl)

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        # row for a back referenced item contains the parent's reference
        # in the verified data
        new_row = utils.setup_new_row_by_resource(resource.next, verified_data,
                                                  schema, txn, idl)

    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        new_row = utils.setup_new_row_by_resource(resource.next, verified_data,
                                                  schema, txn, idl)

        # a non-root table entry MUST be referenced elsewhere
        if OVSDB_SCHEMA_REFERENCED_BY in verified_data:
            for reference in verified_data[OVSDB_SCHEMA_REFERENCED_BY]:
                utils.add_reference(new_row, reference, idl)

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

    index = utils.create_index(schema, verified_data, resource, new_row)
    result = txn.commit()

    return OvsdbTransactionResult(result, index)
Example #6
0
def put_resource(data, resource, schema, txn, idl):

    # Allow PUT operation on System table
    if resource is None:
        raise MethodNotAllowed

    # We want to modify System table
    if resource.next is None:
        resource_update = resource
    else:
        while True:
            if resource.next.next is None:
                break
            resource = resource.next
        resource_update = resource.next

    app_log.debug("Resource = Table: %s Relation: %s Column: %s" %
                  (resource.table, resource.relation, resource.column))

    utils.update_resource_keys(resource_update, schema, idl)

    if resource_update is None or resource_update.row is None or\
            verify.verify_http_method(resource,
                                      schema, REQUEST_TYPE_UPDATE) is False:
        raise MethodNotAllowed

    # verify data
    try:
        verified_data = verify.verify_data(data, resource, schema, idl,
                                           REQUEST_TYPE_UPDATE)
    except DataValidationFailed as e:
        app_log.debug(e)
        raise e

    # We want to modify System table
    if resource.next is None:
        updated_row = utils.update_row(resource_update, verified_data, schema,
                                       txn, idl)

    elif resource.relation == OVSDB_SCHEMA_CHILD:
        '''
        Updating row from a child table
        Example:
        /system/bridges: PUT is allowed when modifying the bridge child table
        '''
        # update row, populate it with data, add it as a reference to
        # the parent resource
        updated_row = utils.update_row(resource_update, verified_data, schema,
                                       txn, idl)

    elif resource.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        '''
        In this case we only modify the data of the table, but we not modify
        the back reference.
        Example:
        /system/vrfs/vrf_default/bgp_routers: PUT allowed as we are
         modifying a back referenced resource
        '''
        # row for a back referenced item contains the parent's reference
        # in the verified data
        updated_row = utils.update_row(resource_update, verified_data, schema,
                                       txn, idl)

    elif resource.relation == OVSDB_SCHEMA_TOP_LEVEL:
        '''
        Updating row when we have a relationship with a top_level table
        Is not allowed to update the references in other tables.
        Example:
        /system/ports: PUT allowed as we are modifying Port to top level table
        '''
        updated_row = utils.update_row(resource_update, verified_data, schema,
                                       txn, idl)

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

    result = txn.commit()
    return OvsdbTransactionResult(result)
Example #7
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)