-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add operations for helm #17
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,9 @@ This extension enables declarative Kubernetes interactions within mcpchecker tas | |
| | `kubernetes.create` | Create a Kubernetes resource | | ||
| | `kubernetes.delete` | Delete a Kubernetes resource | | ||
| | `kubernetes.getCurrentContext` | Get the current context from kubeconfig | | ||
| | `kubernetes.helmInstall` | Install a Helm chart as a release | | ||
| | `kubernetes.helmList` | List Helm releases in a namespace or all namespaces | | ||
| | `kubernetes.helmUninstall` | Uninstall a Helm release | | ||
| | `kubernetes.listContexts` | List all contexts from kubeconfig | | ||
| | `kubernetes.viewConfig` | View kubeconfig as YAML (optionally minified) | | ||
| | `kubernetes.wait` | Wait for a condition on a resource (e.g., `Ready`, `Available`) | | ||
|
|
@@ -87,6 +90,52 @@ spec: | |
| inline: Create an nginx pod named web-server in the test-namespace namespace | ||
| ``` | ||
|
|
||
| ### Helm Example | ||
|
|
||
| Test Helm operations using declarative setup and cleanup: | ||
|
|
||
| ```yaml | ||
| kind: Task | ||
| apiVersion: gevals/v1alpha2 | ||
| metadata: | ||
| name: "list-helm-releases" | ||
| difficulty: easy | ||
| spec: | ||
| requires: | ||
| - extension: kubernetes | ||
|
|
||
| setup: | ||
| # Create namespace | ||
| - kubernetes.create: | ||
| apiVersion: v1 | ||
| kind: Namespace | ||
| metadata: | ||
| name: helm-test | ||
|
|
||
| # Install a test release | ||
| - kubernetes.helmInstall: | ||
| chart: oci://registry-1.docker.io/bitnamicharts/nginx | ||
| name: test-nginx | ||
| namespace: helm-test | ||
|
|
||
| cleanup: | ||
| # Uninstall the release | ||
| - kubernetes.helmUninstall: | ||
| name: test-nginx | ||
| namespace: helm-test | ||
|
|
||
| # Delete namespace | ||
| - kubernetes.delete: | ||
| apiVersion: v1 | ||
| kind: Namespace | ||
| metadata: | ||
| name: helm-test | ||
| ignoreNotFound: true | ||
|
|
||
| prompt: | ||
| inline: List all Helm releases in the cluster | ||
| ``` | ||
|
|
||
| ## Operation Reference | ||
|
|
||
| ### kubernetes.create | ||
|
|
@@ -135,6 +184,48 @@ Waits for a condition on a resource. Supports configurable timeout and expected | |
| timeout: 5m # optional, defaults to 60s | ||
| ``` | ||
|
|
||
| ### kubernetes.helmInstall | ||
|
|
||
| Installs a Helm chart as a release. Supports chart repositories and OCI registries. | ||
|
|
||
| ```yaml | ||
| - kubernetes.helmInstall: | ||
| chart: oci://registry-1.docker.io/bitnamicharts/nginx | ||
| name: my-nginx # optional, generates name if not provided | ||
| namespace: default # optional | ||
| values: # optional Helm values | ||
| replicaCount: 2 | ||
| service: | ||
| type: LoadBalancer | ||
| ``` | ||
|
|
||
| ### kubernetes.helmList | ||
|
|
||
| Lists Helm releases in a namespace or across all namespaces. | ||
|
|
||
| ```yaml | ||
| # List in specific namespace | ||
| - kubernetes.helmList: | ||
| namespace: default | ||
|
|
||
| # List across all namespaces | ||
| - kubernetes.helmList: | ||
| allNamespaces: true | ||
| ``` | ||
|
|
||
| **Outputs:** | ||
| - `releases`: Information about found Helm releases (name, namespace, status, chart) | ||
|
Comment on lines
+216
to
+217
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation inconsistency: The documentation states that Either update the documentation to reflect the actual string output, or modify the implementation to return structured release data. 🤖 Prompt for AI Agents |
||
|
|
||
| ### kubernetes.helmUninstall | ||
|
|
||
| Uninstalls a Helm release. Gracefully handles releases that don't exist. | ||
|
|
||
| ```yaml | ||
| - kubernetes.helmUninstall: | ||
| name: my-nginx | ||
| namespace: default # optional | ||
| ``` | ||
|
|
||
| ### kubernetes.listContexts | ||
|
|
||
| Lists all contexts from the kubeconfig file, including which one is currently active. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,189 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package extension | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os/exec" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/mcpchecker/mcpchecker/pkg/extension/sdk" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // handleHelmInstall installs a Helm chart as a release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (e *Extension) handleHelmInstall(ctx context.Context, req *sdk.OperationRequest) (*sdk.OperationResult, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args, ok := req.Args.(map[string]any) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("args must be an object")), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chart, ok := args["chart"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok || chart == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("chart parameter is required")), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Optional parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name, _ := args["name"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace, _ := args["namespace"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| values, _ := args["values"].(map[string]interface{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs := []string{"install"} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if name != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--generate-name") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, chart) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if namespace != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--namespace", namespace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+32
to
+43
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here let's also set the We don't currently expose the path to that file through the client, but it should be simple to add something around here: kubernetes-extension/pkg/extension/client.go Lines 18 to 51 in 194d786
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if e.kubeconfigPath != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--kubeconfig", e.kubeconfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Add values as --set flags | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for k, v := range values { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--set", fmt.Sprintf("%s=%v", k, v)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+48
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Command injection risk and limited values support. Two concerns with the
Consider using a temporary values file with Sketch: Flatten nested valuesfunc flattenValues(prefix string, values map[string]interface{}, result map[string]string) {
for k, v := range values {
key := k
if prefix != "" {
key = prefix + "." + k
}
switch val := v.(type) {
case map[string]interface{}:
flattenValues(key, val, result)
default:
result[key] = fmt.Sprintf("%v", val)
}
}
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Installing Helm chart", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "chart": chart, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "namespace": namespace, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmd := exec.CommandContext(ctx, "helm", cmdArgs...) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output, err := cmd.CombinedOutput() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogError(ctx, "Helm install failed", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "chart": chart, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "error": err.Error(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("helm install failed: %s\nOutput: %s", err, string(output))), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Helm chart installed successfully", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "chart": chart, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Success(fmt.Sprintf("Helm chart installed successfully\n%s", string(output))), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // handleHelmList lists Helm releases | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (e *Extension) handleHelmList(ctx context.Context, req *sdk.OperationRequest) (*sdk.OperationResult, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args, ok := req.Args.(map[string]any) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("args must be an object")), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs := []string{"list", "--output", "json"} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace, _ := args["namespace"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allNamespaces, _ := args["allNamespaces"].(bool) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if allNamespaces { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--all-namespaces") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if namespace != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--namespace", namespace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if e.kubeconfigPath != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--kubeconfig", e.kubeconfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Listing Helm releases", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "namespace": namespace, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "allNamespaces": allNamespaces, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmd := exec.CommandContext(ctx, "helm", cmdArgs...) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output, err := cmd.CombinedOutput() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogError(ctx, "Helm list failed", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "error": err.Error(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("helm list failed: %s\nOutput: %s", err, string(output))), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Parse JSON output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var releases []map[string]interface{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(output) > 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := json.Unmarshal(output, &releases); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("failed to parse helm list output: %s", err)), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(releases) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Success("No Helm releases found"), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Format releases as a readable string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var result strings.Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.WriteString(fmt.Sprintf("Found %d Helm release(s):\n", len(releases))) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, release := range releases { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name, _ := release["name"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ns, _ := release["namespace"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status, _ := release["status"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chart, _ := release["chart"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.WriteString(fmt.Sprintf(" - %s (namespace: %s, status: %s, chart: %s)\n", name, ns, status, chart)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Success(result.String()), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // handleHelmUninstall uninstalls a Helm release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (e *Extension) handleHelmUninstall(ctx context.Context, req *sdk.OperationRequest) (*sdk.OperationResult, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args, ok := req.Args.(map[string]any) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("args must be an object")), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name, ok := args["name"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok || name == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("name parameter is required")), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs := []string{"uninstall", name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace, _ := args["namespace"].(string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if namespace != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--namespace", namespace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if e.kubeconfigPath != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmdArgs = append(cmdArgs, "--kubeconfig", e.kubeconfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Uninstalling Helm release", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "namespace": namespace, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cmd := exec.CommandContext(ctx, "helm", cmdArgs...) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output, err := cmd.CombinedOutput() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check if it's a "not found" error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if strings.Contains(string(output), "not found") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Helm release not found (ignored)", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Success(fmt.Sprintf("Helm release '%s' not found (already uninstalled)", name)), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogError(ctx, "Helm uninstall failed", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "error": err.Error(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Failure(fmt.Errorf("helm uninstall failed: %s\nOutput: %s", err, string(output))), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.LogInfo(ctx, "Helm release uninstalled successfully", map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return sdk.Success(fmt.Sprintf("Helm release '%s' uninstalled successfully\n%s", name, string(output))), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
latest stable version of Helm 2025 2026💡 Result:
As of February 9, 2026, the latest stable Helm releases are:
(Helm v4 was officially announced/released on November 12, 2025.) [3]
Sources:
[1] (github.com)
[2] (github.com)
[3] (cncf.io)
Citations:
🏁 Script executed:
Repository: mcpchecker/kubernetes-extension
Length of output: 653
🌐 Web query:
azure/setup-helm action latest version v4 v5💡 Result:
azure/setup-helmrelease/tag:v4.3.1(github.com)azure/setup-helm@v4to track the latest v4.x). (github.com)v5release/tag in the upstream repo releases. (github.com)Citations:
Pin Helm to a specific version for reproducible CI builds.
Using
version: 'latest'introduces non-determinism—different workflow runs may install different Helm versions, potentially causing unexpected test failures when a new Helm release ships breaking changes. Pin to a specific version (e.g.,v4.1.0for Helm v4, orv3.20.0for Helm v3) to ensure reproducibility and easier local debugging.♻️ Suggested fix
- name: Install Helm uses: azure/setup-helm@v4 with: - version: 'latest' + version: 'v4.1.0'🤖 Prompt for AI Agents