in internal/kibana/data_view/models.go [15:168]
func (model *dataViewModel) populateFromAPI(ctx context.Context, data *kbapi.DataViewsDataViewResponseObject, spaceID string) diag.Diagnostics {
if data == nil {
return nil
}
var diags diag.Diagnostics
resourceID := clients.CompositeId{
ClusterId: model.SpaceID.ValueString(),
ResourceId: *data.DataView.Id,
}
// An existing null map should should be semantically equal to an empty map.
semanticEqualEmptyMap := func(existing types.Map, incoming types.Map) types.Map {
if !utils.IsKnown(existing) && len(incoming.Elements()) == 0 {
return types.MapNull(incoming.ElementType(ctx))
}
return incoming
}
// An existing null slice should be semantically equal to an empty slice.
semanticEqualEmptySlice := func(existing types.List, incoming types.List) types.List {
if !utils.IsKnown(existing) && len(incoming.Elements()) == 0 {
return types.ListNull(incoming.ElementType(ctx))
}
return incoming
}
handleNamespaces := func(existingList types.List, incoming []string) types.List {
p := path.Root("data_view").AtName("namespaces")
existing := utils.ListTypeToSlice_String(ctx, existingList, p, &diags)
// incoming is typically [] except in <= v8.8.2 where it is omitted
if incoming == nil {
if existing == nil {
return types.ListNull(types.StringType)
} else {
return existingList
}
}
// An existing null slice should be semantically equal to a slice only containing the current space ID.
if existing == nil && len(incoming) == 1 && incoming[0] == model.SpaceID.ValueString() {
return types.ListNull(types.StringType)
}
// Keep the original ordering if equal but unordered
// The API response is ordered by name.
// Additionally, allow for the response containing an extra namespace that is the current SpaceID
// If the SpaceID is not included in the `namespaces` field, when trying to GET the object it will 404
if (len(existing) == len(incoming)) || (len(existing) == len(incoming)-1) {
useExisting := true
for _, ns := range existing {
if !slices.Contains(incoming, ns) {
if ns == spaceID {
continue
}
useExisting = false
break
}
}
if useExisting {
return existingList
}
}
return utils.SliceToListType_String(ctx, incoming, p, &diags)
}
model.ID = types.StringValue(resourceID.String())
model.DataView = utils.StructToObjectType(ctx, data.DataView, getDataViewAttrTypes(), path.Root("data_view"), &diags,
func(item kbapi.DataViewsDataViewResponseObjectInner, meta utils.ObjectMeta) innerModel {
dvInner := utils.ObjectTypeAs[innerModel](ctx, model.DataView, meta.Path, &diags)
if dvInner == nil {
dvInner = &innerModel{}
}
return innerModel{
Title: types.StringPointerValue(item.Title),
Name: types.StringPointerValue(item.Name),
ID: types.StringPointerValue(item.Id),
TimeFieldName: types.StringPointerValue(item.TimeFieldName),
SourceFilters: semanticEqualEmptySlice(dvInner.SourceFilters,
utils.SliceToListType(ctx, utils.Deref(item.SourceFilters), types.StringType, meta.Path.AtName("source_filters"), &diags,
func(item kbapi.DataViewsSourcefilterItem, meta utils.ListMeta) string {
return item.Value
})),
FieldAttributes: semanticEqualEmptyMap(dvInner.FieldAttributes,
utils.MapToMapType(ctx, utils.Deref(item.FieldAttrs), getFieldAttrElemType(), meta.Path.AtName("field_attrs"), &diags,
func(item kbapi.DataViewsFieldattrs, meta utils.MapMeta) fieldAttrModel {
return fieldAttrModel{
CustomLabel: types.StringPointerValue(item.CustomLabel),
Count: types.Int64PointerValue(utils.Itol(item.Count)),
}
})),
RuntimeFieldMap: semanticEqualEmptyMap(dvInner.RuntimeFieldMap,
utils.MapToMapType(ctx, utils.Deref(item.RuntimeFieldMap), getRuntimeFieldMapElemType(), meta.Path.AtName("runtime_field_map"), &diags,
func(item kbapi.DataViewsRuntimefieldmap, meta utils.MapMeta) runtimeFieldModel {
return runtimeFieldModel{
Type: types.StringValue(item.Type),
ScriptSource: types.StringPointerValue(item.Script.Source),
}
})),
FieldFormats: semanticEqualEmptyMap(dvInner.FieldFormats,
utils.MapToMapType(ctx, utils.Deref(item.FieldFormats), getFieldFormatElemType(), meta.Path.AtName("field_formats"), &diags,
func(item kbapi.DataViewsFieldformat, meta utils.MapMeta) fieldFormatModel {
return fieldFormatModel{
ID: types.StringPointerValue(item.Id),
Params: utils.StructToObjectType(ctx, item.Params, getFieldFormatParamsAttrTypes(), meta.Path.AtName("params"), &diags,
func(item kbapi.DataViewsFieldformatParams, meta utils.ObjectMeta) fieldFormatParamsModel {
return fieldFormatParamsModel{
Pattern: types.StringPointerValue(item.Pattern),
UrlTemplate: types.StringPointerValue(item.UrlTemplate),
LabelTemplate: types.StringPointerValue(item.LabelTemplate),
InputFormat: types.StringPointerValue(item.InputFormat),
OutputFormat: types.StringPointerValue(item.OutputFormat),
OutputPrecision: types.Int64PointerValue(utils.Itol(item.OutputPrecision)),
IncludeSpaceWithSuffix: types.BoolPointerValue(item.IncludeSpaceWithSuffix),
UseShortSuffix: types.BoolPointerValue(item.UseShortSuffix),
Timezone: types.StringPointerValue(item.Timezone),
FieldType: types.StringPointerValue(item.FieldType),
Colors: utils.SliceToListType(ctx, utils.Deref(item.Colors), getFieldFormatParamsColorsElemType(), meta.Path.AtName("colors"), meta.Diags,
func(item kbapi.DataViewsFieldformatParamsColor, meta utils.ListMeta) colorConfigModel {
return colorConfigModel{
Range: types.StringPointerValue(item.Range),
Regex: types.StringPointerValue(item.Regex),
Text: types.StringPointerValue(item.Text),
Background: types.StringPointerValue(item.Background),
}
}),
FieldLength: types.Int64PointerValue(utils.Itol(item.FieldLength)),
Transform: types.StringPointerValue(item.Transform),
LookupEntries: utils.SliceToListType(ctx, utils.Deref(item.LookupEntries), getFieldFormatParamsLookupEntryElemType(), meta.Path.AtName("lookup_entries"), meta.Diags,
func(item kbapi.DataViewsFieldformatParamsLookup, meta utils.ListMeta) lookupEntryModel {
return lookupEntryModel{
Key: types.StringPointerValue(item.Key),
Value: types.StringPointerValue(item.Value),
}
}),
UnknownKeyValue: types.StringPointerValue(item.UnknownKeyValue),
Type: types.StringPointerValue(item.Type),
Width: types.Int64PointerValue(utils.Itol(item.Width)),
Height: types.Int64PointerValue(utils.Itol(item.Height)),
}
}),
}
})),
AllowNoIndex: types.BoolPointerValue(item.AllowNoIndex),
Namespaces: handleNamespaces(dvInner.Namespaces, utils.Deref(item.Namespaces)),
}
})
return diags
}