Skip to content

Commit

Permalink
Reinstate kubernetes-sigs#4652 without url-related code
Browse files Browse the repository at this point in the history
Remove code that changes remotes-loading code path, as mandated by kubernetes-sigs#4756
  • Loading branch information
annasong20 committed Aug 29, 2022
1 parent 14b7282 commit f80cf9f
Show file tree
Hide file tree
Showing 21 changed files with 679 additions and 7 deletions.
8 changes: 8 additions & 0 deletions api/ifc/ifc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@ type KvLoader interface {

// Loader interface exposes methods to read bytes.
type Loader interface {

// Repo returns the repo location and true if this Loader
// was created from a url; otherwise the empty string and false.
Repo() (string, bool)

// Root returns the root location for this Loader.
Root() string

// New returns Loader located at newRoot.
New(newRoot string) (Loader, error)

// Load returns the bytes read from the location or an error.
Load(location string) ([]byte, error)

// Cleanup cleans the loader
Cleanup() error
}
Expand Down
2 changes: 1 addition & 1 deletion api/internal/git/repospec.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type RepoSpec struct {
// TODO(monopole): Drop raw, use processed fields instead.
raw string

// Host, e.g. github.com
// Host, e.g. https://github.com/
Host string

// orgRepo name (organization/repoName),
Expand Down
7 changes: 7 additions & 0 deletions api/internal/localizer/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

// Package localizer contains utilities for the command kustomize localize, which is
// documented under proposals/localize-command or at
// https://github.com/kubernetes-sigs/kustomize/blob/master/proposals/22-04-localize-command.md
package localizer
146 changes: 146 additions & 0 deletions api/internal/localizer/locloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package localizer

import (
"log"
"path/filepath"

"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

const dstPrefix = "localized"

// LocArgs holds localize arguments
type LocArgs struct {
// target; local copy if remote
Target filesys.ConfirmedDir

// directory that bounds target's local references, empty string if target is remote
Scope filesys.ConfirmedDir

// localize destination
NewDir filesys.ConfirmedDir
}

// locLoader is the Loader for kustomize localize. It is an ifc.Loader that enforces localize constraints.
type locLoader struct {
fSys filesys.FileSystem

args *LocArgs

// loader at locLoader's current directory
ifc.Loader

// whether locLoader and all its ancestors are the result of local references
local bool
}

var _ ifc.Loader = &locLoader{}

// NewLocLoader is the factory method for Loader, under localize constraints, at targetArg. For invalid localize arguments,
// NewLocLoader returns an error.
func NewLocLoader(targetArg string, scopeArg string, newDirArg string, fSys filesys.FileSystem) (ifc.Loader, LocArgs, error) {
// check earlier to avoid cleanup
repoSpec, err := git.NewRepoSpecFromURL(targetArg)
if err == nil && repoSpec.Ref == "" {
return nil, LocArgs{},
errors.Errorf("localize remote root '%s' missing ref query string parameter", targetArg)
}

// for security, should enforce load restrictions
ldr, err := loader.NewLoader(loader.RestrictionRootOnly, targetArg, fSys)
if err != nil {
return nil, LocArgs{}, errors.WrapPrefixf(err, "unable to establish localize target '%s'", targetArg)
}

scope, err := establishScope(scopeArg, targetArg, ldr, fSys)
if err != nil {
_ = ldr.Cleanup()
return nil, LocArgs{}, errors.WrapPrefixf(err, "invalid localize scope '%s'", scopeArg)
}

newDir, err := createNewDir(newDirArg, ldr, repoSpec, fSys)
if err != nil {
_ = ldr.Cleanup()
return nil, LocArgs{}, errors.WrapPrefixf(err, "invalid localize destination '%s'", newDirArg)
}

args := LocArgs{
Target: filesys.ConfirmedDir(ldr.Root()),
Scope: scope,
NewDir: newDir,
}
return &locLoader{
fSys: fSys,
args: &args,
Loader: ldr,
local: scope != "",
}, args, nil
}

// Load returns the contents of path if path is a valid localize file.
// Otherwise, Load returns an error.
func (ll *locLoader) Load(path string) ([]byte, error) {
// checks in root, and thus in scope
content, err := ll.Loader.Load(path)
if err != nil {
return nil, errors.WrapPrefixf(err, "invalid file reference")
}
if filepath.IsAbs(path) {
return nil, errors.Errorf("absolute paths not yet supported in alpha: file path '%s' is absolute", path)
}
if ll.local {
abs := filepath.Join(ll.Root(), path)
dir, f, err := ll.fSys.CleanedAbs(abs)
if err != nil {
// should never happen
log.Fatalf(errors.WrapPrefixf(err, "cannot clean validated file path '%s'", abs).Error())
}
// target cannot reference newDir, as this load would've failed prior to localize;
// not a problem if remote because then reference could only be in newDir if repo copy,
// which will be cleaned, is inside newDir
if dir.HasPrefix(ll.args.NewDir) {
return nil, errors.Errorf(
"file path '%s' references into localize destination '%s'", dir.Join(f), ll.args.NewDir)
}
}
return content, nil
}

// New returns a Loader at path if path is a valid localize root.
// Otherwise, New returns an error.
func (ll *locLoader) New(path string) (ifc.Loader, error) {
repoSpec, err := git.NewRepoSpecFromURL(path)
if err == nil && repoSpec.Ref == "" {
return nil, errors.Errorf("localize remote root '%s' missing ref query string parameter", path)
}

ldr, err := ll.Loader.New(path)
if err != nil {
return nil, errors.WrapPrefixf(err, "invalid root reference")
}

var isRemote bool
if _, isRemote = ldr.Repo(); !isRemote {
if ll.local && !filesys.ConfirmedDir(ldr.Root()).HasPrefix(ll.args.Scope) {
return nil, errors.Errorf("root '%s' outside localize scope '%s'", ldr.Root(), ll.args.Scope)
}
if ll.local && filesys.ConfirmedDir(ldr.Root()).HasPrefix(ll.args.NewDir) {
return nil, errors.Errorf(
"root '%s' references into localize destination '%s'", ldr.Root(), ll.args.NewDir)
}
}

return &locLoader{
fSys: ll.fSys,
args: ll.args,
Loader: ldr,
local: ll.local && !isRemote,
}, nil
}

0 comments on commit f80cf9f

Please sign in to comment.