Fix: removing detached clusters from resource trackers (#6728)

* removing detached clusters from resource trackers

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* resolve merge conflicts

Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* resolved code conflicts

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update TestGetAddonStatus test case

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>

---------

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Shivin Gopalani <sgopalani@guidewire.com>
Co-authored-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
This commit is contained in:
shivin
2025-03-19 07:35:06 +08:00
committed by GitHub
co-authored by Shivin Gopalani Pushparaj Shetty K S
parent e0f162e47d
commit c5d9f69c9c
3 changed files with 47 additions and 2 deletions
+6 -1
View File
@@ -378,7 +378,8 @@ func TestGetAddonStatus(t *testing.T) {
})
cli := test.MockClient{
MockGet: getFunc,
MockGet: getFunc,
MockList: listFunc,
}
cases := []struct {
@@ -410,6 +411,10 @@ func TestGetAddonStatus(t *testing.T) {
}
}
func listFunc(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
return nil
}
func TestGetAddonVersionMeetSystemRequirement(t *testing.T) {
server := httptest.NewServer(helmHandler)
defer server.Close()
+13 -1
View File
@@ -123,6 +123,14 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
// GetAddonStatus is general func for cli and apiServer get addon status
func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status, error) {
var addonStatus Status
joinedClusters, err := multicluster.NewClusterClient(cli).List(ctx)
if err != nil {
return addonStatus, errors.Wrap(err, "failed to list registered clusters")
}
var joinedClusterMap = make(map[string]bool)
for _, joinedCluster := range joinedClusters.Items {
joinedClusterMap[joinedCluster.Name] = true
}
app, err := FetchAddonRelatedApp(ctx, cli, name)
if err != nil {
@@ -143,8 +151,12 @@ func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status
r.Cluster = multicluster.ClusterLocalName
}
// TODO(wonderflow): we should collect all the necessary information as observability, currently we only collect cluster name
clusters[r.Cluster] = make(map[string]interface{})
// If cluster is not registered in KubeVela then skip it.
if joinedClusterMap[r.Cluster] {
clusters[r.Cluster] = make(map[string]interface{})
}
}
addonStatus.Clusters = clusters
if app.Status.Workflow != nil && app.Status.Workflow.Suspend {
+28
View File
@@ -44,6 +44,7 @@ import (
ocmclusterv1 "open-cluster-management.io/api/cluster/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/utils"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
@@ -486,6 +487,9 @@ func (op DetachClusterManagedClusterKubeConfigPathOption) ApplyToArgs(args *Deta
// DetachCluster detach cluster by name, if cluster is using by application, it will return error
func DetachCluster(ctx context.Context, cli client.Client, clusterName string, options ...DetachClusterOption) error {
if err := removeClusterFromResourceTrackers(ctx, cli, clusterName); err != nil {
return fmt.Errorf("error in removing cluster references from resourcetrackers: %w", err)
}
args := newDetachClusterArgs(options...)
if clusterName == ClusterLocalName {
return ErrReservedLocalClusterName
@@ -612,6 +616,30 @@ func getMutableClusterSecret(ctx context.Context, c client.Client, clusterName s
return clusterSecret, nil
}
// removeClusterFromResourceTrackers removes cluster references from all resource trackers.
func removeClusterFromResourceTrackers(ctx context.Context, cli client.Client, clusterName string) error {
rts := v1beta1.ResourceTrackerList{}
if err := cli.List(ctx, &rts); err != nil {
return fmt.Errorf("unable to list resourcetrackers due to error: %w", err)
}
for i := range rts.Items {
managedResources := rts.Items[i].Spec.ManagedResources
var result []v1beta1.ManagedResource
for _, mr := range managedResources {
if mr.ClusterObjectReference.Cluster != clusterName {
result = append(result, mr)
}
}
if len(rts.Items[i].Spec.ManagedResources) != len(result) {
rts.Items[i].Spec.ManagedResources = result
if err := cli.Update(ctx, &rts.Items[i]); err != nil {
return fmt.Errorf("error in updating resourcetracker %s: %w", rts.Items[i].Name, err)
}
}
}
return nil
}
func getTokenFromExec(execConfig *clientcmdapi.ExecConfig) (string, error) {
// #nosec G204 -- This is intentionally running an exec command with user-provided input
// The execConfig comes from the kubeconfig which should be trusted in this context