def get_resource(idl, resource, schema, uri=None, selector=None, query_arguments=None): depth = _get_depth_param(query_arguments) if isinstance(depth, dict) and ERROR in depth: return depth if resource is None: return None # GET on System table if resource.next is None: if query_arguments is not None: validation_result = validate_non_plural_query_args(query_arguments) if ERROR in validation_result: return validation_result return get_row_json(resource.row, resource.table, schema, idl, uri, selector, depth) # All other cases # get the last resource pair while True: if resource.next.next is None: break resource = resource.next if verify.verify_http_method(resource, schema, "GET") is False: raise Exception({"status": httplib.METHOD_NOT_ALLOWED}) return get_resource_from_db(resource, schema, idl, uri, selector, query_arguments, depth)
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)
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)
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)
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))
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)
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)
def get_resource(idl, resource, schema, uri=None, selector=None, query_arguments=None, fetch_readonly=False, manager=None): depth = getutils.get_depth_param(query_arguments) if isinstance(depth, dict) and ERROR in depth: raise gen.Return(depth) if resource is None: raise gen.Return(None) # We want to get System table if resource.next is None: resource_query = resource else: while True: if resource.next.next is None: break resource = resource.next resource_query = resource.next utils.update_resource_keys(resource_query, schema, idl) if verify.verify_http_method(resource, schema, "GET") is False: raise Exception({'status': httplib.METHOD_NOT_ALLOWED}) # GET on System table if resource.next is None: if query_arguments is not None: validation_result = \ getutils.validate_non_plural_query_args(query_arguments) if ERROR in validation_result: raise gen.Return(validation_result) # Fetch all read-only columns prior to retrieving row data if fetch_readonly and manager: row = idl.tables[resource.table].rows[resource.row] yield utils.fetch_readonly_columns(schema, resource.table, idl, manager, [row]) result = yield get_row_json(resource.row, resource.table, schema, idl, uri, selector, depth, fetch_readonly=fetch_readonly, manager=manager) raise gen.Return(result) else: # Other tables result = yield get_resource_from_db(resource, schema, idl, uri, selector, query_arguments, depth, fetch_readonly, manager) raise gen.Return(result)
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)