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
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
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 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)