agent.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. name string,
  72. namespace string,
  73. ) (*release.Release, error) {
  74. client := action.NewInstall(a.ActionConfig)
  75. if client.Version == "" && client.Devel {
  76. client.Version = ">0.0.0-0"
  77. }
  78. client.ReleaseName = name
  79. client.Namespace = namespace
  80. valuesYaml, err := chartutil.ReadValues(values)
  81. if err != nil {
  82. return nil, fmt.Errorf("Values could not be parsed: %v", err)
  83. }
  84. // Only supports filepaths for now, URL option WIP.
  85. // Check chart dependencies to make sure all are present in /charts
  86. chartRequested, err := loader.Load(cp)
  87. if err != nil {
  88. return nil, err
  89. }
  90. if err := checkIfInstallable(chartRequested); err != nil {
  91. return nil, err
  92. }
  93. // if chartRequested.Metadata.Deprecated {
  94. // return nil, fmt.Errorf("This chart is deprecated")
  95. // }
  96. if req := chartRequested.Metadata.Dependencies; req != nil {
  97. if err := action.CheckDependencies(chartRequested, req); err != nil {
  98. // TODO: Handle dependency updates.
  99. return nil, err
  100. }
  101. }
  102. return client.Run(chartRequested, valuesYaml)
  103. }
  104. // RollbackRelease rolls a release back to a specified revision/version
  105. func (a *Agent) RollbackRelease(
  106. name string,
  107. version int,
  108. ) error {
  109. cmd := action.NewRollback(a.ActionConfig)
  110. cmd.Version = version
  111. return cmd.Run(name)
  112. }
  113. // ------------------------ Helm agent helper functions ------------------------ //
  114. // checkIfInstallable validates if a chart can be installed
  115. // Application chart type is only installable
  116. func checkIfInstallable(ch *chart.Chart) error {
  117. switch ch.Metadata.Type {
  118. case "", "application":
  119. return nil
  120. }
  121. return errors.Errorf("%s charts are not installable", ch.Metadata.Type)
  122. }