def parse_url_path(path, schema, idl, http_method='GET'): if not path.startswith(REST_VERSION_PATH): app_log.debug("[parse_url_path]: path does not start with %s" % REST_VERSION_PATH) return None # remove version and split path path = path[len(REST_VERSION_PATH):] path = split_path(path) if not path: app_log.debug("[parse_url_path]: path is empty") return None # we only serve URIs that begin with '/system' if path[0] != OVSDB_SCHEMA_SYSTEM_URI: app_log.debug("[parse_url_path]: path does not start with /%s" % OVSDB_SCHEMA_SYSTEM_URI) return None resource = Resource(OVSDB_SCHEMA_SYSTEM_TABLE, schema) if resource.table not in idl.tables: app_log.debug("[parse_url_path]: resource table not in idl tables") return None if idl.tables[resource.table].rows.keys(): resource.row = idl.tables[resource.table].rows.keys()[0] else: app_log.debug("[parse_url_path]: table has no rows") return None path = path[1:] if not path: return resource try: parse(path, resource, schema, idl, http_method) return resource except Exception as e: app_log.debug(str(e)) app_log.debug('resource not found') return None app_log.debug("[parse_url_path]: default return") return None
def parse_url_path(path, schema, idl, http_method='GET'): if not path.startswith(REST_VERSION_PATH): return None # remove version and split path path = path[len(REST_VERSION_PATH):] path = split_path(path) if not path: return None # we only serve URIs that begin with '/system' if path[0] != OVSDB_SCHEMA_SYSTEM_URI: return None resource = Resource(OVSDB_SCHEMA_SYSTEM_TABLE) if resource.table not in idl.tables: return None if idl.tables[resource.table].rows.keys(): resource.row = idl.tables[resource.table].rows.keys()[0] else: return None path = path[1:] if not path: return resource try: parse(path, resource, schema, idl, http_method) return resource except Exception as e: app_log.debug(e) app_log.debug('resource not found') return None return None
def parse(path, resource, schema, idl, http_method): if not path: return None ovs_tables = schema.ovs_tables table_names = ovs_tables.keys() new_resource = None # check if path[0] is a forward referenced child of resource.table if path[0] in ovs_tables[resource.table].columns \ and path[0] in ovs_tables[resource.table].children: resource.relation = OVSDB_SCHEMA_CHILD resource.column = path[0] _max = schema.ovs_tables[resource.table].references[ resource.column].n_max app_log.debug("%s is a forward child in %s" % (path[0], resource.table)) child_table = ovs_tables[resource.table].references[ resource.column].ref_table new_resource = Resource(child_table, schema) resource.next = new_resource # index columns indexes = ovs_tables[new_resource.table].indexes if \ ovs_tables[new_resource.table].indexes[0] != 'uuid' else None path = path[1:] if not path and _max > 1: # done parsing uri return if _max == 1: parent = idl.tables[resource.table].rows[resource.row] child_row = parent.__getattr__(resource.column) if not child_row and path: raise Exception elif not child_row and not path: return elif isinstance(child_row, list): new_resource.row = child_row[0].uuid elif isinstance(child_row, dict): new_resource.row = child_row.values()[0].uuid new_resource.index = child_row.keys()[0] elif indexes: if len(path) < len(indexes): # not enough indices raise Exception index_list = path[0:len(indexes)] row = verify_index(new_resource, resource, index_list, schema, idl) if row is None: # row with index doesn't exist raise Exception new_resource.row = row.uuid new_resource.index = index_list path = path[len(index_list):] else: # children are either an ordered list or a dict parent = idl.tables[resource.table].rows[resource.row] children = parent.__getattr__(resource.column) if not children: raise Exception index = path[0] if isinstance(children, dict): column = schema.ovs_tables[resource.table].references[ resource.column] key_type = column.kv_key_type.name if key_type == 'integer': index = int(index) elif key_type == 'uuid': raise Exception else: # ordered list index = int(index) try: row = children[index] new_resource.row = row.uuid new_resource.index = index path = path[1:] except: # not found raise Exception # top-level reference or back referenced child elif path[0] in schema.plural_name_map: # check if path[0] is a back referenced child of resource.table path[0] = schema.plural_name_map[path[0]] if path[0] in ovs_tables[resource.table].children: resource.relation = OVSDB_SCHEMA_BACK_REFERENCE new_resource = Resource(path[0], schema) resource.next = new_resource app_log.debug("%s is a backward child in %s" % (path[0], resource.table)) # or if path[0] is a top level table elif resource.table == OVSDB_SCHEMA_SYSTEM_TABLE and \ ovs_tables[path[0]].parent is None: resource.relation = OVSDB_SCHEMA_TOP_LEVEL new_resource = Resource(path[0], schema) resource.next = new_resource app_log.debug("%s is a top level table" % (path[0])) # do not proceed if relationship cannot be ascertained if not resource.relation: app_log.debug('URI not allowed: relationship does not exist') raise Exception indexes = ovs_tables[new_resource.table].indexes if \ ovs_tables[new_resource.table].indexes[0] != 'uuid' else None path = path[1:] # done processing URI if not path: return # URI has an index to a resource elif indexes: if len(path) < len(indexes): raise Exception index_list = path[0:len(indexes)] row = verify_index(new_resource, resource, index_list, schema, idl) new_resource.row = row.uuid new_resource.index = index_list path = path[len(index_list):] if not new_resource: app_log.debug('URI not allowed: relationship does not exist') raise Exception app_log.debug("table: %s, row: %s, column: %s, relation: %s" % (resource.table, str(resource.row), str( resource.column), str(resource.relation))) # continue processing the path further parse(path, new_resource, schema, idl, http_method)
def parse(path, resource, schema, idl, http_method): ''' recursive routine that compares the URI path with the extended schema and builds resource/subresource relationship. If the relationship referenced by the URI doesn't match with the extended schema we return None ''' if not path: return None ovs_tables = schema.ovs_tables table_names = ovs_tables.keys() _fail = False # check if path[0] is a CHILD of resource.table if path[0] in ovs_tables[resource.table].children: resource.relation = OVSDB_SCHEMA_CHILD resource.column = path[0] app_log.debug("%s is a forward child in %s" % (path[0], resource.table)) path[0] = ovs_tables[resource.table].references[path[0]].ref_table elif path[0] in schema.plural_name_map: path[0] = schema.plural_name_map[path[0]] # check if path[0] is a back referenced CHILD of resource.table if path[0] in ovs_tables[resource.table].children: resource.relation = OVSDB_SCHEMA_BACK_REFERENCE app_log.debug("%s is a backward child in %s" % (path[0], resource.table)) else: if resource.table == OVSDB_SCHEMA_SYSTEM_TABLE and \ ovs_tables[path[0]].parent is None: resource.relation = OVSDB_SCHEMA_TOP_LEVEL app_log.debug("%s is a top level table" % (path[0])) if resource.relation is None: app_log.debug('URI not allowed: relationship does not exist') raise Exception # create the next resource new_resource = Resource(path[0]) resource.next = new_resource path = path[1:] # update path list app_log.debug("table: %s, row: %s, column: %s, relation: %s" % (resource.table, str(resource.row), str(resource.column), str(resource.relation))) # this should be the start of the index index_list = None if path: table_indices = schema.ovs_tables[new_resource.table].indexes # len(path) must at least be equal to len(table_indices) # to uniquely identify a resource if len(path) < len(table_indices): return None index_list = path[0:len(table_indices)] # verify back reference existence if resource.relation == OVSDB_SCHEMA_BACK_REFERENCE: if http_method == 'POST' and index_list is None: return if not verify_back_reference(resource, new_resource, schema, idl, index_list): app_log.debug('URI not allowed: resource verification failed') raise Exception # return if we are done processing the URI if index_list is None: return # verify non-backreference resource existence row = verify_index(new_resource, resource, index_list, schema, idl) if row is None: raise Exception else: new_resource.row = row.uuid new_resource.index = index_list # we now have a complete new_resource # continue processing the path further path = path[len(index_list):] parse(path, new_resource, schema, idl, http_method)