Exemple #1
0
def verify_index(resource, parent, index_values, schema, idl):
    '''
        Verify if a resource exists in the DB Table using the index.
    '''

    if resource.table not in idl.tables:
        return None

    # check if we are dealing with key/value type of forward reference
    kv_type = False
    if parent is not None and parent.relation == OVSDB_SCHEMA_CHILD:
        if schema.ovs_tables[parent.table].references[parent.column].kv_type:
            kv_type = True

    if kv_type:
        # check in parent table that the index exists
        app_log.debug('verifying key/value type reference')
        row = utils.kv_index_to_row(index_values, parent, idl)
    else:
        dbtable = idl.tables[resource.table]
        table_schema = schema.ovs_tables[resource.table]

        row = utils.index_to_row(index_values, table_schema, dbtable)

    return row
Exemple #2
0
def verify_index(resource, parent, index_values, schema, idl):

    if resource.table not in idl.tables:
        return None

    if parent.relation == OVSDB_SCHEMA_BACK_REFERENCE:
        reference_keys = schema.ovs_tables[resource.table].references

        _refCol = None
        for key, value in reference_keys.iteritems():
            if (value.relation == OVSDB_SCHEMA_PARENT
                    and value.ref_table == parent.table):
                _refCol = key
                break

        if _refCol is None:
            return False

        dbtable = idl.tables[resource.table]
        row = utils.index_to_row(index_values,
                                 schema.ovs_tables[resource.table], dbtable)
        if row.__getattr__(_refCol).uuid == parent.row:
            return row
        else:
            return None

    elif parent.relation == OVSDB_SCHEMA_TOP_LEVEL:
        dbtable = idl.tables[resource.table]
        table_schema = schema.ovs_tables[resource.table]
        row = utils.index_to_row(index_values, table_schema, dbtable)
        return row

    else:
        # check if we are dealing with key/value type of forward reference
        kv_type = schema.ovs_tables[parent.table].references[
            parent.column].kv_type

        if kv_type:
            # check in parent table that the index exists
            app_log.debug('verifying key/value type reference')
            row = utils.kv_index_to_row(index_values, parent, idl)
        else:
            dbtable = idl.tables[resource.table]
            table_schema = schema.ovs_tables[resource.table]
            row = utils.index_to_row(index_values, table_schema, dbtable)
        return row
def setup_row(index_values, table, row_data, txn, reflist, schema, idl,
              validator_adapter, errors, old_row=None):

    # Initialize the flag for row to check if it is new row
    is_new = False

    # Check if row exists in DB
    if old_row is not None:
        row = old_row
    else:
        row = utils.index_to_row(index_values,
                                 schema.ovs_tables[table],
                                 idl.tables[table])

    # Create a new row if not found in DB
    if row is None:
        if table in immutable_tables:
            # Do NOT add row in Immutable table_data
            return (None, False)
        row = txn.insert(idl.tables[table])
        is_new = True

    # Routes are special case - only static routes can be updated
    if table == 'Route':
        if not is_new and row.__getattr__('from') != 'static':
            return (None, False)
        elif is_new:
            row.__setattr__('from', 'static')

    references = schema.ovs_tables[table].references
    children = schema.ovs_tables[table].children

    try:
        request_type = REQUEST_TYPE_CREATE if is_new else REQUEST_TYPE_UPDATE
        get_all_errors = True

        # Check for back-references and remove it from the row data since
        # it will be checked upon recursive call anyways.
        _row_data = deepcopy(row_data)
        for data in row_data:
            if data in children and data not in references:
                del _row_data[data]

        results = verify.verify_config_data(_row_data, table, schema,
                                            request_type, get_all_errors)
    except DataValidationFailed as e:
        errors.extend(e.detail)

    config_rows = schema.ovs_tables[table].config
    config_keys = config_rows.keys()

    # Iterate over all config keys
    for key in config_keys:
        # Ignore if row is existing and column is immutable
        if not is_new and not config_rows[key].mutable:
            continue

        # Set the column values from user config
        if key not in row_data and not is_new:
            empty_val = utils.get_empty_by_basic_type(row.__getattr__(key))
            row.__setattr__(key, empty_val)
        elif (key in row_data and
                (is_new or row.__getattr__(key) != row_data[key])):
            row.__setattr__(key, row_data[key])

    # Delete all the keys that don't exist
    for key in children:
        child_table = references[key].ref_table \
            if key in references else key

        # Check if table is immutable
        if child_table in immutable_tables:
            if not is_new and (key not in row_data or not row_data[key]):
                # Deep clean-up children, even if missing or empty,
                # Ignore if immutable
                if key in references:
                    kv_type = references[key].kv_type
                    if kv_type:
                        rowlist = row.__getattr__(key).values()
                    else:
                        rowlist = row.__getattr__(key)
                    clean_subtree(child_table, rowlist, txn, schema, idl,
                                  validator_adapter)
                else:
                    clean_subtree(child_table, [], txn, schema, idl,
                                  validator_adapter, row)
            continue

        # forward child references
        if key in references:
            table_schema = schema.ovs_tables[table]
            reference = table_schema.references[key]
            kv_type = reference.kv_type

            if not is_new and key not in row_data:
                if kv_type:
                    row.__setattr__(key, {})
                else:
                    row.__setattr__(key, [])
        else:
            # back-references
            if child_table not in row_data:
                new_data = {}
            else:
                new_data = row_data[child_table]
            remove_deleted_rows(child_table, new_data, txn, schema, idl,
                                validator_adapter, row)

    # set up children that exist
    for key in children:
        child_table = references[key].ref_table \
            if key in references else key

        if key in row_data:

            if key in references:
                # forward referenced children
                table_schema = schema.ovs_tables[table]
                reference = table_schema.references[key]
                kv_type = reference.kv_type
                kv_key_type = None
                current_child_rows = {}

                # Key-value type children (Dict type)
                # Example - BGP_Router is KV-Type child of VRF
                if kv_type:
                    kv_key_type = reference.kv_key_type
                    if not is_new:
                        current_child_rows = row.__getattr__(key)
                    child_reference_list = {}
                # Regular children
                else:
                    child_reference_list = []

                # Iterate over each child_row
                for child_index, child_row_data in row_data[key].iteritems():
                    current_row = None
                    if kv_type:
                        if (kv_key_type is not None and
                                kv_key_type.name == 'integer'):
                            child_index = int(child_index)
                        if child_index in current_child_rows:
                            current_row = current_child_rows[child_index]
                        child_index_values = []
                    else:
                        child_index_values = utils.escaped_split(child_index)

                    (child_row, is_child_new) = setup_row(child_index_values,
                                                          child_table,
                                                          child_row_data,
                                                          txn, reflist,
                                                          schema, idl,
                                                          validator_adapter,
                                                          errors,
                                                          current_row)
                    if child_row is None:
                        continue

                    op = REQUEST_TYPE_CREATE if is_child_new else \
                        REQUEST_TYPE_UPDATE

                    validator_adapter.add_resource_op(op, child_row,
                                                      child_table, row, table)
                    if kv_type:
                        child_reference_list.update({child_index: child_row})
                    else:
                        child_reference_list.append(child_row)
                        # Save this in global reflist
                        reflist[(child_table, child_index)] = (child_row,
                                                               is_child_new)
                if child_table not in immutable_tables:
                    row.__setattr__(key, child_reference_list)
            else:
                # backward referenced children
                parent_column = None
                references = schema.ovs_tables[child_table].references
                for col_name, col_value in references.iteritems():
                    if col_value.relation == 'parent':
                        parent_column = col_name
                        break
                # Iterate over each child_row
                for child_index, child_row_data in row_data[key].iteritems():
                    child_index_values = utils.escaped_split(child_index)

                    (child_row, is_child_new) = setup_row(child_index_values,
                                                          child_table,
                                                          child_row_data,
                                                          txn, reflist,
                                                          schema, idl,
                                                          validator_adapter,
                                                          errors)
                    if child_row is None:
                        continue

                    op = REQUEST_TYPE_CREATE if is_child_new else \
                        REQUEST_TYPE_UPDATE

                    validator_adapter.add_resource_op(op, child_row,
                                                      child_table, row, table)

                    # Set the references column in child row
                    if parent_column is not None and is_child_new:
                        child_row.__setattr__(parent_column, row)

                    # save this in global reflist
                    reflist[(child_table, child_index)] = (child_row,
                                                           is_child_new)

    return (row, is_new)