Skip to content

Commit

Permalink
feat(kql_database): add definition support (#215)
Browse files Browse the repository at this point in the history
# 📥 Pull Request

## ❓ What are you trying to address

Add definition support to the KQL Database
  • Loading branch information
DariuszPorowski authored Feb 12, 2025
1 parent 4ba1875 commit 2d2b7c1
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 131 deletions.
5 changes: 5 additions & 0 deletions .changes/unreleased/added-20250125-102124.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: added
body: Definition support in the `fabric_kql_database` Resource / Data-Source
time: 2025-01-25T10:21:24.6864838+01:00
custom:
Issue: "215"
15 changes: 15 additions & 0 deletions docs/data-sources/kql_database.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,17 @@ data "fabric_kql_database" "example_by_name" {
### Optional

- `display_name` (String) The KQL Database display name.
- `format` (String) The KQL Database format. Possible values: `Default`
- `id` (String) The KQL Database ID.
- `output_definition` (Boolean) Output definition parts as gzip base64 content? Default: `false`

!> Your terraform state file may grow a lot if you output definition content. Only use it when you must use data from the definition.

- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))

### Read-Only

- `definition` (Attributes Map) Definition parts. Possible path keys: **Default** format: `DatabaseProperties.json`, `DatabaseSchema.kql` (see [below for nested schema](#nestedatt--definition))
- `description` (String) The KQL Database description.
- `properties` (Attributes) The KQL Database properties. (see [below for nested schema](#nestedatt--properties))

Expand All @@ -64,6 +70,15 @@ Optional:

- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).

<a id="nestedatt--definition"></a>

### Nested Schema for `definition`

Read-Only:

- `content` (String) Gzip base64 content of definition part.
Use [`provider::fabric::content_decode`](../functions/content_decode.md) function to decode content.

<a id="nestedatt--properties"></a>

### Nested Schema for `properties`
Expand Down
29 changes: 25 additions & 4 deletions docs/resources/kql_database.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,19 @@ resource "fabric_kql_database" "example4" {

### Required

- `configuration` (Attributes) The KQL Database creation configuration.

Any changes to this configuration will result in recreation of the KQL Database. (see [below for nested schema](#nestedatt--configuration))

- `display_name` (String) The KQL Database display name.
- `workspace_id` (String) The Workspace ID.

### Optional

- `configuration` (Attributes) The KQL Database creation configuration.

Any changes to this configuration will result in recreation of the KQL Database. (see [below for nested schema](#nestedatt--configuration))

- `definition` (Attributes Map) Definition parts. Read more about [KQL Database definition part paths](https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/kql-database-definition). Accepted path keys: **Default** format: `DatabaseProperties.json`, `DatabaseSchema.kql` (see [below for nested schema](#nestedatt--definition))
- `definition_update_enabled` (Boolean) Update definition on change of source content. Default: `true`.
- `description` (String) The KQL Database description.
- `format` (String) The KQL Database format. Possible values: `Default`
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))

### Read-Only
Expand Down Expand Up @@ -110,6 +113,24 @@ Optional:
- `source_cluster_uri` (String) The URI of the source Eventhouse or Azure Data Explorer cluster. Only allowed when `database_type` is `Shortcut`.
- `source_database_name` (String) The name of the database to follow in the source Eventhouse or Azure Data Explorer cluster. Only allowed when `database_type` is `Shortcut`.

<a id="nestedatt--definition"></a>

### Nested Schema for `definition`

Required:

- `source` (String) Path to the file with source of the definition part.

The source content may include placeholders for token substitution. Use the dot with the token name `{{ .TokenName }}`.

Optional:

- `tokens` (Map of String) A map of key/value pairs of tokens substitutes in the source.

Read-Only:

- `source_content_sha256` (String) SHA256 of source's content of definition part.

<a id="nestedatt--timeouts"></a>

### Nested Schema for `timeouts`
Expand Down
14 changes: 7 additions & 7 deletions internal/services/kqldatabase/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const (
ItemDefinitionPathDocsURL = "https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/kql-database-definition"
)

// var itemDefinitionFormats = []fabricitem.DefinitionFormat{ //nolint:gochecknoglobals
// {
// Type: fabricitem.DefinitionFormatDefault,
// API: "",
// Paths: []string{"DatabaseProperties.json", "DatabaseSchema.kql"},
// },
// }
var itemDefinitionFormats = []fabricitem.DefinitionFormat{ //nolint:gochecknoglobals
{
Type: fabricitem.DefinitionFormatDefault,
API: "",
Paths: []string{"DatabaseProperties.json", "DatabaseSchema.kql"},
},
}
16 changes: 7 additions & 9 deletions internal/services/kqldatabase/data_kql_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func NewDataSourceKQLDatabase() datasource.DataSource {
propertiesSetter := func(ctx context.Context, from *fabkqldatabase.Properties, to *fabricitem.DataSourceFabricItemPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties]) diag.Diagnostics {
propertiesSetter := func(ctx context.Context, from *fabkqldatabase.Properties, to *fabricitem.DataSourceFabricItemDefinitionPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties]) diag.Diagnostics {
properties := supertypes.NewSingleNestedObjectValueOfNull[kqlDatabasePropertiesModel](ctx)

if from != nil {
Expand All @@ -34,7 +34,7 @@ func NewDataSourceKQLDatabase() datasource.DataSource {
return nil
}

itemGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.DataSourceFabricItemPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties], fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
itemGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.DataSourceFabricItemDefinitionPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties], fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
client := fabkqldatabase.NewClientFactoryWithClient(fabricClient).NewItemsClient()

respGet, err := client.GetKQLDatabase(ctx, model.WorkspaceID.ValueString(), model.ID.ValueString(), nil)
Expand All @@ -47,7 +47,7 @@ func NewDataSourceKQLDatabase() datasource.DataSource {
return nil
}

itemListGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.DataSourceFabricItemPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties], errNotFound fabcore.ResponseError, fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
itemListGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.DataSourceFabricItemDefinitionPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties], errNotFound fabcore.ResponseError, fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
client := fabkqldatabase.NewClientFactoryWithClient(fabricClient).NewItemsClient()

pager := client.NewListKQLDatabasesPager(model.WorkspaceID.ValueString(), nil)
Expand All @@ -69,24 +69,22 @@ func NewDataSourceKQLDatabase() datasource.DataSource {
return &errNotFound
}

config := fabricitem.DataSourceFabricItemProperties[kqlDatabasePropertiesModel, fabkqldatabase.Properties]{
DataSourceFabricItem: fabricitem.DataSourceFabricItem{
config := fabricitem.DataSourceFabricItemDefinitionProperties[kqlDatabasePropertiesModel, fabkqldatabase.Properties]{
DataSourceFabricItemDefinition: fabricitem.DataSourceFabricItemDefinition{
Type: ItemType,
Name: ItemName,
TFName: ItemTFName,
MarkdownDescription: "Get a Fabric " + ItemName + ".\n\n" +
"Use this data source to fetch a [" + ItemName + "](" + ItemDocsURL + ").\n\n" +
ItemDocsSPNSupport,
IsDisplayNameUnique: true,
// FormatTypeDefault: ItemFormatTypeDefault,
// FormatTypes: ItemFormatTypes,
// DefinitionPathKeys: ItemDefinitionPaths,
DefinitionFormats: itemDefinitionFormats,
},
PropertiesAttributes: getDataSourceKQLDatabasePropertiesAttributes(),
PropertiesSetter: propertiesSetter,
ItemGetter: itemGetter,
ItemListGetter: itemListGetter,
}

return fabricitem.NewDataSourceFabricItemProperties(config)
return fabricitem.NewDataSourceFabricItemDefinitionProperties(config)
}
45 changes: 23 additions & 22 deletions internal/services/kqldatabase/data_kql_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,27 +234,28 @@ func TestAcc_KQLDatabaseDataSource(t *testing.T) {
ExpectError: regexp.MustCompile(common.ErrorReadHeader),
},
// read by id with definition
// {
// ResourceName: testDataSourceItemFQN,
// Config: at.CompileConfig(
// testDataSourceItemHeader,
// map[string]any{
// "workspace_id": workspaceID,
// "id": entityID,
// "output_definition": true,
// },
// ),
// Check: resource.ComposeAggregateTestCheckFunc(
// resource.TestCheckResourceAttr(testDataSourceItemFQN, "workspace_id", workspaceID),
// resource.TestCheckResourceAttr(testDataSourceItemFQN, "id", entityID),
// resource.TestCheckResourceAttr(testDataSourceItemFQN, "display_name", entityDisplayName),
// resource.TestCheckResourceAttr(testDataSourceItemFQN, "description", entityDescription),
// resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.query_service_uri"),
// resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.ingestion_service_uri"),
// resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.eventhouse_id"),
// resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.database_type"),
// resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "definition.DatabaseProperties.json.content"),
// ),
// },
{
ResourceName: testDataSourceItemFQN,
Config: at.CompileConfig(
testDataSourceItemHeader,
map[string]any{
"workspace_id": workspaceID,
"id": entityID,
"format": "Default",
"output_definition": true,
},
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(testDataSourceItemFQN, "workspace_id", workspaceID),
resource.TestCheckResourceAttr(testDataSourceItemFQN, "id", entityID),
resource.TestCheckResourceAttr(testDataSourceItemFQN, "display_name", entityDisplayName),
resource.TestCheckResourceAttr(testDataSourceItemFQN, "description", entityDescription),
resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.query_service_uri"),
resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.ingestion_service_uri"),
resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.eventhouse_id"),
resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "properties.database_type"),
resource.TestCheckResourceAttrSet(testDataSourceItemFQN, "definition.DatabaseProperties.json.content"),
),
},
}))
}
49 changes: 25 additions & 24 deletions internal/services/kqldatabase/resource_kql_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/microsoft/fabric-sdk-go/fabric"
fabkqldatabase "github.com/microsoft/fabric-sdk-go/fabric/kqldatabase"
supertypes "github.com/orange-cloudavenue/terraform-plugin-framework-supertypes"
Expand Down Expand Up @@ -60,7 +62,7 @@ func NewResourceKQLDatabase() resource.Resource {
return &cp, nil
}

propertiesSetter := func(ctx context.Context, from *fabkqldatabase.Properties, to *fabricitem.ResourceFabricItemConfigPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification]) diag.Diagnostics {
propertiesSetter := func(ctx context.Context, from *fabkqldatabase.Properties, to *fabricitem.ResourceFabricItemConfigDefinitionPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification]) diag.Diagnostics {
properties := supertypes.NewSingleNestedObjectValueOfNull[kqlDatabasePropertiesModel](ctx)

if from != nil {
Expand All @@ -77,7 +79,7 @@ func NewResourceKQLDatabase() resource.Resource {
return nil
}

itemGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.ResourceFabricItemConfigPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification], fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
itemGetter := func(ctx context.Context, fabricClient fabric.Client, model fabricitem.ResourceFabricItemConfigDefinitionPropertiesModel[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification], fabricItem *fabricitem.FabricItemProperties[fabkqldatabase.Properties]) error {
client := fabkqldatabase.NewClientFactoryWithClient(fabricClient).NewItemsClient()

respGet, err := client.GetKQLDatabase(ctx, model.WorkspaceID.ValueString(), model.ID.ValueString(), nil)
Expand All @@ -90,36 +92,35 @@ func NewResourceKQLDatabase() resource.Resource {
return nil
}

config := fabricitem.ResourceFabricItemConfigProperties[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification]{
ResourceFabricItem: fabricitem.ResourceFabricItem{
config := fabricitem.ResourceFabricItemConfigDefinitionProperties[kqlDatabasePropertiesModel, fabkqldatabase.Properties, kqlDatabaseConfigurationModel, fabkqldatabase.CreationPayloadClassification]{
ResourceFabricItemDefinition: fabricitem.ResourceFabricItemDefinition{
Type: ItemType,
Name: ItemName,
NameRenameAllowed: true,
TFName: ItemTFName,
MarkdownDescription: "Manage a Fabric " + ItemName + ".\n\n" +
"Use this resource to manage a [" + ItemName + "](" + ItemDocsURL + ").\n\n" +
ItemDocsSPNSupport,
DisplayNameMaxLength: 123,
DescriptionMaxLength: 256,
// FormatTypeDefault: ItemFormatTypeDefault,
// FormatTypes: ItemFormatTypes,
// DefinitionPathDocsURL: ItemDefinitionPathDocsURL,
// DefinitionPathKeys: ItemDefinitionPaths,
// DefinitionPathKeysValidator: []validator.Map{
// mapvalidator.SizeAtLeast(2),
// mapvalidator.SizeAtMost(2),
// mapvalidator.KeysAre(stringvalidator.OneOf(ItemDefinitionPaths...)),
// },
// DefinitionRequired: false,
// DefinitionEmpty: "",
DisplayNameMaxLength: 123,
DescriptionMaxLength: 256,
DefinitionPathDocsURL: ItemDefinitionPathDocsURL,
DefinitionFormats: itemDefinitionFormats,
DefinitionPathKeysValidator: []validator.Map{
mapvalidator.SizeAtLeast(2),
mapvalidator.SizeAtMost(2),
mapvalidator.KeysAre(fabricitem.DefinitionPathKeysValidator(itemDefinitionFormats)...),
},
DefinitionRequired: false,
DefinitionEmpty: "",
},
ConfigRequired: true,
ConfigAttributes: getResourceKQLDatabaseConfigurationAttributes(),
CreationPayloadSetter: creationPayloadSetter,
PropertiesAttributes: getResourceKQLDatabasePropertiesAttributes(),
PropertiesSetter: propertiesSetter,
ItemGetter: itemGetter,
ConfigRequired: false,
ConfigOrDefinitionRequired: true,
ConfigAttributes: getResourceKQLDatabaseConfigurationAttributes(),
CreationPayloadSetter: creationPayloadSetter,
PropertiesAttributes: getResourceKQLDatabasePropertiesAttributes(),
PropertiesSetter: propertiesSetter,
ItemGetter: itemGetter,
}

return fabricitem.NewResourceFabricItemConfigProperties(config)
return fabricitem.NewResourceFabricItemConfigDefinitionProperties(config)
}
Loading

0 comments on commit 2d2b7c1

Please sign in to comment.