Skip to main content
Glama

k8s-mcp-server

client.go8.81 kB
package helm import ( "context" "fmt" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/registry" "helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/repo" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "log" "os" "path/filepath" ) // Client wraps Helm operations type Client struct { settings *cli.EnvSettings restConfig *rest.Config k8sClient kubernetes.Interface } // NewClient creates a new Helm client func NewClient(kubeconfig string) (*Client, error) { settings := cli.New() if kubeconfig != "" { settings.KubeConfig = kubeconfig } // Get Kubernetes REST config var restConfig *rest.Config var err error if settings.KubeConfig != "" { restConfig, err = clientcmd.BuildConfigFromFlags("", settings.KubeConfig) } else { // Try to use the default kubeconfig path first if home := os.Getenv("HOME"); home != "" { defaultKubeconfig := filepath.Join(home, ".kube", "config") if _, err := os.Stat(defaultKubeconfig); err == nil { restConfig, err = clientcmd.BuildConfigFromFlags("", defaultKubeconfig) } else { restConfig, err = rest.InClusterConfig() } } else { restConfig, err = rest.InClusterConfig() } } if err != nil { return nil, fmt.Errorf("failed to get Kubernetes config: %w", err) } // Create Kubernetes client k8sClient, err := kubernetes.NewForConfig(restConfig) if err != nil { return nil, fmt.Errorf("failed to create Kubernetes client: %w", err) } return &Client{ settings: settings, restConfig: restConfig, k8sClient: k8sClient, }, nil } func (c *Client) InstallChart(ctx context.Context, namespace, releaseName, chartName, repoURL string, values map[string]interface{}) (*release.Release, error) { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewInstall(actionConfig) client.Namespace = namespace client.ReleaseName = releaseName client.CreateNamespace = true cln, err := registry.NewClient( registry.ClientOptDebug(true), registry.ClientOptCredentialsFile(""), registry.ClientOptEnableCache(false)) if err != nil { return nil, fmt.Errorf("failed to initialize registry: %w", err) } fmt.Println("Registry client created successfully:", cln) if values == nil { values = make(map[string]interface{}) } // If repoURL is provided, add it to settings or append to chartName accordingly if repoURL != "" { client.RepoURL = repoURL } // Locate the chart (resolves repo/chart or OCI) chartPath, err := client.LocateChart(chartName, c.settings) if err != nil { return nil, fmt.Errorf("failed to locate chart: %w", err) } // Load the chart from the resolved path (can be a URL or OCI reference) chart, err := loader.Load(chartPath) if err != nil { return nil, fmt.Errorf("failed to load chart: %w", err) } // Run the install action release, err := client.Run(chart, values) if err != nil { return nil, fmt.Errorf("failed to install chart: %w", err) } return release, nil } func (c *Client) UpgradeChart(ctx context.Context, namespace, releaseName, chartName string, values map[string]interface{}) (*release.Release, error) { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, fmt.Errorf("failed to initialize action config: %w", err) } // Create and assign registry client regClient, err := registry.NewClient( registry.ClientOptDebug(true), registry.ClientOptEnableCache(false), ) if err != nil { return nil, fmt.Errorf("failed to initialize registry client: %w", err) } fmt.Println("Registry client created successfully:", regClient) client := action.NewUpgrade(actionConfig) client.Namespace = namespace if values == nil { values = make(map[string]interface{}) } // Locate the chart (for both OCI and regular charts) chartPath, err := client.LocateChart(chartName, c.settings) if err != nil { return nil, fmt.Errorf("failed to locate chart: %w", err) } chart, err := loader.Load(chartPath) if err != nil { return nil, fmt.Errorf("failed to load chart: %w", err) } release, err := client.Run(releaseName, chart, values) if err != nil { return nil, fmt.Errorf("failed to upgrade chart: %w", err) } return release, nil } // UninstallChart uninstalls a Helm release func (c *Client) UninstallChart(ctx context.Context, namespace, releaseName string) error { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewUninstall(actionConfig) _, err := client.Run(releaseName) if err != nil { return fmt.Errorf("failed to uninstall release: %w", err) } return nil } func (c *Client) ListReleases(ctx context.Context, namespace string) ([]*release.Release, error) { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewList(actionConfig) client.AllNamespaces = namespace == "" releases, err := client.Run() if err != nil { return nil, fmt.Errorf("failed to list releases: %w", err) } // remove useless fields from releases for _, release := range releases { release.Chart.Templates = nil release.Chart.Files = nil release.Chart.Values = nil release.Chart.Schema = nil release.Config = nil release.Manifest = "" release.Chart.Lock = nil release.Hooks = nil } return releases, nil } func (c *Client) GetRelease(ctx context.Context, namespace, releaseName string) (*release.Release, error) { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewGet(actionConfig) release, err := client.Run(releaseName) if err != nil { return nil, fmt.Errorf("failed to get release: %w", err) } return release, nil } func (c *Client) GetReleaseHistory(ctx context.Context, namespace, releaseName string) ([]*release.Release, error) { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewHistory(actionConfig) releases, err := client.Run(releaseName) if err != nil { return nil, fmt.Errorf("failed to get release history: %w", err) } return releases, nil } // RollbackRelease rolls back a Helm release func (c *Client) RollbackRelease(ctx context.Context, namespace, releaseName string, revision int) error { actionConfig := &action.Configuration{} if err := actionConfig.Init(c.settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return fmt.Errorf("failed to initialize action config: %w", err) } client := action.NewRollback(actionConfig) client.Version = revision if err := client.Run(releaseName); err != nil { return fmt.Errorf("failed to rollback release: %w", err) } return nil } // addRepo adds a Helm repository func (c *Client) HelmRepoAdd(ctx context.Context, name, url string) error { repoFile := c.settings.RepositoryConfig // Ensure the file directory exists if err := os.MkdirAll(filepath.Dir(repoFile), 0755); err != nil { return err } // Load existing repositories f, err := repo.LoadFile(repoFile) if err != nil && !os.IsNotExist(err) { return err } if f == nil { f = repo.NewFile() } // Check if repo already exists if f.Has(name) { return nil // Already exists } // Add the repository entry := &repo.Entry{ Name: name, URL: url, } r, err := repo.NewChartRepository(entry, getter.All(c.settings)) if err != nil { return err } if _, err := r.DownloadIndexFile(); err != nil { return fmt.Errorf("failed to download repository index: %w", err) } f.Update(entry) return f.WriteFile(repoFile, 0644) } func (c *Client) HelmRepoList(ctx context.Context) ([]*repo.Entry, error) { repoFile := c.settings.RepositoryConfig f, err := repo.LoadFile(repoFile) if err != nil { return nil, fmt.Errorf("failed to load repository file: %w", err) } return f.Repositories, nil }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/reza-gholizade/k8s-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server