2022-12-12 10:31:28 +00:00
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
2024-02-16 20:54:38 +00:00
|
|
|
"context"
|
2024-01-25 11:32:47 +00:00
|
|
|
"reflect"
|
2022-12-12 10:31:28 +00:00
|
|
|
"testing"
|
|
|
|
|
2023-05-16 16:35:39 +00:00
|
|
|
"github.com/databricks/cli/bundle/config"
|
|
|
|
"github.com/databricks/cli/bundle/config/resources"
|
2024-02-16 12:46:24 +00:00
|
|
|
"github.com/databricks/cli/bundle/internal/tf/schema"
|
2024-02-16 20:54:38 +00:00
|
|
|
"github.com/databricks/cli/libs/dyn"
|
|
|
|
"github.com/databricks/cli/libs/dyn/convert"
|
2023-10-16 15:32:49 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/catalog"
|
2023-04-21 08:30:20 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/compute"
|
2024-10-29 09:11:08 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/dashboards"
|
2022-12-12 10:31:28 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/jobs"
|
2023-04-21 08:30:20 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/ml"
|
2023-04-05 14:29:42 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/pipelines"
|
2023-09-07 21:54:31 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/serving"
|
2022-12-12 10:31:28 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2022-12-12 15:36:59 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2022-12-12 10:31:28 +00:00
|
|
|
)
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
func produceTerraformConfiguration(t *testing.T, config config.Root) *schema.Root {
|
|
|
|
vin, err := convert.FromTyped(config, dyn.NilValue)
|
|
|
|
require.NoError(t, err)
|
|
|
|
out, err := BundleToTerraformWithDynValue(context.Background(), vin)
|
|
|
|
require.NoError(t, err)
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertToResourceStruct[T any](t *testing.T, resource *T, data any) {
|
|
|
|
require.NotNil(t, resource)
|
|
|
|
require.NotNil(t, data)
|
|
|
|
|
|
|
|
// Convert data to a dyn.Value.
|
|
|
|
vin, err := convert.FromTyped(data, dyn.NilValue)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Convert the dyn.Value to a struct.
|
|
|
|
err = convert.ToTyped(resource, vin)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformJob(t *testing.T) {
|
2022-12-12 10:31:28 +00:00
|
|
|
var src = resources.Job{
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "my job",
|
|
|
|
JobClusters: []jobs.JobCluster{
|
|
|
|
{
|
|
|
|
JobClusterKey: "key",
|
2024-04-03 10:39:53 +00:00
|
|
|
NewCluster: compute.ClusterSpec{
|
2022-12-12 10:31:28 +00:00
|
|
|
SparkVersion: "10.4.x-scala2.12",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
GitSource: &jobs.GitSource{
|
2023-07-18 15:30:00 +00:00
|
|
|
GitProvider: jobs.GitProviderGitHub,
|
2022-12-12 10:31:28 +00:00
|
|
|
GitUrl: "https://github.com/foo/bar",
|
|
|
|
},
|
2023-09-07 12:48:59 +00:00
|
|
|
Parameters: []jobs.JobParameterDefinition{
|
|
|
|
{
|
|
|
|
Name: "param1",
|
|
|
|
Default: "default1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "param2",
|
|
|
|
Default: "default2",
|
|
|
|
},
|
|
|
|
},
|
2022-12-12 10:31:28 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
2022-12-15 12:00:41 +00:00
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"my_job": &src,
|
2022-12-12 10:31:28 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceJob
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Job["my_job"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "my job", resource.Name)
|
|
|
|
assert.Len(t, resource.JobCluster, 1)
|
|
|
|
assert.Equal(t, "https://github.com/foo/bar", resource.GitSource.Url)
|
|
|
|
assert.Len(t, resource.Parameter, 2)
|
|
|
|
assert.Equal(t, "param1", resource.Parameter[0].Name)
|
|
|
|
assert.Equal(t, "param2", resource.Parameter[1].Name)
|
2022-12-12 10:31:28 +00:00
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
2022-12-12 15:36:59 +00:00
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformJobPermissions(t *testing.T) {
|
2023-03-21 09:58:16 +00:00
|
|
|
var src = resources.Job{
|
|
|
|
Permissions: []resources.Permission{
|
|
|
|
{
|
|
|
|
Level: "CAN_VIEW",
|
|
|
|
UserName: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"my_job": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePermissions
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Permissions["job_my_job"])
|
2023-03-21 09:58:16 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.JobId)
|
|
|
|
assert.Len(t, resource.AccessControl, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.AccessControl[0].UserName)
|
|
|
|
assert.Equal(t, "CAN_VIEW", resource.AccessControl[0].PermissionLevel)
|
2023-03-21 09:58:16 +00:00
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformJobTaskLibraries(t *testing.T) {
|
2022-12-12 15:36:59 +00:00
|
|
|
var src = resources.Job{
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "my job",
|
2023-07-03 09:46:45 +00:00
|
|
|
Tasks: []jobs.Task{
|
2022-12-12 15:36:59 +00:00
|
|
|
{
|
|
|
|
TaskKey: "key",
|
2023-04-21 08:30:20 +00:00
|
|
|
Libraries: []compute.Library{
|
2022-12-12 15:36:59 +00:00
|
|
|
{
|
2023-04-21 08:30:20 +00:00
|
|
|
Pypi: &compute.PythonPyPiLibrary{
|
2022-12-12 15:36:59 +00:00
|
|
|
Package: "mlflow",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
2022-12-15 12:00:41 +00:00
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"my_job": &src,
|
2022-12-12 15:36:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceJob
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Job["my_job"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "my job", resource.Name)
|
|
|
|
require.Len(t, resource.Task, 1)
|
|
|
|
require.Len(t, resource.Task[0].Library, 1)
|
|
|
|
assert.Equal(t, "mlflow", resource.Task[0].Library[0].Pypi.Package)
|
2022-12-12 15:36:59 +00:00
|
|
|
}
|
2023-03-20 20:28:43 +00:00
|
|
|
|
2024-04-05 15:52:39 +00:00
|
|
|
func TestBundleToTerraformForEachTaskLibraries(t *testing.T) {
|
|
|
|
var src = resources.Job{
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "my job",
|
|
|
|
Tasks: []jobs.Task{
|
|
|
|
{
|
|
|
|
TaskKey: "key",
|
|
|
|
ForEachTask: &jobs.ForEachTask{
|
|
|
|
Inputs: "[1,2,3]",
|
|
|
|
Task: jobs.Task{
|
|
|
|
TaskKey: "iteration",
|
|
|
|
Libraries: []compute.Library{
|
|
|
|
{
|
|
|
|
Pypi: &compute.PythonPyPiLibrary{
|
|
|
|
Package: "mlflow",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"my_job": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceJob
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Job["my_job"])
|
2024-04-05 15:52:39 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "my job", resource.Name)
|
|
|
|
require.Len(t, resource.Task, 1)
|
|
|
|
require.Len(t, resource.Task[0].ForEachTask.Task.Library, 1)
|
|
|
|
assert.Equal(t, "mlflow", resource.Task[0].ForEachTask.Task.Library[0].Pypi.Package)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformPipeline(t *testing.T) {
|
2023-04-05 14:29:42 +00:00
|
|
|
var src = resources.Pipeline{
|
|
|
|
PipelineSpec: &pipelines.PipelineSpec{
|
|
|
|
Name: "my pipeline",
|
|
|
|
Libraries: []pipelines.PipelineLibrary{
|
|
|
|
{
|
|
|
|
Notebook: &pipelines.NotebookLibrary{
|
|
|
|
Path: "notebook path",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
File: &pipelines.FileLibrary{
|
|
|
|
Path: "file path",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-12-12 11:36:06 +00:00
|
|
|
Notifications: []pipelines.Notifications{
|
|
|
|
{
|
|
|
|
Alerts: []string{
|
|
|
|
"on-update-fatal-failure",
|
|
|
|
},
|
|
|
|
EmailRecipients: []string{
|
|
|
|
"jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Alerts: []string{
|
|
|
|
"on-update-failure",
|
|
|
|
"on-flow-failure",
|
|
|
|
},
|
|
|
|
EmailRecipients: []string{
|
|
|
|
"jane@doe.com",
|
|
|
|
"john@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-04-05 14:29:42 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Pipelines: map[string]*resources.Pipeline{
|
|
|
|
"my_pipeline": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePipeline
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Pipeline["my_pipeline"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "my pipeline", resource.Name)
|
|
|
|
assert.Len(t, resource.Library, 2)
|
|
|
|
assert.Len(t, resource.Notification, 2)
|
|
|
|
assert.Equal(t, resource.Notification[0].Alerts, []string{"on-update-fatal-failure"})
|
|
|
|
assert.Equal(t, resource.Notification[0].EmailRecipients, []string{"jane@doe.com"})
|
|
|
|
assert.Equal(t, resource.Notification[1].Alerts, []string{"on-update-failure", "on-flow-failure"})
|
|
|
|
assert.Equal(t, resource.Notification[1].EmailRecipients, []string{"jane@doe.com", "john@doe.com"})
|
2023-04-05 14:29:42 +00:00
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformPipelinePermissions(t *testing.T) {
|
2023-03-21 09:58:16 +00:00
|
|
|
var src = resources.Pipeline{
|
|
|
|
Permissions: []resources.Permission{
|
|
|
|
{
|
|
|
|
Level: "CAN_VIEW",
|
|
|
|
UserName: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Pipelines: map[string]*resources.Pipeline{
|
|
|
|
"my_pipeline": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePermissions
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Permissions["pipeline_my_pipeline"])
|
2023-03-21 09:58:16 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.PipelineId)
|
|
|
|
assert.Len(t, resource.AccessControl, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.AccessControl[0].UserName)
|
|
|
|
assert.Equal(t, "CAN_VIEW", resource.AccessControl[0].PermissionLevel)
|
2023-03-21 09:58:16 +00:00
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformModel(t *testing.T) {
|
2023-03-20 20:28:43 +00:00
|
|
|
var src = resources.MlflowModel{
|
2023-04-21 08:30:20 +00:00
|
|
|
Model: &ml.Model{
|
2023-03-20 20:28:43 +00:00
|
|
|
Name: "name",
|
|
|
|
Description: "description",
|
2023-04-21 08:30:20 +00:00
|
|
|
Tags: []ml.ModelTag{
|
2023-03-20 20:28:43 +00:00
|
|
|
{
|
|
|
|
Key: "k1",
|
|
|
|
Value: "v1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Key: "k2",
|
|
|
|
Value: "v2",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Models: map[string]*resources.MlflowModel{
|
|
|
|
"my_model": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceMlflowModel
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.MlflowModel["my_model"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "name", resource.Name)
|
|
|
|
assert.Equal(t, "description", resource.Description)
|
|
|
|
assert.Len(t, resource.Tags, 2)
|
|
|
|
assert.Equal(t, "k1", resource.Tags[0].Key)
|
|
|
|
assert.Equal(t, "v1", resource.Tags[0].Value)
|
|
|
|
assert.Equal(t, "k2", resource.Tags[1].Key)
|
|
|
|
assert.Equal(t, "v2", resource.Tags[1].Value)
|
2023-03-20 20:28:43 +00:00
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformModelPermissions(t *testing.T) {
|
2023-03-21 09:58:16 +00:00
|
|
|
var src = resources.MlflowModel{
|
2024-02-16 20:54:38 +00:00
|
|
|
Model: &ml.Model{
|
|
|
|
Name: "name",
|
|
|
|
},
|
2023-03-21 09:58:16 +00:00
|
|
|
Permissions: []resources.Permission{
|
|
|
|
{
|
|
|
|
Level: "CAN_READ",
|
|
|
|
UserName: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Models: map[string]*resources.MlflowModel{
|
|
|
|
"my_model": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePermissions
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Permissions["mlflow_model_my_model"])
|
2023-03-21 09:58:16 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.RegisteredModelId)
|
|
|
|
assert.Len(t, resource.AccessControl, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.AccessControl[0].UserName)
|
|
|
|
assert.Equal(t, "CAN_READ", resource.AccessControl[0].PermissionLevel)
|
2023-03-21 09:58:16 +00:00
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformExperiment(t *testing.T) {
|
2023-03-20 20:28:43 +00:00
|
|
|
var src = resources.MlflowExperiment{
|
2023-04-21 08:30:20 +00:00
|
|
|
Experiment: &ml.Experiment{
|
2023-03-20 20:28:43 +00:00
|
|
|
Name: "name",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Experiments: map[string]*resources.MlflowExperiment{
|
|
|
|
"my_experiment": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceMlflowExperiment
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.MlflowExperiment["my_experiment"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "name", resource.Name)
|
2023-03-20 20:28:43 +00:00
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
2023-03-21 09:58:16 +00:00
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformExperimentPermissions(t *testing.T) {
|
2023-03-21 09:58:16 +00:00
|
|
|
var src = resources.MlflowExperiment{
|
2024-02-16 20:54:38 +00:00
|
|
|
Experiment: &ml.Experiment{
|
|
|
|
Name: "name",
|
|
|
|
},
|
2023-03-21 09:58:16 +00:00
|
|
|
Permissions: []resources.Permission{
|
|
|
|
{
|
|
|
|
Level: "CAN_READ",
|
|
|
|
UserName: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Experiments: map[string]*resources.MlflowExperiment{
|
|
|
|
"my_experiment": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePermissions
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Permissions["mlflow_experiment_my_experiment"])
|
2023-03-21 09:58:16 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.ExperimentId)
|
|
|
|
assert.Len(t, resource.AccessControl, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.AccessControl[0].UserName)
|
|
|
|
assert.Equal(t, "CAN_READ", resource.AccessControl[0].PermissionLevel)
|
2023-03-21 09:58:16 +00:00
|
|
|
}
|
2023-09-07 21:54:31 +00:00
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformModelServing(t *testing.T) {
|
2023-09-07 21:54:31 +00:00
|
|
|
var src = resources.ModelServingEndpoint{
|
|
|
|
CreateServingEndpoint: &serving.CreateServingEndpoint{
|
|
|
|
Name: "name",
|
|
|
|
Config: serving.EndpointCoreConfigInput{
|
|
|
|
ServedModels: []serving.ServedModelInput{
|
|
|
|
{
|
|
|
|
ModelName: "model_name",
|
|
|
|
ModelVersion: "1",
|
|
|
|
ScaleToZeroEnabled: true,
|
|
|
|
WorkloadSize: "Small",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
TrafficConfig: &serving.TrafficConfig{
|
|
|
|
Routes: []serving.Route{
|
|
|
|
{
|
|
|
|
ServedModelName: "model_name-1",
|
|
|
|
TrafficPercentage: 100,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
ModelServingEndpoints: map[string]*resources.ModelServingEndpoint{
|
|
|
|
"my_model_serving_endpoint": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceModelServing
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.ModelServing["my_model_serving_endpoint"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
2023-09-07 21:54:31 +00:00
|
|
|
assert.Equal(t, "name", resource.Name)
|
|
|
|
assert.Equal(t, "model_name", resource.Config.ServedModels[0].ModelName)
|
|
|
|
assert.Equal(t, "1", resource.Config.ServedModels[0].ModelVersion)
|
|
|
|
assert.Equal(t, true, resource.Config.ServedModels[0].ScaleToZeroEnabled)
|
|
|
|
assert.Equal(t, "Small", resource.Config.ServedModels[0].WorkloadSize)
|
|
|
|
assert.Equal(t, "model_name-1", resource.Config.TrafficConfig.Routes[0].ServedModelName)
|
|
|
|
assert.Equal(t, 100, resource.Config.TrafficConfig.Routes[0].TrafficPercentage)
|
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformModelServingPermissions(t *testing.T) {
|
2023-09-07 21:54:31 +00:00
|
|
|
var src = resources.ModelServingEndpoint{
|
2024-02-16 20:54:38 +00:00
|
|
|
CreateServingEndpoint: &serving.CreateServingEndpoint{
|
|
|
|
Name: "name",
|
2024-06-21 13:43:21 +00:00
|
|
|
|
|
|
|
// Need to specify this to satisfy the equivalence test:
|
|
|
|
// The previous method of generation includes the "create" field
|
|
|
|
// because it is required (not marked as `omitempty`).
|
|
|
|
// The previous method used [json.Marshal] from the standard library
|
|
|
|
// and as such observed the `omitempty` tag.
|
|
|
|
// The new method leverages [dyn.Value] where any field that is not
|
|
|
|
// explicitly set is not part of the value.
|
|
|
|
Config: serving.EndpointCoreConfigInput{
|
|
|
|
ServedModels: []serving.ServedModelInput{
|
|
|
|
{
|
|
|
|
ModelName: "model_name",
|
|
|
|
ModelVersion: "1",
|
|
|
|
ScaleToZeroEnabled: true,
|
|
|
|
WorkloadSize: "Small",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-02-16 20:54:38 +00:00
|
|
|
},
|
2023-09-07 21:54:31 +00:00
|
|
|
Permissions: []resources.Permission{
|
|
|
|
{
|
|
|
|
Level: "CAN_VIEW",
|
|
|
|
UserName: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
ModelServingEndpoints: map[string]*resources.ModelServingEndpoint{
|
|
|
|
"my_model_serving_endpoint": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourcePermissions
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Permissions["model_serving_my_model_serving_endpoint"])
|
2023-09-07 21:54:31 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.ServingEndpointId)
|
|
|
|
assert.Len(t, resource.AccessControl, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.AccessControl[0].UserName)
|
|
|
|
assert.Equal(t, "CAN_VIEW", resource.AccessControl[0].PermissionLevel)
|
2023-09-07 21:54:31 +00:00
|
|
|
}
|
2023-10-16 15:32:49 +00:00
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformRegisteredModel(t *testing.T) {
|
2023-10-16 15:32:49 +00:00
|
|
|
var src = resources.RegisteredModel{
|
|
|
|
CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{
|
|
|
|
Name: "name",
|
|
|
|
CatalogName: "catalog",
|
|
|
|
SchemaName: "schema",
|
|
|
|
Comment: "comment",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
RegisteredModels: map[string]*resources.RegisteredModel{
|
|
|
|
"my_registered_model": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceRegisteredModel
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.RegisteredModel["my_registered_model"])
|
2024-02-16 12:46:24 +00:00
|
|
|
|
2023-10-16 15:32:49 +00:00
|
|
|
assert.Equal(t, "name", resource.Name)
|
|
|
|
assert.Equal(t, "catalog", resource.CatalogName)
|
|
|
|
assert.Equal(t, "schema", resource.SchemaName)
|
|
|
|
assert.Equal(t, "comment", resource.Comment)
|
|
|
|
assert.Nil(t, out.Data)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestBundleToTerraformRegisteredModelGrants(t *testing.T) {
|
2023-10-16 15:32:49 +00:00
|
|
|
var src = resources.RegisteredModel{
|
2024-02-16 20:54:38 +00:00
|
|
|
CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{
|
|
|
|
Name: "name",
|
|
|
|
CatalogName: "catalog",
|
|
|
|
SchemaName: "schema",
|
|
|
|
},
|
2023-10-16 15:32:49 +00:00
|
|
|
Grants: []resources.Grant{
|
|
|
|
{
|
|
|
|
Privileges: []string{"EXECUTE"},
|
|
|
|
Principal: "jane@doe.com",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
RegisteredModels: map[string]*resources.RegisteredModel{
|
|
|
|
"my_registered_model": &src,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-10-18 15:38:10 +00:00
|
|
|
var resource schema.ResourceGrants
|
|
|
|
out := produceTerraformConfiguration(t, config)
|
|
|
|
convertToResourceStruct(t, &resource, out.Resource.Grants["registered_model_my_registered_model"])
|
2023-10-16 15:32:49 +00:00
|
|
|
|
2024-02-16 12:46:24 +00:00
|
|
|
assert.NotEmpty(t, resource.Function)
|
|
|
|
assert.Len(t, resource.Grant, 1)
|
|
|
|
assert.Equal(t, "jane@doe.com", resource.Grant[0].Principal)
|
|
|
|
assert.Equal(t, "EXECUTE", resource.Grant[0].Privileges[0])
|
2024-01-25 11:32:47 +00:00
|
|
|
}
|
2023-10-16 15:32:49 +00:00
|
|
|
|
2024-05-01 08:22:35 +00:00
|
|
|
func TestBundleToTerraformDeletedResources(t *testing.T) {
|
|
|
|
var job1 = resources.Job{
|
|
|
|
JobSettings: &jobs.JobSettings{},
|
|
|
|
}
|
|
|
|
var job2 = resources.Job{
|
|
|
|
ModifiedStatus: resources.ModifiedStatusDeleted,
|
|
|
|
JobSettings: &jobs.JobSettings{},
|
|
|
|
}
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"my_job1": &job1,
|
|
|
|
"my_job2": &job2,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
vin, err := convert.FromTyped(config, dyn.NilValue)
|
|
|
|
require.NoError(t, err)
|
|
|
|
out, err := BundleToTerraformWithDynValue(context.Background(), vin)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, ok := out.Resource.Job["my_job1"]
|
|
|
|
assert.True(t, ok)
|
|
|
|
_, ok = out.Resource.Job["my_job2"]
|
|
|
|
assert.False(t, ok)
|
|
|
|
}
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
func TestTerraformToBundleEmptyLocalResources(t *testing.T) {
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{},
|
|
|
|
}
|
2024-05-01 08:22:35 +00:00
|
|
|
var tfState = resourcesState{
|
|
|
|
Resources: []stateResource{
|
|
|
|
{
|
|
|
|
Type: "databricks_job",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_job",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_pipeline",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_pipeline",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_model",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_experiment",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_experiment",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_model_serving",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_model_serving",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_registered_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_registered_model",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
},
|
2024-05-31 09:42:25 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_quality_monitor",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_monitor",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
2024-07-31 12:16:28 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_schema",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_schema",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
2024-09-23 10:42:34 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_cluster",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_cluster",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
2024-10-29 09:11:08 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_dashboard",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_dashboard",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
err := TerraformToBundle(&tfState, &config)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Jobs["test_job"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Jobs["test_job"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Pipelines["test_pipeline"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Pipelines["test_pipeline"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Models["test_mlflow_model"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Models["test_mlflow_model"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Experiments["test_mlflow_experiment"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Experiments["test_mlflow_experiment"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.ModelServingEndpoints["test_model_serving"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.ModelServingEndpoints["test_model_serving"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.RegisteredModels["test_registered_model"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.RegisteredModels["test_registered_model"].ModifiedStatus)
|
|
|
|
|
2024-05-31 09:42:25 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.QualityMonitors["test_monitor"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.QualityMonitors["test_monitor"].ModifiedStatus)
|
|
|
|
|
2024-07-31 12:16:28 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.Schemas["test_schema"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Schemas["test_schema"].ModifiedStatus)
|
|
|
|
|
2024-09-23 10:42:34 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.Clusters["test_cluster"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Clusters["test_cluster"].ModifiedStatus)
|
|
|
|
|
2024-10-29 09:11:08 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.Dashboards["test_dashboard"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Dashboards["test_dashboard"].ModifiedStatus)
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
AssertFullResourceCoverage(t, &config)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTerraformToBundleEmptyRemoteResources(t *testing.T) {
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"test_job": {
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "test_job",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Pipelines: map[string]*resources.Pipeline{
|
|
|
|
"test_pipeline": {
|
|
|
|
PipelineSpec: &pipelines.PipelineSpec{
|
|
|
|
Name: "test_pipeline",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Models: map[string]*resources.MlflowModel{
|
|
|
|
"test_mlflow_model": {
|
|
|
|
Model: &ml.Model{
|
|
|
|
Name: "test_mlflow_model",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Experiments: map[string]*resources.MlflowExperiment{
|
|
|
|
"test_mlflow_experiment": {
|
|
|
|
Experiment: &ml.Experiment{
|
|
|
|
Name: "test_mlflow_experiment",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ModelServingEndpoints: map[string]*resources.ModelServingEndpoint{
|
|
|
|
"test_model_serving": {
|
|
|
|
CreateServingEndpoint: &serving.CreateServingEndpoint{
|
|
|
|
Name: "test_model_serving",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
RegisteredModels: map[string]*resources.RegisteredModel{
|
|
|
|
"test_registered_model": {
|
|
|
|
CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{
|
|
|
|
Name: "test_registered_model",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-05-31 09:42:25 +00:00
|
|
|
QualityMonitors: map[string]*resources.QualityMonitor{
|
|
|
|
"test_monitor": {
|
|
|
|
CreateMonitor: &catalog.CreateMonitor{
|
|
|
|
TableName: "test_monitor",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-07-31 12:16:28 +00:00
|
|
|
Schemas: map[string]*resources.Schema{
|
|
|
|
"test_schema": {
|
|
|
|
CreateSchema: &catalog.CreateSchema{
|
|
|
|
Name: "test_schema",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-09-23 10:42:34 +00:00
|
|
|
Clusters: map[string]*resources.Cluster{
|
|
|
|
"test_cluster": {
|
|
|
|
ClusterSpec: &compute.ClusterSpec{
|
|
|
|
ClusterName: "test_cluster",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-10-29 09:11:08 +00:00
|
|
|
Dashboards: map[string]*resources.Dashboard{
|
|
|
|
"test_dashboard": {
|
2024-11-13 13:40:53 +00:00
|
|
|
Dashboard: &dashboards.Dashboard{
|
2024-10-29 09:11:08 +00:00
|
|
|
DisplayName: "test_dashboard",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
}
|
2024-05-01 08:22:35 +00:00
|
|
|
var tfState = resourcesState{
|
|
|
|
Resources: nil,
|
2024-01-25 11:32:47 +00:00
|
|
|
}
|
|
|
|
err := TerraformToBundle(&tfState, &config)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.Jobs["test_job"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Jobs["test_job"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.Pipelines["test_pipeline"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Pipelines["test_pipeline"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.Models["test_mlflow_model"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Models["test_mlflow_model"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.Experiments["test_mlflow_experiment"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Experiments["test_mlflow_experiment"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.ModelServingEndpoints["test_model_serving"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.ModelServingEndpoints["test_model_serving"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "", config.Resources.RegisteredModels["test_registered_model"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.RegisteredModels["test_registered_model"].ModifiedStatus)
|
|
|
|
|
2024-05-31 09:42:25 +00:00
|
|
|
assert.Equal(t, "", config.Resources.QualityMonitors["test_monitor"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.QualityMonitors["test_monitor"].ModifiedStatus)
|
|
|
|
|
2024-07-31 12:16:28 +00:00
|
|
|
assert.Equal(t, "", config.Resources.Schemas["test_schema"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Schemas["test_schema"].ModifiedStatus)
|
|
|
|
|
2024-09-23 10:42:34 +00:00
|
|
|
assert.Equal(t, "", config.Resources.Clusters["test_cluster"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Clusters["test_cluster"].ModifiedStatus)
|
|
|
|
|
2024-10-29 09:11:08 +00:00
|
|
|
assert.Equal(t, "", config.Resources.Dashboards["test_dashboard"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Dashboards["test_dashboard"].ModifiedStatus)
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
AssertFullResourceCoverage(t, &config)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTerraformToBundleModifiedResources(t *testing.T) {
|
|
|
|
var config = config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"test_job": {
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "test_job",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_job_new": {
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Name: "test_job_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Pipelines: map[string]*resources.Pipeline{
|
|
|
|
"test_pipeline": {
|
|
|
|
PipelineSpec: &pipelines.PipelineSpec{
|
|
|
|
Name: "test_pipeline",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_pipeline_new": {
|
|
|
|
PipelineSpec: &pipelines.PipelineSpec{
|
|
|
|
Name: "test_pipeline_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Models: map[string]*resources.MlflowModel{
|
|
|
|
"test_mlflow_model": {
|
|
|
|
Model: &ml.Model{
|
|
|
|
Name: "test_mlflow_model",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_mlflow_model_new": {
|
|
|
|
Model: &ml.Model{
|
|
|
|
Name: "test_mlflow_model_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Experiments: map[string]*resources.MlflowExperiment{
|
|
|
|
"test_mlflow_experiment": {
|
|
|
|
Experiment: &ml.Experiment{
|
|
|
|
Name: "test_mlflow_experiment",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_mlflow_experiment_new": {
|
|
|
|
Experiment: &ml.Experiment{
|
|
|
|
Name: "test_mlflow_experiment_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ModelServingEndpoints: map[string]*resources.ModelServingEndpoint{
|
|
|
|
"test_model_serving": {
|
|
|
|
CreateServingEndpoint: &serving.CreateServingEndpoint{
|
|
|
|
Name: "test_model_serving",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_model_serving_new": {
|
|
|
|
CreateServingEndpoint: &serving.CreateServingEndpoint{
|
|
|
|
Name: "test_model_serving_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
RegisteredModels: map[string]*resources.RegisteredModel{
|
|
|
|
"test_registered_model": {
|
|
|
|
CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{
|
|
|
|
Name: "test_registered_model",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_registered_model_new": {
|
|
|
|
CreateRegisteredModelRequest: &catalog.CreateRegisteredModelRequest{
|
|
|
|
Name: "test_registered_model_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-05-31 09:42:25 +00:00
|
|
|
QualityMonitors: map[string]*resources.QualityMonitor{
|
|
|
|
"test_monitor": {
|
|
|
|
CreateMonitor: &catalog.CreateMonitor{
|
|
|
|
TableName: "test_monitor",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_monitor_new": {
|
|
|
|
CreateMonitor: &catalog.CreateMonitor{
|
|
|
|
TableName: "test_monitor_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-07-31 12:16:28 +00:00
|
|
|
Schemas: map[string]*resources.Schema{
|
|
|
|
"test_schema": {
|
|
|
|
CreateSchema: &catalog.CreateSchema{
|
|
|
|
Name: "test_schema",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_schema_new": {
|
|
|
|
CreateSchema: &catalog.CreateSchema{
|
|
|
|
Name: "test_schema_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-09-23 10:42:34 +00:00
|
|
|
Clusters: map[string]*resources.Cluster{
|
|
|
|
"test_cluster": {
|
|
|
|
ClusterSpec: &compute.ClusterSpec{
|
|
|
|
ClusterName: "test_cluster",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_cluster_new": {
|
|
|
|
ClusterSpec: &compute.ClusterSpec{
|
|
|
|
ClusterName: "test_cluster_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-10-29 09:11:08 +00:00
|
|
|
Dashboards: map[string]*resources.Dashboard{
|
|
|
|
"test_dashboard": {
|
2024-11-13 13:40:53 +00:00
|
|
|
Dashboard: &dashboards.Dashboard{
|
2024-10-29 09:11:08 +00:00
|
|
|
DisplayName: "test_dashboard",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_dashboard_new": {
|
2024-11-13 13:40:53 +00:00
|
|
|
Dashboard: &dashboards.Dashboard{
|
2024-10-29 09:11:08 +00:00
|
|
|
DisplayName: "test_dashboard_new",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
}
|
2024-05-01 08:22:35 +00:00
|
|
|
var tfState = resourcesState{
|
|
|
|
Resources: []stateResource{
|
|
|
|
{
|
|
|
|
Type: "databricks_job",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_job",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_job",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_job_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_pipeline",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_pipeline",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_pipeline",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_pipeline_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_model",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_model_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_experiment",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_experiment",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_mlflow_experiment",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_mlflow_experiment_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_model_serving",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_model_serving",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_model_serving",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_model_serving_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_registered_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_registered_model",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_registered_model",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_registered_model_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
},
|
2024-05-31 09:42:25 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_quality_monitor",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_monitor",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "test_monitor"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_quality_monitor",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_monitor_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "test_monitor_old"}},
|
|
|
|
},
|
|
|
|
},
|
2024-07-31 12:16:28 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_schema",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_schema",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_schema",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_schema_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
2024-09-23 10:42:34 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_cluster",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_cluster",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_cluster",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_cluster_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
2024-10-29 09:11:08 +00:00
|
|
|
{
|
|
|
|
Type: "databricks_dashboard",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_dashboard",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: "databricks_dashboard",
|
|
|
|
Mode: "managed",
|
|
|
|
Name: "test_dashboard_old",
|
|
|
|
Instances: []stateResourceInstance{
|
|
|
|
{Attributes: stateInstanceAttributes{ID: "2"}},
|
|
|
|
},
|
|
|
|
},
|
2024-01-25 11:32:47 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
err := TerraformToBundle(&tfState, &config)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Jobs["test_job"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Jobs["test_job"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Jobs["test_job_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Jobs["test_job_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Jobs["test_job_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Jobs["test_job_new"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Pipelines["test_pipeline"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Pipelines["test_pipeline"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Pipelines["test_pipeline_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Pipelines["test_pipeline_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Pipelines["test_pipeline_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Pipelines["test_pipeline_new"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Models["test_mlflow_model"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Models["test_mlflow_model"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Models["test_mlflow_model_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Models["test_mlflow_model_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Models["test_mlflow_model_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Models["test_mlflow_model_new"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.RegisteredModels["test_registered_model"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.RegisteredModels["test_registered_model"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.RegisteredModels["test_registered_model_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.RegisteredModels["test_registered_model_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.RegisteredModels["test_registered_model_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.RegisteredModels["test_registered_model_new"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Experiments["test_mlflow_experiment"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Experiments["test_mlflow_experiment"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Experiments["test_mlflow_experiment_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Experiments["test_mlflow_experiment_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Experiments["test_mlflow_experiment_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Experiments["test_mlflow_experiment_new"].ModifiedStatus)
|
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.ModelServingEndpoints["test_model_serving"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.ModelServingEndpoints["test_model_serving"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.ModelServingEndpoints["test_model_serving_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.ModelServingEndpoints["test_model_serving_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.ModelServingEndpoints["test_model_serving_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.ModelServingEndpoints["test_model_serving_new"].ModifiedStatus)
|
|
|
|
|
2024-05-31 09:42:25 +00:00
|
|
|
assert.Equal(t, "test_monitor", config.Resources.QualityMonitors["test_monitor"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.QualityMonitors["test_monitor"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "test_monitor_old", config.Resources.QualityMonitors["test_monitor_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.QualityMonitors["test_monitor_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.QualityMonitors["test_monitor_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.QualityMonitors["test_monitor_new"].ModifiedStatus)
|
2024-07-31 12:16:28 +00:00
|
|
|
|
|
|
|
assert.Equal(t, "1", config.Resources.Schemas["test_schema"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Schemas["test_schema"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Schemas["test_schema_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Schemas["test_schema_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Schemas["test_schema_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Schemas["test_schema_new"].ModifiedStatus)
|
|
|
|
|
2024-09-23 10:42:34 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.Clusters["test_cluster"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Clusters["test_cluster"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Clusters["test_cluster_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Clusters["test_cluster_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Clusters["test_cluster_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Clusters["test_cluster_new"].ModifiedStatus)
|
|
|
|
|
2024-10-29 09:11:08 +00:00
|
|
|
assert.Equal(t, "1", config.Resources.Dashboards["test_dashboard"].ID)
|
|
|
|
assert.Equal(t, "", config.Resources.Dashboards["test_dashboard"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "2", config.Resources.Dashboards["test_dashboard_old"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusDeleted, config.Resources.Dashboards["test_dashboard_old"].ModifiedStatus)
|
|
|
|
assert.Equal(t, "", config.Resources.Dashboards["test_dashboard_new"].ID)
|
|
|
|
assert.Equal(t, resources.ModifiedStatusCreated, config.Resources.Dashboards["test_dashboard_new"].ModifiedStatus)
|
|
|
|
|
2024-01-25 11:32:47 +00:00
|
|
|
AssertFullResourceCoverage(t, &config)
|
|
|
|
}
|
|
|
|
|
|
|
|
func AssertFullResourceCoverage(t *testing.T, config *config.Root) {
|
|
|
|
resources := reflect.ValueOf(config.Resources)
|
|
|
|
for i := 0; i < resources.NumField(); i++ {
|
|
|
|
field := resources.Field(i)
|
|
|
|
if field.Kind() == reflect.Map {
|
|
|
|
assert.True(
|
|
|
|
t,
|
|
|
|
!field.IsNil() && field.Len() > 0,
|
|
|
|
"TerraformToBundle should support '%s' (please add it to convert.go and extend the test suite)",
|
|
|
|
resources.Type().Field(i).Name,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2023-10-16 15:32:49 +00:00
|
|
|
}
|