Skip to content

Commit

Permalink
move ClusterResourceSets
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Jul 7, 2020
1 parent e68354f commit 9040843
Show file tree
Hide file tree
Showing 6 changed files with 574 additions and 7 deletions.
4 changes: 2 additions & 2 deletions cmd/clusterctl/client/cluster/mover.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ func getMoveSequence(graph *objectGraph) *moveSequence {
// NB. it is necessary to filter out nodes not belonging to a cluster because e.g. discovery reads all the secrets,
// but only few of them are related to Clusters/Machines etc.
moveGroup := moveGroup{}
for _, n := range graph.getNodesWithClusterTenants() {
for _, n := range graph.getNodesWithTenants() {
// If the node was already included in the moveSequence, skip it.
if moveSequence.hasNode(n) {
continue
Expand Down Expand Up @@ -360,7 +360,7 @@ func patchCluster(proxy Proxy, cluster *node, patch client.Patch) error {
func (o *objectMover) ensureNamespaces(graph *objectGraph, toProxy Proxy) error {
ensureNamespaceBackoff := newWriteBackoff()
namespaces := sets.NewString()
for _, node := range graph.getNodesWithClusterTenants() {
for _, node := range graph.getNodesWithTenants() {
namespace := node.identity.Namespace

// If the namespace was already processed, skip it.
Expand Down
36 changes: 36 additions & 0 deletions cmd/clusterctl/client/cluster/mover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,42 @@ var moveTests = []struct {
},
},
},
{
name: "A ClusterResourceSet applied to a cluster",
fields: moveTestsFields{
objs: func() []runtime.Object {
objs := []runtime.Object{}
objs = append(objs, test.NewFakeCluster("ns1", "cluster1").Objs()...)

objs = append(objs, test.NewFakeClusterResourceSet("ns1", "crs1").
WithSecret("resource-s1").
WithConfigMap("resource-c1").
ApplyToCluster(test.SelectClusterObj(objs, "ns1", "cluster1")).
Objs()...)

return objs
}(),
},
wantMoveGroups: [][]string{
{ //group 1
// Cluster
"cluster.x-k8s.io/v1alpha3, Kind=Cluster, ns1/cluster1",
// ClusterResourceSet
"addons.cluster.x-k8s.io/v1alpha3, Kind=ClusterResourceSet, ns1/crs1",
},
{ //group 2 (objects with ownerReferences in group 1)
// owned by Clusters
"/v1, Kind=Secret, ns1/cluster1-ca",
"/v1, Kind=Secret, ns1/cluster1-kubeconfig",
"infrastructure.cluster.x-k8s.io/v1alpha3, Kind=GenericInfrastructureCluster, ns1/cluster1",
// owned by ClusterResourceSet
"/v1, Kind=Secret, ns1/resource-s1",
"/v1, Kind=ConfigMap, ns1/resource-c1",
// owned by ClusterResourceSet & Cluster
"addons.cluster.x-k8s.io/v1alpha3, Kind=ClusterResourceSetBinding, ns1/crs1",
},
},
},
}

func Test_getMoveSequence(t *testing.T) {
Expand Down
46 changes: 42 additions & 4 deletions cmd/clusterctl/client/cluster/objectgraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
logf "sigs.k8s.io/cluster-api/cmd/clusterctl/log"
addonsv1alpha3 "sigs.k8s.io/cluster-api/exp/addons/api/v1alpha3"
secretutil "sigs.k8s.io/cluster-api/util/secret"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -58,6 +59,10 @@ type node struct {
// tenantClusters define the list of Clusters which are tenant for the node, no matter if the node has a direct OwnerReference to the Cluster or if
// the node is linked to a Cluster indirectly in the OwnerReference chain.
tenantClusters map[*node]empty

// tenantCRSs define the list of ClusterResourceSet which are tenant for the node, no matter if the node has a direct OwnerReference to the Cluster or if
// the node is linked to a ClusterResourceSet indirectly in the OwnerReference chain.
tenantCRSs map[*node]empty
}

// markObserved marks the fact that a node was observed as a concrete object.
Expand Down Expand Up @@ -130,6 +135,7 @@ func (o *objectGraph) ownerToVirtualNode(owner metav1.OwnerReference, namespace
owners: make(map[*node]ownerReferenceAttributes),
softOwners: make(map[*node]empty),
tenantClusters: make(map[*node]empty),
tenantCRSs: make(map[*node]empty),
virtual: true,
}

Expand Down Expand Up @@ -158,6 +164,7 @@ func (o *objectGraph) objToNode(obj *unstructured.Unstructured) *node {
owners: make(map[*node]ownerReferenceAttributes),
softOwners: make(map[*node]empty),
tenantClusters: make(map[*node]empty),
tenantCRSs: make(map[*node]empty),
virtual: false,
}

Expand Down Expand Up @@ -254,6 +261,9 @@ func (o *objectGraph) Discovery(namespace string, types []metav1.TypeMeta) error
// Completes the graph by setting for each node the list of Clusters the node belong to.
o.setClusterTenants()

// Completes the graph by setting for each node the list of ClusterResourceSet the node belong to.
o.setCRSTenants()

return nil
}

Expand Down Expand Up @@ -306,11 +316,22 @@ func (o *objectGraph) getNodes() []*node {
return nodes
}

// getNodesWithClusterTenants returns the list of nodes existing in the object graph that belong at least to one Cluster.
func (o *objectGraph) getNodesWithClusterTenants() []*node {
// getCRSs returns the list of ClusterResourceSet existing in the object graph.
func (o *objectGraph) getCRSs() []*node {
clusters := []*node{}
for _, node := range o.uidToNode {
if node.identity.GroupVersionKind().GroupKind() == addonsv1alpha3.GroupVersion.WithKind("ClusterResourceSet").GroupKind() {
clusters = append(clusters, node)
}
}
return clusters
}

// getNodesWithTenants returns the list of nodes existing in the object graph that belong at least to one Cluster or to a ClusterResourceSet.
func (o *objectGraph) getNodesWithTenants() []*node {
nodes := []*node{}
for _, node := range o.uidToNode {
if len(node.tenantClusters) > 0 {
if len(node.tenantClusters) > 0 || len(node.tenantCRSs) > 0 {
nodes = append(nodes, node)
}
}
Expand Down Expand Up @@ -360,7 +381,7 @@ func (o *objectGraph) setClusterTenants() {
}
}

// setNodeTenant sets a tenant for a node and for its own dependents/sofDependents.
// setNodeTenant sets a cluster tenant for a node and for its own dependents/sofDependents.
func (o *objectGraph) setClusterTenant(node, tenant *node) {
node.tenantClusters[tenant] = empty{}
for _, other := range o.getNodes() {
Expand All @@ -369,3 +390,20 @@ func (o *objectGraph) setClusterTenant(node, tenant *node) {
}
}
}

// setClusterTenants sets the cluster tenants for the clusters itself and all their dependent object tree.
func (o *objectGraph) setCRSTenants() {
for _, crs := range o.getCRSs() {
o.setCRSTenant(crs, crs)
}
}

// setCRSTenant sets a ClusterResourceSet tenant for a node and for its own dependents/sofDependents.
func (o *objectGraph) setCRSTenant(node, tenant *node) {
node.tenantCRSs[tenant] = empty{}
for _, other := range o.getNodes() {
if other.isOwnedBy(node) {
o.setCRSTenant(other, tenant)
}
}
}
Loading

0 comments on commit 9040843

Please sign in to comment.