mirror of https://github.com/databricks/cli.git
210 lines
6.5 KiB
Go
210 lines
6.5 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
|
|
"github.com/databricks/cli/bundle/config/resources"
|
|
"github.com/databricks/databricks-sdk-go"
|
|
)
|
|
|
|
// Resources defines Databricks resources associated with the bundle.
|
|
type Resources struct {
|
|
Jobs map[string]*resources.Job `json:"jobs,omitempty"`
|
|
Pipelines map[string]*resources.Pipeline `json:"pipelines,omitempty"`
|
|
|
|
Models map[string]*resources.MlflowModel `json:"models,omitempty"`
|
|
Experiments map[string]*resources.MlflowExperiment `json:"experiments,omitempty"`
|
|
ModelServingEndpoints map[string]*resources.ModelServingEndpoint `json:"model_serving_endpoints,omitempty"`
|
|
RegisteredModels map[string]*resources.RegisteredModel `json:"registered_models,omitempty"`
|
|
QualityMonitors map[string]*resources.QualityMonitor `json:"quality_monitors,omitempty"`
|
|
Schemas map[string]*resources.Schema `json:"schemas,omitempty"`
|
|
Volumes map[string]*resources.Volume `json:"volumes,omitempty"`
|
|
Clusters map[string]*resources.Cluster `json:"clusters,omitempty"`
|
|
Dashboards map[string]*resources.Dashboard `json:"dashboards,omitempty"`
|
|
Apps map[string]*resources.App `json:"apps,omitempty"`
|
|
}
|
|
|
|
type ConfigResource interface {
|
|
// Function to assert if the resource exists in the workspace configured in
|
|
// the input workspace client.
|
|
Exists(ctx context.Context, w *databricks.WorkspaceClient, id string) (bool, error)
|
|
|
|
// Terraform equivalent name of the resource. For example "databricks_job"
|
|
// for jobs and "databricks_pipeline" for pipelines.
|
|
TerraformResourceName() string
|
|
|
|
// GetName returns the in-product name of the resource.
|
|
GetName() string
|
|
|
|
// GetURL returns the URL of the resource.
|
|
GetURL() string
|
|
|
|
// InitializeURL initializes the URL field of the resource.
|
|
InitializeURL(baseURL url.URL)
|
|
|
|
// IsNil returns true if the resource is nil, for example, when it was removed from the bundle.
|
|
IsNil() bool
|
|
}
|
|
|
|
// ResourceGroup represents a group of resources of the same type.
|
|
// It includes a description of the resource type and a map of resources.
|
|
type ResourceGroup struct {
|
|
Description ResourceDescription
|
|
Resources map[string]ConfigResource
|
|
}
|
|
|
|
// collectResourceMap collects resources of a specific type into a ResourceGroup.
|
|
func collectResourceMap[T ConfigResource](
|
|
description ResourceDescription,
|
|
input map[string]T,
|
|
) ResourceGroup {
|
|
resources := make(map[string]ConfigResource)
|
|
for key, resource := range input {
|
|
if resource.IsNil() {
|
|
continue
|
|
}
|
|
resources[key] = resource
|
|
}
|
|
return ResourceGroup{
|
|
Description: description,
|
|
Resources: resources,
|
|
}
|
|
}
|
|
|
|
// AllResources returns all resources in the bundle grouped by their resource type.
|
|
func (r *Resources) AllResources() []ResourceGroup {
|
|
descriptions := SupportedResources()
|
|
return []ResourceGroup{
|
|
collectResourceMap(descriptions["jobs"], r.Jobs),
|
|
collectResourceMap(descriptions["pipelines"], r.Pipelines),
|
|
collectResourceMap(descriptions["models"], r.Models),
|
|
collectResourceMap(descriptions["experiments"], r.Experiments),
|
|
collectResourceMap(descriptions["model_serving_endpoints"], r.ModelServingEndpoints),
|
|
collectResourceMap(descriptions["registered_models"], r.RegisteredModels),
|
|
collectResourceMap(descriptions["quality_monitors"], r.QualityMonitors),
|
|
collectResourceMap(descriptions["schemas"], r.Schemas),
|
|
collectResourceMap(descriptions["clusters"], r.Clusters),
|
|
collectResourceMap(descriptions["dashboards"], r.Dashboards),
|
|
collectResourceMap(descriptions["volumes"], r.Volumes),
|
|
collectResourceMap(descriptions["apps"], r.Apps),
|
|
}
|
|
}
|
|
|
|
func (r *Resources) FindResourceByConfigKey(key string) (ConfigResource, error) {
|
|
found := make([]ConfigResource, 0)
|
|
for k := range r.Jobs {
|
|
if k == key {
|
|
found = append(found, r.Jobs[k])
|
|
}
|
|
}
|
|
for k := range r.Pipelines {
|
|
if k == key {
|
|
found = append(found, r.Pipelines[k])
|
|
}
|
|
}
|
|
|
|
if len(found) == 0 {
|
|
return nil, fmt.Errorf("no such resource: %s", key)
|
|
}
|
|
|
|
if len(found) > 1 {
|
|
keys := make([]string, 0, len(found))
|
|
for _, r := range found {
|
|
keys = append(keys, fmt.Sprintf("%s:%s", r.TerraformResourceName(), key))
|
|
}
|
|
return nil, fmt.Errorf("ambiguous: %s (can resolve to all of %s)", key, keys)
|
|
}
|
|
|
|
return found[0], nil
|
|
}
|
|
|
|
type ResourceDescription struct {
|
|
// Singular and plural name when used to refer to the configuration.
|
|
SingularName string
|
|
PluralName string
|
|
|
|
// Singular and plural title when used in summaries / terminal UI.
|
|
SingularTitle string
|
|
PluralTitle string
|
|
}
|
|
|
|
// The keys of the map corresponds to the resource key in the bundle configuration.
|
|
func SupportedResources() map[string]ResourceDescription {
|
|
return map[string]ResourceDescription{
|
|
"jobs": {
|
|
SingularName: "job",
|
|
PluralName: "jobs",
|
|
SingularTitle: "Job",
|
|
PluralTitle: "Jobs",
|
|
},
|
|
"pipelines": {
|
|
SingularName: "pipeline",
|
|
PluralName: "pipelines",
|
|
SingularTitle: "Pipeline",
|
|
PluralTitle: "Pipelines",
|
|
},
|
|
"models": {
|
|
SingularName: "model",
|
|
PluralName: "models",
|
|
SingularTitle: "Model",
|
|
PluralTitle: "Models",
|
|
},
|
|
"experiments": {
|
|
SingularName: "experiment",
|
|
PluralName: "experiments",
|
|
SingularTitle: "Experiment",
|
|
PluralTitle: "Experiments",
|
|
},
|
|
"model_serving_endpoints": {
|
|
SingularName: "model_serving_endpoint",
|
|
PluralName: "model_serving_endpoints",
|
|
SingularTitle: "Model Serving Endpoint",
|
|
PluralTitle: "Model Serving Endpoints",
|
|
},
|
|
"registered_models": {
|
|
SingularName: "registered_model",
|
|
PluralName: "registered_models",
|
|
SingularTitle: "Registered Model",
|
|
PluralTitle: "Registered Models",
|
|
},
|
|
"quality_monitors": {
|
|
SingularName: "quality_monitor",
|
|
PluralName: "quality_monitors",
|
|
SingularTitle: "Quality Monitor",
|
|
PluralTitle: "Quality Monitors",
|
|
},
|
|
"schemas": {
|
|
SingularName: "schema",
|
|
PluralName: "schemas",
|
|
SingularTitle: "Schema",
|
|
PluralTitle: "Schemas",
|
|
},
|
|
"clusters": {
|
|
SingularName: "cluster",
|
|
PluralName: "clusters",
|
|
SingularTitle: "Cluster",
|
|
PluralTitle: "Clusters",
|
|
},
|
|
"dashboards": {
|
|
SingularName: "dashboard",
|
|
PluralName: "dashboards",
|
|
SingularTitle: "Dashboard",
|
|
PluralTitle: "Dashboards",
|
|
},
|
|
"volumes": {
|
|
SingularName: "volume",
|
|
PluralName: "volumes",
|
|
SingularTitle: "Volume",
|
|
PluralTitle: "Volumes",
|
|
},
|
|
"apps": {
|
|
SingularName: "app",
|
|
PluralName: "apps",
|
|
SingularTitle: "App",
|
|
PluralTitle: "Apps",
|
|
},
|
|
}
|
|
}
|