コード例 #1
0
def _get_or_create_model_for_component(
    model_type,
    component_data,
    field_map,
    forbidden_model_fields=set(),
    save_priority=SAVE_PRIORITY,
):
    """
    For concrete component type try to save or reuse instance of
    Component using field_map and list of fields to save.
    Field_map maps from component fields to database fields. Some of the
    fields are forbidden to save for given component type, for example field
    name is forbidden in Storage Component.

    :param model_type: If provided, a 'model' field will be added
    :param component_data: list of dicts describing the components
    :param field_map: mapping from database fields to component_data keys
    :param forbidden_model_fields: If provided, model will be created
                                   without those fields
    :param save_priority: Save priority
    """
    model_fields = {
        field: component_data[field_map[field]]
        for field in field_map
        if all((
            component_data.get(field_map[field]),
            field != 'type',
            field not in forbidden_model_fields,
        ))
    }
    if all((
        'model_name' in component_data,
        'name' not in forbidden_model_fields,
    )):
        model_fields['name'] = component_data['model_name']
    if model_type == ComponentType.software:
        path = model_fields.get('path')
        family = model_fields.get('family')
        if path and not family:
            model_fields['family'] = path
    if 'family' in model_fields:
        model_fields['family'] = model_fields.get('family', '')[:128]
    model, created = ComponentModel.create(
        model_type,
        save_priority,
        **model_fields)
    return model
コード例 #2
0
def _update_component_data(
    device,
    component_data,
    Component,
    field_map,
    unique_fields,
    model_type=None,
    forbidden_model_fields=set(),
):
    """
    Update components of a device based on the data from scan.

    This function is a little tricky, because we want to reuse the
    components as much as possible, instead of deleting everything and
    creating new ones every time.

    :param component_data: list of dicts describing the components
    :param Component: model to use to query and create components
    :param field_map: mapping from database fields to component_data keys
    :param unique_fields: list of tuples of fields that are unique together
    :param model_type: If provided, a 'model' field will be added
    :param forbidden_model_fields: If provided, model will be created
                                   without those fields
    """

    component_ids = []
    for index, data in enumerate(component_data):
        data['device'] = device
        data['index'] = index
        for group in unique_fields:
            # First try to find an existing component using unique fields
            fields = {
                field: data[field_map[field]]
                for field in group
                if data.get(field_map[field]) is not None
            }
            if len(group) != len(fields):
                continue
            try:
                component = Component.objects.get(**fields)
            except Component.DoesNotExist:
                continue
            break
        else:
            # No matching component found, create a new one
            if model_type is not None or 'type' in data:
                # If model_type is provided, create the model
                model = None
                if model_type is None:
                    try:
                        model_type = ComponentType.from_name(data['type'])
                    except ValueError:
                        model_type = None
                if model_type is not None:
                    model_fields = {
                        field: data[field_map[field]]
                        for field in field_map
                        if all((
                            data.get(field_map[field]),
                            field != 'type',
                            field not in forbidden_model_fields,
                        ))
                    }
                    if all((
                        'model_name' in data,
                        'name' not in forbidden_model_fields,
                    )):
                        model_fields['name'] = data['model_name']
                    model, created = ComponentModel.create(
                        model_type,
                        0,
                        **model_fields)
                if model is None:
                    raise ValueError('Unknown model')
                component = Component(model=model)
            else:
                component = Component()
        # Fill the component with values from the data dict
        for field, key in field_map.iteritems():
            if key in data:
                setattr(component, field, data[key])
        component.save(priority=100)
        component_ids.append(component.id)
    # Delete the components that are no longer current
    for component in Component.objects.filter(
        device=device,
    ).exclude(
        id__in=component_ids,
    ):
        component.delete()