Localize resources (#4912)

* Localize resources

* Improve readability

* Add integration tests

* Group test helper functions
This commit is contained in:
Anna Song
2023-01-05 11:47:59 -05:00
committed by GitHub
parent 6949c83840
commit 06da3b96a2
4 changed files with 466 additions and 25 deletions

View File

@@ -10,9 +10,18 @@ type ResourceLoadError struct {
FileError error
}
var _ error = ResourceLoadError{}
func (rle ResourceLoadError) Error() string {
return fmt.Sprintf(`when parsing as inline received error: %s
when parsing as filepath received error: %s`, rle.InlineError, rle.FileError)
}
type PathLocalizeError struct {
Path string
FileError error
RootError error
}
func (ple PathLocalizeError) Error() string {
return fmt.Sprintf(`could not localize path %q as file: %s; could not localize path %q as directory: %s`,
ple.Path, ple.FileError, ple.Path, ple.RootError)
}

View File

@@ -148,11 +148,15 @@ func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
kust.Crds,
lc.localizeFile,
},
"resources": {
kust.Resources,
lc.localizeResource,
},
} {
for i, path := range field.paths {
locPath, err := field.locFn(path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize %s path", fieldName)
return errors.WrapPrefixf(err, "unable to localize %s entry", fieldName)
}
field.paths[i] = locPath
}
@@ -198,8 +202,6 @@ func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
kust.Replacements[i].Path = newPath
}
}
// TODO(annasong): localize all other kustomization fields: resources
return nil
}
@@ -254,6 +256,39 @@ func (lc *localizer) localizePatches(patches []types.Patch) error {
return nil
}
// localizeResource localizes resource path, a file or root, and returns the
// localized path
func (lc *localizer) localizeResource(path string) (string, error) {
var locPath string
content, fileErr := lc.ldr.Load(path)
// The following check catches the case where path is a repo root.
// Load on a repo will successfully return its README in HTML.
// Because HTML does not follow resource formatting, we then correctly try
// to localize path as a root.
if fileErr == nil {
_, resErr := lc.rFactory.NewResMapFromBytes(content)
if resErr != nil {
fileErr = errors.WrapPrefixf(resErr, "invalid resource at file %q", path)
} else {
locPath, fileErr = lc.localizeFileWithContent(path, content)
}
}
if fileErr != nil {
var rootErr error
locPath, rootErr = lc.localizeDir(path)
if rootErr != nil {
err := PathLocalizeError{
Path: path,
FileError: fileErr,
RootError: rootErr,
}
return "", err
}
}
return locPath, nil
}
// localizeFile localizes file path and returns the localized path
func (lc *localizer) localizeFile(path string) (string, error) {
content, err := lc.ldr.Load(path)
@@ -267,8 +302,9 @@ func (lc *localizer) localizeFile(path string) (string, error) {
func (lc *localizer) localizeFileWithContent(path string, content []byte) (string, error) {
var locPath string
if loader.IsRemoteFile(path) {
// TODO(annasong): You need to check if you can add a localize directory here to store
// the remote file content. There may be a directory that shares the localize directory name.
if lc.fSys.Exists(lc.root.Join(LocalizeDir)) {
return "", errors.Errorf("%s already contains %s needed to store file %q", lc.root, LocalizeDir, path)
}
locPath = locFilePath(path)
} else {
// ldr has checked that path must be relative; this is subject to change in beta.
@@ -306,8 +342,9 @@ func (lc *localizer) localizeDir(path string) (string, error) {
}
var locPath string
if repo := ldr.Repo(); repo != "" {
// TODO(annasong): You need to check if you can add a localize directory here to store
// the remote file content. There may be a directory that shares the localize directory name.
if lc.fSys.Exists(lc.root.Join(LocalizeDir)) {
return "", errors.Errorf("%s already contains %s needed to store root %q", lc.root, LocalizeDir, path)
}
locPath, err = locRootPath(path, repo, root, lc.fSys)
if err != nil {
return "", err

View File

@@ -1013,3 +1013,53 @@ nameSuffix: -test
}
checkLocalizeInTargetSuccess(t, kustAndComponents)
}
func TestLocalizeResources(t *testing.T) {
kustAndResources := map[string]string{
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- pod.yaml
- ../../alpha
`,
"pod.yaml": podConfiguration,
"../../alpha/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: my-
`,
}
expected, actual := makeFileSystems(t, "/a/b", kustAndResources)
err := Run("/a/b", "/", "", actual)
require.NoError(t, err)
addFiles(t, expected, "/localized-b/a/b", kustAndResources)
checkFSys(t, expected, actual)
}
func TestLocalizePathError(t *testing.T) {
kustAndResources := map[string]string{
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- b
`,
}
expected, actual := makeFileSystems(t, "/a", kustAndResources)
err := Run("/a", "/", "", actual)
const expectedFileErr = `invalid file reference: '/a/b' must resolve to a file`
const expectedRootErr = `unable to localize root "b": unable to find one of 'kustomization.yaml', 'kustomization.yml' or 'Kustomization' in directory '/a/b'`
var actualErr PathLocalizeError
require.ErrorAs(t, err, &actualErr)
require.Equal(t, "b", actualErr.Path)
require.EqualError(t, actualErr.FileError, expectedFileErr)
require.EqualError(t, actualErr.RootError, expectedRootErr)
const expectedErrPrefix = `unable to localize target "/a": unable to localize resources entry`
require.EqualError(t, err, fmt.Sprintf(`%s: could not localize path "b" as file: %s; could not localize path "b" as directory: %s`,
expectedErrPrefix, expectedFileErr, expectedRootErr))
checkFSys(t, expected, actual)
}