agent.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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/release"
  8. "k8s.io/helm/pkg/chartutil"
  9. )
  10. // Agent is a Helm agent for performing helm operations
  11. type Agent struct {
  12. ActionConfig *action.Configuration
  13. }
  14. // ListReleases lists releases based on a ListFilter
  15. func (a *Agent) ListReleases(
  16. namespace string,
  17. filter *ListFilter,
  18. ) ([]*release.Release, error) {
  19. cmd := action.NewList(a.ActionConfig)
  20. filter.apply(cmd)
  21. return cmd.Run()
  22. }
  23. // GetRelease returns the info of a release.
  24. func (a *Agent) GetRelease(
  25. name string,
  26. version int,
  27. ) (*release.Release, error) {
  28. // Namespace is already known by the RESTClientGetter.
  29. cmd := action.NewGet(a.ActionConfig)
  30. cmd.Version = version
  31. return cmd.Run(name)
  32. }
  33. // GetReleaseHistory returns a list of charts for a specific release
  34. func (a *Agent) GetReleaseHistory(
  35. name string,
  36. ) ([]*release.Release, error) {
  37. cmd := action.NewHistory(a.ActionConfig)
  38. return cmd.Run(name)
  39. }
  40. // UpgradeRelease upgrades a specific release with new values.yaml
  41. func (a *Agent) UpgradeRelease(
  42. name string,
  43. values string,
  44. ) (*release.Release, error) {
  45. valuesYaml, err := chartutil.ReadValues([]byte(values))
  46. if err != nil {
  47. return nil, fmt.Errorf("Values could not be parsed: %v", err)
  48. }
  49. return a.UpgradeReleaseByValues(name, valuesYaml)
  50. }
  51. // UpgradeReleaseByValues upgrades a release by unmarshaled yaml values
  52. func (a *Agent) UpgradeReleaseByValues(
  53. name string,
  54. values map[string]interface{},
  55. ) (*release.Release, error) {
  56. // grab the latest release
  57. rel, err := a.GetRelease(name, 0)
  58. if err != nil {
  59. return nil, fmt.Errorf("Could not get release to be upgraded: %v", err)
  60. }
  61. ch := rel.Chart
  62. cmd := action.NewUpgrade(a.ActionConfig)
  63. res, err := cmd.Run(name, ch, values)
  64. if err != nil {
  65. return nil, fmt.Errorf("Upgrade failed: %v", err)
  66. }
  67. return res, nil
  68. }
  69. // InstallChartConfig is the config required to install a chart
  70. type InstallChartConfig struct {
  71. Chart *chart.Chart
  72. Name string
  73. Namespace string
  74. Values map[string]interface{}
  75. }
  76. // InstallChartFromValuesBytes reads the raw values and calls Agent.InstallChart
  77. func (a *Agent) InstallChartFromValuesBytes(
  78. conf *InstallChartConfig,
  79. values []byte,
  80. ) (*release.Release, error) {
  81. valuesYaml, err := chartutil.ReadValues(values)
  82. if err != nil {
  83. return nil, fmt.Errorf("Values could not be parsed: %v", err)
  84. }
  85. conf.Values = valuesYaml
  86. return a.InstallChart(conf)
  87. }
  88. // InstallChart installs a new chart
  89. func (a *Agent) InstallChart(
  90. conf *InstallChartConfig,
  91. ) (*release.Release, error) {
  92. cmd := action.NewInstall(a.ActionConfig)
  93. if cmd.Version == "" && cmd.Devel {
  94. cmd.Version = ">0.0.0-0"
  95. }
  96. cmd.ReleaseName = conf.Name
  97. cmd.Namespace = conf.Namespace
  98. if err := checkIfInstallable(conf.Chart); err != nil {
  99. return nil, err
  100. }
  101. // if chartRequested.Metadata.Deprecated {
  102. // return nil, fmt.Errorf("This chart is deprecated")
  103. // }
  104. if req := conf.Chart.Metadata.Dependencies; req != nil {
  105. if err := action.CheckDependencies(conf.Chart, req); err != nil {
  106. // TODO: Handle dependency updates.
  107. return nil, err
  108. }
  109. }
  110. return cmd.Run(conf.Chart, conf.Values)
  111. }
  112. // RollbackRelease rolls a release back to a specified revision/version
  113. func (a *Agent) RollbackRelease(
  114. name string,
  115. version int,
  116. ) error {
  117. cmd := action.NewRollback(a.ActionConfig)
  118. cmd.Version = version
  119. return cmd.Run(name)
  120. }
  121. // ------------------------ Helm agent helper functions ------------------------ //
  122. // checkIfInstallable validates if a chart can be installed
  123. // Application chart type is only installable
  124. func checkIfInstallable(ch *chart.Chart) error {
  125. switch ch.Metadata.Type {
  126. case "", "application":
  127. return nil
  128. }
  129. return errors.Errorf("%s charts are not installable", ch.Metadata.Type)
  130. }