1
16
17 package action
18
19 import (
20 "fmt"
21 "os"
22 "path/filepath"
23 "strings"
24
25 "github.com/pkg/errors"
26
27 "helm.sh/helm/v3/pkg/chartutil"
28 "helm.sh/helm/v3/pkg/cli"
29 "helm.sh/helm/v3/pkg/downloader"
30 "helm.sh/helm/v3/pkg/getter"
31 "helm.sh/helm/v3/pkg/registry"
32 "helm.sh/helm/v3/pkg/repo"
33 )
34
35
36
37
38 type Pull struct {
39 ChartPathOptions
40
41 Settings *cli.EnvSettings
42
43 Devel bool
44 Untar bool
45 VerifyLater bool
46 UntarDir string
47 DestDir string
48 cfg *Configuration
49 }
50
51 type PullOpt func(*Pull)
52
53 func WithConfig(cfg *Configuration) PullOpt {
54 return func(p *Pull) {
55 p.cfg = cfg
56 }
57 }
58
59
60 func NewPull() *Pull {
61 return NewPullWithOpts()
62 }
63
64
65 func NewPullWithOpts(opts ...PullOpt) *Pull {
66 p := &Pull{}
67 for _, fn := range opts {
68 fn(p)
69 }
70
71 return p
72 }
73
74
75 func (p *Pull) SetRegistryClient(client *registry.Client) {
76 p.cfg.RegistryClient = client
77 }
78
79
80 func (p *Pull) Run(chartRef string) (string, error) {
81 var out strings.Builder
82
83 c := downloader.ChartDownloader{
84 Out: &out,
85 Keyring: p.Keyring,
86 Verify: downloader.VerifyNever,
87 Getters: getter.All(p.Settings),
88 Options: []getter.Option{
89 getter.WithBasicAuth(p.Username, p.Password),
90 getter.WithPassCredentialsAll(p.PassCredentialsAll),
91 getter.WithTLSClientConfig(p.CertFile, p.KeyFile, p.CaFile),
92 getter.WithInsecureSkipVerifyTLS(p.InsecureSkipTLSverify),
93 getter.WithPlainHTTP(p.PlainHTTP),
94 },
95 RegistryClient: p.cfg.RegistryClient,
96 RepositoryConfig: p.Settings.RepositoryConfig,
97 RepositoryCache: p.Settings.RepositoryCache,
98 }
99
100 if registry.IsOCI(chartRef) {
101 c.Options = append(c.Options,
102 getter.WithRegistryClient(p.cfg.RegistryClient))
103 c.RegistryClient = p.cfg.RegistryClient
104 }
105
106 if p.Verify {
107 c.Verify = downloader.VerifyAlways
108 } else if p.VerifyLater {
109 c.Verify = downloader.VerifyLater
110 }
111
112
113
114 dest := p.DestDir
115 if p.Untar {
116 var err error
117 dest, err = os.MkdirTemp("", "helm-")
118 if err != nil {
119 return out.String(), errors.Wrap(err, "failed to untar")
120 }
121 defer os.RemoveAll(dest)
122 }
123
124 if p.RepoURL != "" {
125 chartURL, err := repo.FindChartInAuthAndTLSAndPassRepoURL(p.RepoURL, p.Username, p.Password, chartRef, p.Version, p.CertFile, p.KeyFile, p.CaFile, p.InsecureSkipTLSverify, p.PassCredentialsAll, getter.All(p.Settings))
126 if err != nil {
127 return out.String(), err
128 }
129 chartRef = chartURL
130 }
131
132 saved, v, err := c.DownloadTo(chartRef, p.Version, dest)
133 if err != nil {
134 return out.String(), err
135 }
136
137 if p.Verify {
138 for name := range v.SignedBy.Identities {
139 fmt.Fprintf(&out, "Signed by: %v\n", name)
140 }
141 fmt.Fprintf(&out, "Using Key With Fingerprint: %X\n", v.SignedBy.PrimaryKey.Fingerprint)
142 fmt.Fprintf(&out, "Chart Hash Verified: %s\n", v.FileHash)
143 }
144
145
146 if p.Untar {
147 ud := p.UntarDir
148 if !filepath.IsAbs(ud) {
149 ud = filepath.Join(p.DestDir, ud)
150 }
151
152 udCheck := ud
153 if udCheck == "." {
154 _, udCheck = filepath.Split(chartRef)
155 } else {
156 _, chartName := filepath.Split(chartRef)
157 udCheck = filepath.Join(udCheck, chartName)
158 }
159
160 if _, err := os.Stat(udCheck); err != nil {
161 if err := os.MkdirAll(udCheck, 0755); err != nil {
162 return out.String(), errors.Wrap(err, "failed to untar (mkdir)")
163 }
164
165 } else {
166 return out.String(), errors.Errorf("failed to untar: a file or directory with the name %s already exists", udCheck)
167 }
168
169 return out.String(), chartutil.ExpandFile(ud, saved)
170 }
171 return out.String(), nil
172 }
173
View as plain text