@@ -18,10 +18,13 @@ package action
1818
1919import (
2020 "fmt"
21+ "net/url"
2122 "path/filepath"
23+ "runtime"
2224 "strings"
2325
2426 "github.com/Masterminds/log-go"
27+ "github.com/pkg/errors"
2528 "gopkg.in/yaml.v2"
2629
2730 pkg "github.com/rancher-sandbox/hypper/internal/package"
@@ -168,14 +171,27 @@ func (i *Install) CreateDepRelsFromAnnot(p *pkg.Pkg,
168171 // find dependency:
169172 depChrtVer , depInRepo := repoEntries [dep .Name ]
170173 if ! depInRepo {
171-
172- // If the dependency is not in a known repo we should fail to
173- // load it. LoadChart will pull down a chart from the Internet.
174- // If the repo is not one the user has opted-in by adding the
175- // repo to we should not load the chart for security reasons.
176- if strings .HasPrefix (dep .Repository , "file://" ) {
177- // Load chart to get ns and other info
178- log .Debugf ("Dependency \" %s\" not found in repos, attempting to load local chart" , dep .Name )
174+ u , err := url .Parse (dep .Repository )
175+ var isWindowsPath bool
176+ if err != nil {
177+ // check if the path is a windows local path like c:\foo\bar
178+ // Is there a better way to check for this? There must be
179+ if runtime .GOOS == "windows" && strings .Contains (err .Error (), "invalid control character in URL" ) {
180+ isWindowsPath = true
181+ } else {
182+ // we have an invalid repository
183+ return errors .Wrap (err , fmt .Sprintf ("unable to parse repository %q" , dep .Repository ))
184+ }
185+ }
186+ // Local charts (where there is no scheme) and those specified
187+ // with the file scheme can be processed. They are local. Any
188+ // chart that is in a repository should be from an added repo.
189+ // Adding a repo enables a user to opt-in for security purposes.
190+ // This is what linux system package managers do and it has been
191+ // a recommendation from security reviews for Helm.
192+ if u .Scheme == "" || u .Scheme == "file" || isWindowsPath {
193+ // pull chart to obtain default ns
194+ log .Debugf ("Dependency \" %s\" not found in repos, loading chart" , dep .Name )
179195 depChart , err := i .LoadChart (dep .Name , p .ParentChartPath , dep .Repository , dep .Version , settings , logger )
180196 if err != nil {
181197 return err
@@ -187,22 +203,32 @@ func (i *Install) CreateDepRelsFromAnnot(p *pkg.Pkg,
187203 depP := pkg .NewPkg (depRelName , dep .Name , depChart .Metadata .Version , depNS ,
188204 pkg .Unknown , pkg .Unknown , pkg .Unknown , dep .Repository , p .ParentChartPath )
189205
190- if depPinDB := pkgdb .GetPackageByFingerprint (depP .GetFingerPrint ()); depPinDB == nil {
191- // first time we process depP
206+ if strings .HasPrefix (dep .Repository , "file://" ) /* depP local */ {
207+ // if depP is local, it can depend on local charts too: check recursively,
208+ // but break loops by not recurse into charts already processed.
192209
193- // Add dep to DB, marking it as processed
194- pkgdb . Add ( depP )
210+ if depPinDB := pkgdb . GetPackageByFingerprint ( depP . GetFingerPrint ()); depPinDB == nil {
211+ // first time we process depP
195212
196- // Create depP dependency relations, and recursively add any
197- // deps depP may have.
198- if err := i .CreateDepRelsFromAnnot (depP , depChart .Metadata .Annotations , repoEntries ,
199- pkgdb , settings , logger ); err != nil {
200- return err
213+ // Add dep to DB, marking it as processed
214+ pkgdb .Add (depP )
215+
216+ // Create depP dependency relations, and recursively add any
217+ // deps depP may have.
218+ if err := i .CreateDepRelsFromAnnot (depP , depChart .Metadata .Annotations , repoEntries ,
219+ pkgdb , settings , logger ); err != nil {
220+ return err
221+ }
201222 }
223+ } else {
224+ // depP is not a local chart
225+ // Add dep to DB
226+ pkgdb .Add (depP )
202227 }
203228 } else {
204229 return fmt .Errorf ("unable to load dependency %q from repository %q" , dep .Name , dep .Repository )
205230 }
231+
206232 } else {
207233 // obtain default ns and release name of dep:
208234 depNS = GetNamespaceFromAnnot (depChrtVer .chartVersions [0 ].Annotations , settings .Namespace ())
0 commit comments