agent.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package helm
  2. import (
  3. "errors"
  4. "io/ioutil"
  5. "github.com/porter-dev/porter/internal/config"
  6. "github.com/porter-dev/porter/internal/kubernetes"
  7. "github.com/porter-dev/porter/internal/logger"
  8. "helm.sh/helm/v3/pkg/action"
  9. "helm.sh/helm/v3/pkg/kube"
  10. "helm.sh/helm/v3/pkg/release"
  11. "helm.sh/helm/v3/pkg/storage"
  12. "helm.sh/helm/v3/pkg/chartutil"
  13. kubefake "helm.sh/helm/v3/pkg/kube/fake"
  14. k8s "k8s.io/client-go/kubernetes"
  15. )
  16. // Agent is a Helm agent for performing helm operations
  17. type Agent struct {
  18. ActionConfig *action.Configuration
  19. }
  20. // Form represents the options for connecting to a cluster and
  21. // creating a Helm agent
  22. type Form struct {
  23. KubeConfig []byte
  24. AllowedContexts []string
  25. Context string `json:"context" form:"required"`
  26. Storage string `json:"storage" form:"oneof=secret configmap memory"`
  27. Namespace string `json:"namespace"`
  28. }
  29. // ToAgent uses the Form to generate an agent. Setting testing=true will create
  30. // a test agent with in-memory storage
  31. func (h *Form) ToAgent(
  32. l *logger.Logger,
  33. helmConf *config.HelmGlobalConf,
  34. storage *storage.Storage,
  35. ) (*Agent, error) {
  36. if helmConf.IsTesting {
  37. testStorage := storage
  38. if testStorage == nil {
  39. testStorage = StorageMap["memory"](nil, h.Namespace, nil)
  40. }
  41. return &Agent{&action.Configuration{
  42. Releases: testStorage,
  43. KubeClient: &kubefake.FailingKubeClient{
  44. PrintingKubeClient: kubefake.PrintingKubeClient{
  45. Out: ioutil.Discard,
  46. },
  47. },
  48. Capabilities: chartutil.DefaultCapabilities,
  49. Log: l.Printf,
  50. }}, nil
  51. }
  52. // create a kubernetes agent
  53. conf := &kubernetes.OutOfClusterConfig{
  54. KubeConfig: h.KubeConfig,
  55. AllowedContexts: h.AllowedContexts,
  56. Context: h.Context,
  57. }
  58. k8sAgent, err := kubernetes.AgentFromOutOfClusterConfig(conf)
  59. if err != nil {
  60. return nil, err
  61. }
  62. clientset, ok := k8sAgent.Clientset.(*k8s.Clientset)
  63. if !ok {
  64. return nil, errors.New("Agent Clientset was not of type *(k8s.io/client-go/kubernetes).Clientset")
  65. }
  66. // use k8s agent to create Helm agent
  67. return &Agent{&action.Configuration{
  68. RESTClientGetter: k8sAgent.RESTClientGetter,
  69. KubeClient: kube.New(k8sAgent.RESTClientGetter),
  70. Releases: StorageMap[h.Storage](l, h.Namespace, clientset),
  71. Log: l.Printf,
  72. }}, nil
  73. }
  74. // ListReleases lists releases based on a ListFilter
  75. func (a *Agent) ListReleases(
  76. namespace string,
  77. filter *ListFilter,
  78. ) ([]*release.Release, error) {
  79. cmd := action.NewList(a.ActionConfig)
  80. filter.apply(cmd)
  81. return cmd.Run()
  82. }
  83. // GetRelease returns the info of a release.
  84. func (a *Agent) GetRelease(
  85. name string,
  86. version int,
  87. ) (*release.Release, error) {
  88. // Namespace is already known by the RESTClientGetter.
  89. cmd := action.NewGet(a.ActionConfig)
  90. cmd.Version = version
  91. return cmd.Run(name)
  92. }