Examples

This document runs though a series of examples of using the Helm SDK. Intended to document various SDK functionalities.

The final example shows main.go driver ( link). That runs the below actions and includes necessary helper functions.

The code for the examples lives in the helm/helm-www/sdkexamples/ directory. And is intended to be fully functional.

Actions

Install Action

This example installs the given chart/release, for the given version and values:

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "helm.sh/helm/v3/pkg/action"
  7. "helm.sh/helm/v3/pkg/chart/loader"
  8. "helm.sh/helm/v3/pkg/cli"
  9. "helm.sh/helm/v3/pkg/downloader"
  10. "helm.sh/helm/v3/pkg/getter"
  11. )
  12. func runInstall(ctx context.Context, logger *log.Logger, settings *cli.EnvSettings, releaseName string, chartRef string, chartVersion string, releaseValues map[string]interface{}) error {
  13. actionConfig, err := initActionConfig(settings, logger)
  14. if err != nil {
  15. return fmt.Errorf("failed to init action config: %w", err)
  16. }
  17. installClient := action.NewInstall(actionConfig)
  18. installClient.DryRunOption = "none"
  19. installClient.ReleaseName = releaseName
  20. installClient.Namespace = settings.Namespace()
  21. installClient.Version = chartVersion
  22. registryClient, err := newRegistryClientTLS(
  23. settings,
  24. logger,
  25. installClient.CertFile,
  26. installClient.KeyFile,
  27. installClient.CaFile,
  28. installClient.InsecureSkipTLSverify,
  29. installClient.PlainHTTP)
  30. if err != nil {
  31. return fmt.Errorf("failed to created registry client: %w", err)
  32. }
  33. installClient.SetRegistryClient(registryClient)
  34. chartPath, err := installClient.ChartPathOptions.LocateChart(chartRef, settings)
  35. if err != nil {
  36. return err
  37. }
  38. providers := getter.All(settings)
  39. chart, err := loader.Load(chartPath)
  40. if err != nil {
  41. return err
  42. }
  43. // Check chart dependencies to make sure all are present in /charts
  44. if chartDependencies := chart.Metadata.Dependencies; chartDependencies != nil {
  45. if err := action.CheckDependencies(chart, chartDependencies); err != nil {
  46. err = fmt.Errorf("failed to check chart dependencies: %w", err)
  47. if !installClient.DependencyUpdate {
  48. return err
  49. }
  50. manager := &downloader.Manager{
  51. Out: logger.Writer(),
  52. ChartPath: chartPath,
  53. Keyring: installClient.ChartPathOptions.Keyring,
  54. SkipUpdate: false,
  55. Getters: providers,
  56. RepositoryConfig: settings.RepositoryConfig,
  57. RepositoryCache: settings.RepositoryCache,
  58. Debug: settings.Debug,
  59. RegistryClient: installClient.GetRegistryClient(),
  60. }
  61. if err := manager.Update(); err != nil {
  62. return err
  63. }
  64. // Reload the chart with the updated Chart.lock file.
  65. if chart, err = loader.Load(chartPath); err != nil {
  66. return fmt.Errorf("failed to reload chart after repo update: %w", err)
  67. }
  68. }
  69. }
  70. release, err := installClient.RunWithContext(ctx, chart, releaseValues)
  71. if err != nil {
  72. return fmt.Errorf("failed to run install: %w", err)
  73. }
  74. logger.Printf("release created:\n%+v", *release)
  75. return nil
  76. }

Upgrade Action

This example upgrades the given release, with the given chart, version and values:

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "helm.sh/helm/v3/pkg/action"
  7. "helm.sh/helm/v3/pkg/chart/loader"
  8. "helm.sh/helm/v3/pkg/cli"
  9. "helm.sh/helm/v3/pkg/downloader"
  10. "helm.sh/helm/v3/pkg/getter"
  11. )
  12. func runUpgrade(ctx context.Context, logger *log.Logger, settings *cli.EnvSettings, releaseName string, chartRef string, chartVersion string, releaseValues map[string]interface{}) error {
  13. actionConfig, err := initActionConfig(settings, logger)
  14. if err != nil {
  15. return fmt.Errorf("failed to init action config: %w", err)
  16. }
  17. upgradeClient := action.NewUpgrade(actionConfig)
  18. upgradeClient.Namespace = settings.Namespace()
  19. upgradeClient.DryRunOption = "none"
  20. upgradeClient.Version = chartVersion
  21. registryClient, err := newRegistryClientTLS(
  22. settings,
  23. logger,
  24. upgradeClient.CertFile,
  25. upgradeClient.KeyFile,
  26. upgradeClient.CaFile,
  27. upgradeClient.InsecureSkipTLSverify,
  28. upgradeClient.PlainHTTP)
  29. if err != nil {
  30. return fmt.Errorf("missing registry client: %w", err)
  31. }
  32. upgradeClient.SetRegistryClient(registryClient)
  33. chartPath, err := upgradeClient.ChartPathOptions.LocateChart(chartRef, settings)
  34. if err != nil {
  35. return err
  36. }
  37. providers := getter.All(settings)
  38. // Check chart dependencies to make sure all are present in /charts
  39. chart, err := loader.Load(chartPath)
  40. if err != nil {
  41. return fmt.Errorf("failed to load chart: %w", err)
  42. }
  43. if req := chart.Metadata.Dependencies; req != nil {
  44. if err := action.CheckDependencies(chart, req); err != nil {
  45. err = fmt.Errorf("failed to check chart dependencies: %w", err)
  46. if !upgradeClient.DependencyUpdate {
  47. return err
  48. }
  49. man := &downloader.Manager{
  50. Out: logger.Writer(),
  51. ChartPath: chartPath,
  52. Keyring: upgradeClient.ChartPathOptions.Keyring,
  53. SkipUpdate: false,
  54. Getters: providers,
  55. RepositoryConfig: settings.RepositoryConfig,
  56. RepositoryCache: settings.RepositoryCache,
  57. Debug: settings.Debug,
  58. }
  59. if err := man.Update(); err != nil {
  60. return err
  61. }
  62. // Reload the chart with the updated Chart.lock file.
  63. if chart, err = loader.Load(chartPath); err != nil {
  64. return fmt.Errorf("failed to reload chart after repo update: %w", err)
  65. }
  66. }
  67. }
  68. release, err := upgradeClient.RunWithContext(ctx, releaseName, chart, releaseValues)
  69. if err != nil {
  70. return fmt.Errorf("failed to run upgrade action: %w", err)
  71. }
  72. logger.Printf("release: %+v", release)
  73. return nil
  74. }

Uninstall Action

This example uninstalls the given release

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "helm.sh/helm/v3/pkg/action"
  6. "helm.sh/helm/v3/pkg/cli"
  7. )
  8. func runUninstall(logger *log.Logger, settings *cli.EnvSettings, releaseName string) error {
  9. actionConfig, err := initActionConfig(settings, logger)
  10. if err != nil {
  11. return fmt.Errorf("failed to init action config: %w", err)
  12. }
  13. uninstallClient := action.NewUninstall(actionConfig)
  14. uninstallClient.DeletionPropagation = "foreground" // "background" or "orphan"
  15. result, err := uninstallClient.Run(releaseName)
  16. if err != nil {
  17. return fmt.Errorf("failed to run uninstall action: %w", err)
  18. }
  19. if result != nil {
  20. logger.Printf("result: %+v\n", *result.Release)
  21. }
  22. logger.Printf("release \"%s\" uninstalled\n", releaseName)
  23. return nil
  24. }

List Action

This example lists all released charts (in the currently configured namespace)

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "helm.sh/helm/v3/pkg/action"
  6. "helm.sh/helm/v3/pkg/cli"
  7. )
  8. func runList(logger *log.Logger, settings *cli.EnvSettings) error {
  9. actionConfig, err := initActionConfigList(settings, logger, false)
  10. if err != nil {
  11. return fmt.Errorf("failed to init action config: %w", err)
  12. }
  13. listClient := action.NewList(actionConfig)
  14. // Only list deployed
  15. //listClient.Deployed = true
  16. listClient.All = true
  17. listClient.SetStateMask()
  18. results, err := listClient.Run()
  19. if err != nil {
  20. return fmt.Errorf("failed to run list action: %w", err)
  21. }
  22. for _, rel := range results {
  23. logger.Printf("list result: %+v", rel)
  24. }
  25. return nil
  26. }

Pull Action

This example pulls a chart from an OCI repository

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "helm.sh/helm/v3/pkg/action"
  6. "helm.sh/helm/v3/pkg/cli"
  7. )
  8. func runPull(logger *log.Logger, settings *cli.EnvSettings, chartRef, chartVersion string) error {
  9. actionConfig, err := initActionConfig(settings, logger)
  10. if err != nil {
  11. return fmt.Errorf("failed to init action config: %w", err)
  12. }
  13. registryClient, err := newRegistryClient(settings, false)
  14. if err != nil {
  15. return fmt.Errorf("failed to created registry client: %w", err)
  16. }
  17. actionConfig.RegistryClient = registryClient
  18. pullClient := action.NewPullWithOpts(
  19. action.WithConfig(actionConfig))
  20. // client.RepoURL = ""
  21. pullClient.DestDir = "./"
  22. pullClient.Settings = settings
  23. pullClient.Version = chartVersion
  24. result, err := pullClient.Run(chartRef)
  25. if err != nil {
  26. return fmt.Errorf("failed to pull chart: %w", err)
  27. }
  28. logger.Printf("%+v", result)
  29. return nil
  30. }

Driver

The driver here shows the necessary auxillary functions needed for the Helm SDK actions to function. And shows the above examples in action, to pull, install, update, and uninstall the ‘podinfo’ chart from an OCI repository.

  1. package main
  2. import (
  3. "bufio"
  4. "context"
  5. "fmt"
  6. "log"
  7. "os"
  8. "helm.sh/helm/v3/pkg/action"
  9. "helm.sh/helm/v3/pkg/cli"
  10. "helm.sh/helm/v3/pkg/registry"
  11. )
  12. var helmDriver string = os.Getenv("HELM_DRIVER")
  13. func initActionConfig(settings *cli.EnvSettings, logger *log.Logger) (*action.Configuration, error) {
  14. return initActionConfigList(settings, logger, false)
  15. }
  16. func initActionConfigList(settings *cli.EnvSettings, logger *log.Logger, allNamespaces bool) (*action.Configuration, error) {
  17. actionConfig := new(action.Configuration)
  18. namespace := func() string {
  19. // For list action, you can pass an empty string instead of settings.Namespace() to list
  20. // all namespaces
  21. if allNamespaces {
  22. return ""
  23. }
  24. return settings.Namespace()
  25. }()
  26. if err := actionConfig.Init(
  27. settings.RESTClientGetter(),
  28. namespace,
  29. helmDriver,
  30. logger.Printf); err != nil {
  31. return nil, err
  32. }
  33. return actionConfig, nil
  34. }
  35. func newRegistryClient(settings *cli.EnvSettings, plainHTTP bool) (*registry.Client, error) {
  36. opts := []registry.ClientOption{
  37. registry.ClientOptDebug(settings.Debug),
  38. registry.ClientOptEnableCache(true),
  39. registry.ClientOptWriter(os.Stderr),
  40. registry.ClientOptCredentialsFile(settings.RegistryConfig),
  41. }
  42. if plainHTTP {
  43. opts = append(opts, registry.ClientOptPlainHTTP())
  44. }
  45. // Create a new registry client
  46. registryClient, err := registry.NewClient(opts...)
  47. if err != nil {
  48. return nil, err
  49. }
  50. return registryClient, nil
  51. }
  52. func newRegistryClientTLS(settings *cli.EnvSettings, logger *log.Logger, certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool) (*registry.Client, error) {
  53. if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify {
  54. registryClient, err := registry.NewRegistryClientWithTLS(
  55. logger.Writer(),
  56. certFile,
  57. keyFile,
  58. caFile,
  59. insecureSkipTLSverify,
  60. settings.RegistryConfig,
  61. settings.Debug)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return registryClient, nil
  66. }
  67. registryClient, err := newRegistryClient(settings, plainHTTP)
  68. if err != nil {
  69. return nil, err
  70. }
  71. return registryClient, nil
  72. }
  73. func main() {
  74. logger := log.Default()
  75. // For convenience, initialize SDK setting via CLI mechanism
  76. settings := cli.New()
  77. // Release name, chart and values
  78. releaseName := "helm-sdk-example"
  79. chartRef := "oci://ghcr.io/stefanprodan/charts/podinfo"
  80. releaseValues := map[string]interface{}{
  81. "replicaCount": "2",
  82. }
  83. // Pull the chart to the local filesystem
  84. if err := runPull(logger, settings, chartRef, "6.4.1"); err != nil {
  85. fmt.Printf("failed to run pull: %+v", err)
  86. os.Exit(1)
  87. }
  88. // Install the chart (from the pulled chart local archive)
  89. if err := runInstall(context.TODO(), logger, settings, releaseName, "./podinfo-6.4.1.tgz", "", releaseValues); err != nil {
  90. fmt.Printf("failed to run install: %+v", err)
  91. os.Exit(1)
  92. }
  93. // List installed charts
  94. if err := runList(logger, settings); err != nil {
  95. fmt.Printf("failed to run list: %+v", err)
  96. os.Exit(1)
  97. }
  98. //
  99. fmt.Print("Chart installed. Press 'Return' to continue...")
  100. bufio.NewReader(os.Stdin).ReadBytes('\n')
  101. // Upgrade to version 6.5.4, updating the replicaCount to three
  102. releaseValues["replicaCount"] = "3"
  103. if err := runUpgrade(context.TODO(), logger, settings, releaseName, chartRef, "6.5.4", releaseValues); err != nil {
  104. fmt.Printf("failed to run upgrade: %+v", err)
  105. os.Exit(1)
  106. }
  107. // List installed charts
  108. if err := runList(logger, settings); err != nil {
  109. fmt.Printf("failed to run list: %+v", err)
  110. os.Exit(1)
  111. }
  112. //
  113. fmt.Print("Chart upgraded. Press 'Return' to continue...")
  114. bufio.NewReader(os.Stdin).ReadBytes('\n')
  115. // Uninstall the chart
  116. if err := runUninstall(logger, settings, releaseName); err != nil {
  117. fmt.Printf("failed to run uninstall: %+v", err)
  118. os.Exit(1)
  119. }
  120. }