Skip to content
This repository was archived by the owner on Jan 24, 2026. It is now read-only.

fix: delete plugin namespace after removing it#39

Merged
mrgb7 merged 8 commits into
mrgb7:mainfrom
nmn3m:fix/plugin-namespace-uninstall
May 31, 2025
Merged

fix: delete plugin namespace after removing it#39
mrgb7 merged 8 commits into
mrgb7:mainfrom
nmn3m:fix/plugin-namespace-uninstall

Conversation

@nmn3m

@nmn3m nmn3m commented May 29, 2025

Copy link
Copy Markdown
Contributor

Fix

  • Added cleanup logic to ensure the namespace created by a plugin is properly removed upon its uninstallation.

Impact

- Prevents accumulation of unused namespaces.
- Keeps the playground environment clean and consistent.
- No changes to plugin behavior or isolation guarantees.

Comment thread cmd/cluster/plugin/remove.go Outdated
},
}

func deleteNamespace(kubeConfigData, namespace string) error {

@mrgb7 mrgb7 May 30, 2025

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include the namespace deletion as part of the plugin installation process. This helps maintain abstraction by keeping operational commands decoupled from the core logic, ensuring clearer separation of concerns.
e.g. in ArgoCD installer or helm installer you can set cleanup of the namespace.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look into architecture docs here

@nmn3m nmn3m May 30, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it,
but do you mean plugin uninstallation process not installation process?

what i will do.

  • Move namespace cleanup logic from the command layer (remove.go) to the installer layer.
  • Create a shared cleanup Namespace utility function in the installer package to handle namespace deletion.
  • Add namespace cleanup as part of the UnInstall method in both Helm and ArgoCD installers.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep uninstall. When I said installation process I meant the layer sorry for confusion. Let me know if you need any help in architecture

@mrgb7 mrgb7 May 30, 2025

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmn3m First, investigate why the uninstall function in the Helm and ArgoCD installers does not clean up the namespace. Look into whether there are flags or options available in Helm and ArgoCD to ensure proper cleanup. Keep in mind that not all plugins are responsible for creating namespaces some are intended solely to update or override the configuration of other plugins.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, Got it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Uninstall Behavior & Namespace Ownership

Findings

  • Helm

    • helm uninstall only removes release-managed resources.
    • --namespace is used for lookup; does not trigger deletion.
    • No built-in support for namespace cleanup.
  • ArgoCD

    • Application deletion removes only managed resources.
    • Destination namespace is specified but not managed.

Issues

  • No tracking or handling of namespace ownership.
  • Plugin types vary:
    • Some create and own namespaces (e.g., ArgoCD, Cert-Manager).
    • Some reuse existing namespaces (e.g., Ingress controllers, TLS).
    • Some modify other namespaces.

Changes

  • Introduced a mechanism to identify if a plugin owns its namespace.
  • Namespace deletion is now conditional based on plugin type.
  • Clear separation between resource cleanup and namespace management logic.

🛠️ Code Improvements

  • Applied interface segregation to break import cycles instead of creating a new package.

🐛 Bug Fix: ArgoCD Uninstall Error

  • Fixed HTTP 415 - Invalid content type during ArgoCD app deletion.
  • Solution: Set proper header in argo.go:
    req.Header.Set("Content-Type", "application/json")

Comment thread internal/installer/namespace.go Outdated
@@ -0,0 +1,57 @@
package installer

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The installer package includes the installers which implement installer interface, however here you added a utility. so it should be in different package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got your point,
Do you have a problem if i add this utility inside k8s package as i see, i will fit there with client.go

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you can define a new function in the abstracted K8s client called DeleteNamespace

Comment thread internal/installer/namespace.go Outdated
return fmt.Errorf("failed to delete namespace %s: %w", namespace, err)
}

for {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no infinite stop here it will re-try for ever which is consuming the resources. also keep into account race condition between installer deleting the resource in background and deleting the namespace itself

Comment thread internal/plugins/base.go Outdated
}

// Default implementation - plugins can override if needed
func (b *BasePlugin) OwnsNamespace() bool {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need this as the plugin has a string namespace field so you check if it is empty

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugin Namespace Lifecycle Design

This design provides a clean and flexible way to handle plugin lifecycles:

  • Plugins that own their namespace (e.g., ArgoCD, Nginx, LoadBalancer)
    → Can safely delete the entire namespace during uninstallation.

  • Plugins that share a namespace (e.g., TLS sharing the cert-manager namespace)
    → Will leave the namespace intact during uninstallation to avoid disrupting other components.

  • Separation of concerns between:

    • GetNamespace() — Defines where the plugin runs.
    • OwnsNamespace() — Defines whether the plugin has exclusive control over that namespace.

This distinction is especially critical for shared environments, where deleting a shared namespace could unintentionally break other plugins or system components relying on it.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Namespaces are not shared by design each plugin either defines its own namespace or operates without one. keep it simple

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

Comment thread internal/plugins/base.go Outdated
Version: version,
KubeConfig: kubeConfig,
RepoName: plugin.GetRepoName(),
Plugin: plugin,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this field never used ?

Comment thread internal/installer/installer.go Outdated
@@ -1,5 +1,15 @@
package installer

type PluginInterface interface {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain more why we need this interface inside the installer interface under installer package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget to remove it, I was using it to solve Applied interface segregation to break import cycles instead of creating a new package

@mrgb7 mrgb7 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution 🚀

@mrgb7
mrgb7 merged commit 6dbd278 into mrgb7:main May 31, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants