mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 05:12:31 +08:00
75 lines
2.8 KiB
Go
75 lines
2.8 KiB
Go
package cloudmigration
|
|
|
|
import (
|
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
|
)
|
|
|
|
var (
|
|
ErrDuplicateResourceType = errutil.BadRequest("cloudmigrations.duplicateResourceType")
|
|
ErrUnknownResourceType = errutil.BadRequest("cloudmigrations.unknownResourceType")
|
|
ErrMissingDependency = errutil.BadRequest("cloudmigrations.missingDependency")
|
|
)
|
|
|
|
// DependencyMap is a map of resource types to their direct dependencies.
|
|
type DependencyMap map[MigrateDataType][]MigrateDataType
|
|
|
|
// ResourceDependency is a map of resource types to their direct dependencies.
|
|
// This is used to determine which resources can be filtered out from the snapshot without breaking the dependency chain.
|
|
var ResourceDependency = DependencyMap{
|
|
PluginDataType: nil,
|
|
FolderDataType: nil,
|
|
DatasourceDataType: {PluginDataType},
|
|
LibraryElementDataType: {FolderDataType},
|
|
DashboardDataType: {FolderDataType, DatasourceDataType, LibraryElementDataType},
|
|
MuteTimingType: nil,
|
|
NotificationTemplateType: nil,
|
|
ContactPointType: {NotificationTemplateType},
|
|
NotificationPolicyType: {ContactPointType, MuteTimingType},
|
|
AlertRuleType: {DatasourceDataType, FolderDataType, DashboardDataType, MuteTimingType, ContactPointType, NotificationPolicyType},
|
|
AlertRuleGroupType: {AlertRuleType},
|
|
}
|
|
|
|
// Parse a raw slice of resource types and returns a set of them if it has all correct dependencies.
|
|
func (depMap DependencyMap) Parse(rawInput []MigrateDataType) (ResourceTypes, error) {
|
|
// Clean up any possible duplicates.
|
|
input := make(ResourceTypes, len(rawInput))
|
|
for _, resourceType := range rawInput {
|
|
if _, exists := input[resourceType]; exists {
|
|
return nil, ErrDuplicateResourceType.Errorf("duplicate resource type found: %v", resourceType)
|
|
}
|
|
input[resourceType] = struct{}{}
|
|
}
|
|
|
|
// Validate that all dependencies are present.
|
|
for resourceType := range input {
|
|
if err := depMap.validateDependencies(resourceType, input); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return input, nil
|
|
}
|
|
|
|
// validateDependencies recursively checks if all dependencies for a resource type are present in the input set.
|
|
func (depMap DependencyMap) validateDependencies(resourceType MigrateDataType, input ResourceTypes) error {
|
|
// Get the direct dependencies for this resource type.
|
|
dependencies, ok := depMap[resourceType]
|
|
if !ok {
|
|
return ErrUnknownResourceType.Errorf("unknown resource type: %v", resourceType)
|
|
}
|
|
|
|
// Make sure all direct dependencies are in the input.
|
|
for _, dep := range dependencies {
|
|
if _, exists := input[dep]; !exists {
|
|
return ErrMissingDependency.Errorf("missing dependency: %v for resource type %v", dep, resourceType)
|
|
}
|
|
|
|
// Recursively validate dependencies of dependencies
|
|
if err := depMap.validateDependencies(dep, input); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|