Skip to content

Commit

Permalink
databricks#3950: migrated to the plugin framework
Browse files Browse the repository at this point in the history
  • Loading branch information
dgomez04 committed Oct 14, 2024
1 parent 5cd4114 commit e080a2c
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 294 deletions.
2 changes: 2 additions & 0 deletions internal/providers/pluginfw/pluginfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
providercommon "github.com/databricks/terraform-provider-databricks/internal/providers/common"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/resources/cluster"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/resources/library"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/resources/notificationdestinations"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/resources/qualitymonitor"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/resources/volume"

Expand Down Expand Up @@ -52,6 +53,7 @@ func (p *DatabricksProviderPluginFramework) DataSources(ctx context.Context) []f
return []func() datasource.DataSource{
cluster.DataSourceCluster,
volume.DataSourceVolumes,
notificationdestinations.DataSourceNotificationDestinations,
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package notificationdestinations

import (
"context"
"fmt"
"strings"

"github.com/databricks/databricks-sdk-go/service/settings"
"github.com/databricks/terraform-provider-databricks/common"
pluginfwcommon "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/common"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/converters"
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/tfschema"
"github.com/databricks/terraform-provider-databricks/internal/service/settings_tf"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
)

func DataSourceNotificationDestinations() datasource.DataSource {
return &NotificationDestinationsDataSource{}
}

var _ datasource.DataSourceWithConfigure = &NotificationDestinationsDataSource{}

type NotificationDestinationsDataSource struct {
Client *common.DatabricksClient
}

type NotificationDestinationsInfo struct {
Id types.String `tfsdk:"id" tf:"computed"`
DisplayNameContains types.String `tfsdk:"display_name_contains" tf:"optional"`
Type types.String `tfsdk:"type" tf:"optional"`
NotificationDestinations []settings_tf.ListNotificationDestinationsResult `tfsdk:"notification_destinations" tf:"computed"`
}

func (d *NotificationDestinationsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = "databricks_notification_destinations_pluginframework"
}

func (d *NotificationDestinationsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: tfschema.DataSourceStructToSchemaMap(NotificationDestinationsInfo{}, nil),
}
}

func (d *NotificationDestinationsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if d.Client == nil {
d.Client = pluginfwcommon.ConfigureDataSource(req, resp)
}
}

func validateType(notificationType string) diag.Diagnostics {
validTypes := map[string]struct{}{
string(settings.DestinationTypeEmail): {},
string(settings.DestinationTypeMicrosoftTeams): {},
string(settings.DestinationTypePagerduty): {},
string(settings.DestinationTypeSlack): {},
string(settings.DestinationTypeWebhook): {},
}

if _, valid := validTypes[notificationType]; !valid {
return diag.Diagnostics{diag.NewErrorDiagnostic(fmt.Sprintf("Invalid type '%s'; valid types are EMAIL, MICROSOFT_TEAMS, PAGERDUTY, SLACK, WEBHOOK.", notificationType), "")}
}
return nil
}

func validateLength(destinations []settings_tf.ListNotificationDestinationsResult) diag.Diagnostics {
if len(destinations) == 0 {
return diag.Diagnostics{diag.NewErrorDiagnostic("Could not find any notification destinations with the specified criteria.", "")}
}
return nil
}

func appendToResponse(resp *datasource.ReadResponse, diags diag.Diagnostics) bool {
resp.Diagnostics.Append(diags...)
return resp.Diagnostics.HasError()
}

func (d *NotificationDestinationsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
w, diags := d.Client.GetWorkspaceClient()
if appendToResponse(resp, diags) {
return
}

var notificationInfo NotificationDestinationsInfo
if appendToResponse(resp, req.Config.Get(ctx, &notificationInfo)) {
return
}

notificationType := notificationInfo.Type.ValueString()
notificationDisplayName := notificationInfo.DisplayNameContains.ValueString()

if notificationType != "" {
if appendToResponse(resp, validateType(notificationType)) {
return
}
}

notificationsGoSdk, err := w.NotificationDestinations.ListAll(ctx, settings.ListNotificationDestinationsRequest{})
if err != nil {
resp.Diagnostics.AddError("Failed to fetch Notification Destinations", err.Error())
return
}

var notificationsTfSdk []settings_tf.ListNotificationDestinationsResult
for _, notification := range notificationsGoSdk {
if (notification.DestinationType.String() != notificationType) || (notificationDisplayName != "" && !strings.Contains(notification.DisplayName, notificationDisplayName)) {
continue
}

var notificationDestination settings_tf.ListNotificationDestinationsResult
if appendToResponse(resp, converters.GoSdkToTfSdkStruct(ctx, notification, &notificationDestination)) {
return
}
notificationsTfSdk = append(notificationsTfSdk, notificationDestination)
}

if appendToResponse(resp, validateLength(notificationsTfSdk)) {
return
}

notificationInfo.NotificationDestinations = notificationsTfSdk
resp.Diagnostics.Append(resp.State.Set(ctx, notificationInfo)...)

}
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
package acceptance
package notificationdestinations_test

import (
"testing"

"github.com/databricks/terraform-provider-databricks/internal/acceptance"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const dataSourceTemplate = `
resource "databricks_notification_destination" "email_notification" {
display_name = "email notification destination"
config {
email {
addresses = ["abc@gmail.com"]
}
}
}
resource "databricks_notification_destination" "notification" {
display_name = "slack notification destination"
config {
slack {
url = "https://hooks.slack.com/services/..."
}
}
}
data "databricks_notification_destinations" "this" {}
`

func checkNotificationsDestinationsDataSourcePopulated(t *testing.T) func(s *terraform.State) error {
func CheckDataSourceNotificationsPopulated(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
ds, ok := s.Modules[0].Resources["data.databricks_notification_destinations.this"]
require.True(t, ok, "data.databricks_notification_destinations.this has to be there")
Expand All @@ -54,9 +33,29 @@ func checkNotificationsDestinationsDataSourcePopulated(t *testing.T) func(s *ter
}
}

func TestWorkspaceDataSourceNotificationDestination(t *testing.T) {
WorkspaceLevel(t, Step{
Template: dataSourceTemplate,
Check: checkNotificationsDestinationsDataSourcePopulated(t),
func TestAccNotificationsCreation(t *testing.T) {
acceptance.WorkspaceLevel(t, acceptance.Step{
Template: `
resource "databricks_notification_destination" "email_notification" {
display_name = "email notification destination"
config {
email {
addresses = ["abc@gmail.com"]
}
}
}
resource "databricks_notification_destination" "notification" {
display_name = "slack notification destination"
config {
slack {
url = "https://hooks.slack.com/services/..."
}
}
}
data "databricks_notification_destinations" "this" {}
`,
Check: CheckDataSourceNotificationsPopulated(t),
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package notificationdestinations

import (
"testing"

"github.com/databricks/terraform-provider-databricks/internal/service/settings_tf"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/stretchr/testify/assert"
)

func TestValidateType_InvalidType(t *testing.T) {
actualDiagnostics := validateType("INVALID")
expectedDiagnostics := diag.Diagnostics{diag.NewErrorDiagnostic("Invalid type 'INVALID'; valid types are EMAIL, MICROSOFT_TEAMS, PAGERDUTY, SLACK, WEBHOOK.", "")}
assert.True(t, actualDiagnostics.HasError())
assert.Equal(t, expectedDiagnostics, actualDiagnostics)
}

func TestValidateLength(t *testing.T) {
actualDiagnostics := validateLength([]settings_tf.ListNotificationDestinationsResult{})
expectedDiagnostics := diag.Diagnostics{diag.NewErrorDiagnostic("Could not find any notification destinations with the specified criteria.", "")}
assert.True(t, actualDiagnostics.HasError())
assert.Equal(t, expectedDiagnostics, actualDiagnostics)
}
1 change: 0 additions & 1 deletion internal/providers/sdkv2/sdkv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ func DatabricksProvider() *schema.Provider {
"databricks_mws_credentials": mws.DataSourceMwsCredentials().ToResource(),
"databricks_mws_workspaces": mws.DataSourceMwsWorkspaces().ToResource(),
"databricks_node_type": clusters.DataSourceNodeType().ToResource(),
"databricks_notification_destinations": settings.DataSourceNotificationDestinations().ToResource(),
"databricks_notebook": workspace.DataSourceNotebook().ToResource(),
"databricks_notebook_paths": workspace.DataSourceNotebookPaths().ToResource(),
"databricks_pipelines": pipelines.DataSourcePipelines().ToResource(),
Expand Down
85 changes: 0 additions & 85 deletions settings/data_notification_destinations.go

This file was deleted.

Loading

0 comments on commit e080a2c

Please sign in to comment.