Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup finalizers for all namespace resources #421

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pluralsh/controller-reconcile-helper v0.0.4 h1:1o+7qYSyoeqKFjx+WgQTxDz4Q2VMpzprJIIKShxqG0E=
github.com/pluralsh/controller-reconcile-helper v0.0.4/go.mod h1:AfY0gtteD6veBjmB6jiRx/aR4yevEf6K0M13/pGan/s=
github.com/pluralsh/gqlclient v1.3.17 h1:hD/rG+lhxP3kN1UUXrzZd2uN7P76MvNTEJEzYOpERXo=
github.com/pluralsh/gqlclient v1.3.17/go.mod h1:z1qHnvPeqIN/a+5OzFs40e6HI6tDxzh1+yJuEpvqGy4=
github.com/pluralsh/gqlclient v1.3.18 h1:SthOBnlEgXh1bAKQXrZDNZRekaw3zDku4I4xgVsumDE=
github.com/pluralsh/gqlclient v1.3.18/go.mod h1:z1qHnvPeqIN/a+5OzFs40e6HI6tDxzh1+yJuEpvqGy4=
github.com/pluralsh/oauth v0.9.2 h1:tM9hBK4tCnJUeCOgX0ctxBBCS3hiCDPoxkJLODtedmQ=
Expand Down
95 changes: 90 additions & 5 deletions pkg/kubernetes/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import (
"github.com/pluralsh/plural/pkg/application"
"github.com/pluralsh/plural/pkg/utils"
"github.com/pluralsh/plural/pkg/utils/pathing"
"github.com/pluralsh/polly/containers"
v1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -151,17 +153,100 @@ func (k *kube) Nodes() (*v1.NodeList, error) {
return k.Kube.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
}

type GroupResource struct {
Name string
APIGroup string
APIResource metav1.APIResource
GroupVersion schema.GroupVersion
}

func (k *kube) FinalizeNamespace(namespace string) error {
ctx := context.Background()
client := k.Kube.CoreV1().Namespaces()
ns, err := client.Get(ctx, namespace, metav1.GetOptions{})

if err := k.cleanupFinalizersForAllNamespaceResources(ctx, namespace); err != nil {
return err
}

return nil
}

func (k *kube) cleanupFinalizersForAllNamespaceResources(ctx context.Context, namespace string) error {
resources, err := k.getResourceTypes()
if err != nil {
return err
}
for _, res := range resources {
gvr := schema.GroupVersionResource{
Group: res.APIGroup,
Version: res.GroupVersion.Version,
Resource: res.APIResource.Name,
}
objList, err := k.Dynamic.Resource(gvr).Namespace(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}

for _, item := range objList.Items {
if len(item.GetFinalizers()) > 0 {
utils.LogInfo().Println("found finalizers for resource ", item.GetKind(), item.GetName())
item.SetFinalizers([]string{})
_, err = k.Dynamic.Resource(gvr).Namespace(item.GetNamespace()).Update(ctx, &item, metav1.UpdateOptions{})
if err != nil {
if !k8serrors.IsNotFound(err) {
return err
}
}
}
}
}
return nil
}

func (k *kube) getResourceTypes() ([]GroupResource, error) {
discoveryClient := memory.NewMemCacheClient(k.Discovery)
discoveryClient.Invalidate()
lists, err := discoveryClient.ServerPreferredResources()
if err != nil {
return nil, err
}
var resources []GroupResource
resources = make([]GroupResource, 0)
for _, list := range lists {
if len(list.APIResources) == 0 {
continue
}
gv, err := schema.ParseGroupVersion(list.GroupVersion)
if err != nil {
continue
}
for _, resource := range list.APIResources {
if len(resource.Verbs) == 0 {
continue
}
verbs := containers.ToSet[string](resource.Verbs)
if !verbs.Has("get") || !verbs.Has("update") {
continue
}

// filter namespaced
if !resource.Namespaced {
continue
}

ns.Spec.Finalizers = []v1.FinalizerName{}
_, err = client.Finalize(ctx, ns, metav1.UpdateOptions{})
return err
name := resource.Name
if len(gv.Group) > 0 {
name += "." + gv.Group
}

resources = append(resources, GroupResource{
Name: name,
APIGroup: gv.Group,
APIResource: resource,
GroupVersion: gv,
})
}
}
return resources, nil
}

func (k *kube) LogTailList(namespace string) (*platformv1alpha1.LogTailList, error) {
Expand Down