Validate clustermap parent-child dependancy
Add ValidateClusterMap() method to confirm there are no parent-child dependancy issues for any clustermaps. Closes: #481 Change-Id: Ifb57b026933909a4350d71353adca23a42440a48
This commit is contained in:
parent
e2e8732fed
commit
edb2aae971
@ -39,3 +39,13 @@ type ErrClusterNotInMap struct {
|
|||||||
func (e ErrClusterNotInMap) Error() string {
|
func (e ErrClusterNotInMap) Error() string {
|
||||||
return fmt.Sprintf("cluster '%s' is not defined in cluster map %v", e.Child, e.Map)
|
return fmt.Sprintf("cluster '%s' is not defined in cluster map %v", e.Child, e.Map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrClusterCircularDependency returned for circular dependencies
|
||||||
|
type ErrClusterCircularDependency struct {
|
||||||
|
Parent string
|
||||||
|
Map *v1alpha1.ClusterMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrClusterCircularDependency) Error() string {
|
||||||
|
return fmt.Sprintf("%v contains cluster referenced as both parent and child: %s", e.Map, e.Parent)
|
||||||
|
}
|
||||||
|
@ -36,6 +36,7 @@ type WriteOptions struct {
|
|||||||
// TODO use typed cluster names
|
// TODO use typed cluster names
|
||||||
type ClusterMap interface {
|
type ClusterMap interface {
|
||||||
ParentCluster(string) (string, error)
|
ParentCluster(string) (string, error)
|
||||||
|
ValidateClusterMap() error
|
||||||
AllClusters() []string
|
AllClusters() []string
|
||||||
ClusterKubeconfigContext(string) (string, error)
|
ClusterKubeconfigContext(string) (string, error)
|
||||||
Sources(string) ([]v1alpha1.KubeconfigSource, error)
|
Sources(string) ([]v1alpha1.KubeconfigSource, error)
|
||||||
@ -66,6 +67,33 @@ func (cm clusterMap) ParentCluster(child string) (string, error) {
|
|||||||
return currentCluster.Parent, nil
|
return currentCluster.Parent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validates a clustermap has valid parent-child map structure
|
||||||
|
func (cm clusterMap) ValidateClusterMap() error {
|
||||||
|
clusterMap := cm.AllClusters()
|
||||||
|
for _, childCluster := range clusterMap {
|
||||||
|
var parentClusters []string
|
||||||
|
var currentChild string = childCluster
|
||||||
|
for {
|
||||||
|
currentCluster, _ := cm.apiMap.Map[currentChild]
|
||||||
|
for _, c := range parentClusters {
|
||||||
|
if c == currentCluster.Parent {
|
||||||
|
// Quit on parent whos also child
|
||||||
|
return ErrClusterCircularDependency{Parent: childCluster, Map: cm.apiMap}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Quit loop once top level of current cluster is reached
|
||||||
|
if currentCluster.Parent == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
parentClusters = append(parentClusters, currentCluster.Parent)
|
||||||
|
currentChild = currentCluster.Parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return success if there are no conflicts
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AllClusters returns all clusters in a map
|
// AllClusters returns all clusters in a map
|
||||||
func (cm clusterMap) AllClusters() []string {
|
func (cm clusterMap) AllClusters() []string {
|
||||||
clusters := []string{}
|
clusters := []string{}
|
||||||
|
@ -97,6 +97,27 @@ func TestClusterMap(t *testing.T) {
|
|||||||
assert.Equal(t, "", parent)
|
assert.Equal(t, "", parent)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Validate Circular Clustermap", func(t *testing.T) {
|
||||||
|
// Create new map with circular dependency
|
||||||
|
circularAPIMap := &v1alpha1.ClusterMap{
|
||||||
|
Map: map[string]*v1alpha1.Cluster{},
|
||||||
|
}
|
||||||
|
for key, value := range apiMap.Map {
|
||||||
|
newValue := *value
|
||||||
|
circularAPIMap.Map[key] = &newValue
|
||||||
|
}
|
||||||
|
circularAPIMap.Map["ephemeral"].Parent = "workload"
|
||||||
|
cMapCircular := clustermap.NewClusterMap(circularAPIMap)
|
||||||
|
err := cMapCircular.ValidateClusterMap()
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Validate all Clustermaps", func(t *testing.T) {
|
||||||
|
// Check child clusterID against map of parent clusterID map
|
||||||
|
err := cMap.ValidateClusterMap()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("all clusters", func(t *testing.T) {
|
t.Run("all clusters", func(t *testing.T) {
|
||||||
clusters := cMap.AllClusters()
|
clusters := cMap.AllClusters()
|
||||||
assert.Len(t, clusters, 4)
|
assert.Len(t, clusters, 4)
|
||||||
|
Loading…
Reference in New Issue
Block a user