agent.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package helm
  2. import (
  3. "fmt"
  4. "github.com/pkg/errors"
  5. "helm.sh/helm/v3/pkg/action"
  6. "helm.sh/helm/v3/pkg/chart"
  7. "helm.sh/helm/v3/pkg/chart/loader"
  8. "helm.sh/helm/v3/pkg/release"
  9. "k8s.io/helm/pkg/chartutil"
  10. )
  11. // Agent is a Helm agent for performing helm operations
  12. type Agent struct {
  13. ActionConfig *action.Configuration
  14. }
  15. // ListReleases lists releases based on a ListFilter
  16. func (a *Agent) ListReleases(
  17. namespace string,
  18. filter *ListFilter,
  19. ) ([]*release.Release, error) {
  20. cmd := action.NewList(a.ActionConfig)
  21. filter.apply(cmd)
  22. return cmd.Run()
  23. }
  24. // GetRelease returns the info of a release.
  25. func (a *Agent) GetRelease(
  26. name string,
  27. version int,
  28. ) (*release.Release, error) {
  29. // Namespace is already known by the RESTClientGetter.
  30. cmd := action.NewGet(a.ActionConfig)
  31. cmd.Version = version
  32. return cmd.Run(name)
  33. }
  34. // GetReleaseHistory returns a list of charts for a specific release
  35. func (a *Agent) GetReleaseHistory(
  36. name string,
  37. ) ([]*release.Release, error) {
  38. cmd := action.NewHistory(a.ActionConfig)
  39. return cmd.Run(name)
  40. }
  41. // UpgradeRelease upgrades a specific release with new values.yaml
  42. func (a *Agent) UpgradeRelease(
  43. name string,
  44. values string,
  45. ) (*release.Release, error) {
  46. // grab the latest release
  47. rel, err := a.GetRelease(name, 0)
  48. if err != nil {
  49. return nil, fmt.Errorf("Could not get release to be upgraded: %v", err)
  50. }
  51. ch := rel.Chart
  52. cmd := action.NewUpgrade(a.ActionConfig)
  53. valuesYaml, err := chartutil.ReadValues([]byte(values))
  54. if err != nil {
  55. return nil, fmt.Errorf("Values could not be parsed: %v", err)
  56. }
  57. res, err := cmd.Run(name, ch, valuesYaml)
  58. if err != nil {
  59. return nil, fmt.Errorf("Upgrade failed: %v", err)
  60. }
  61. return res, nil
  62. }
  63. // InstallChart installs a new chart by URL, absolute or relative filepaths.
  64. // Equivalent to `helm install [CHART_NAME] [cp]` where cp is one of the following:
  65. // 1) Absolute URL: https://example.com/charts/nginx-1.2.3.tgz
  66. // 2) path to packaged chart ./nginx-1.2.3.tgz
  67. // 3) path to unpacked chart ./nginx
  68. func (a *Agent) InstallChart(
  69. cp string,
  70. values []byte,
  71. ) (*release.Release, error) {
  72. cmd := action.NewInstall(a.ActionConfig)
  73. valuesYaml, err := chartutil.ReadValues(values)
  74. if err != nil {
  75. return nil, fmt.Errorf("Values could not be parsed: %v", err)
  76. }
  77. // Only supports filepaths for now, URL option WIP.
  78. // Check chart dependencies to make sure all are present in /charts
  79. chartRequested, err := loader.Load(cp)
  80. if err != nil {
  81. return nil, err
  82. }
  83. if err := checkIfInstallable(chartRequested); err != nil {
  84. return nil, err
  85. }
  86. if chartRequested.Metadata.Deprecated {
  87. return nil, fmt.Errorf("This chart is deprecated")
  88. }
  89. if req := chartRequested.Metadata.Dependencies; req != nil {
  90. if err := action.CheckDependencies(chartRequested, req); err != nil {
  91. // TODO: Handle dependency updates.
  92. return nil, err
  93. }
  94. }
  95. return cmd.Run(chartRequested, valuesYaml)
  96. }
  97. // RollbackRelease rolls a release back to a specified revision/version
  98. func (a *Agent) RollbackRelease(
  99. name string,
  100. version int,
  101. ) error {
  102. cmd := action.NewRollback(a.ActionConfig)
  103. cmd.Version = version
  104. return cmd.Run(name)
  105. }
  106. // ------------------------ Helm agent helper functions ------------------------ //
  107. // checkIfInstallable validates if a chart can be installed
  108. // Application chart type is only installable
  109. func checkIfInstallable(ch *chart.Chart) error {
  110. switch ch.Metadata.Type {
  111. case "", "application":
  112. return nil
  113. }
  114. return errors.Errorf("%s charts are not installable", ch.Metadata.Type)
  115. }