Skip to content

Commit 49a645f

Browse files
authored
Merge pull request #5294 from typeid/localize_absolute_paths
feat: localize absolute paths
2 parents e7a1549 + 7b1eaf1 commit 49a645f

File tree

6 files changed

+69
-22
lines changed

6 files changed

+69
-22
lines changed

api/internal/localizer/localizer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func (lc *localizer) localizeFileWithContent(path string, content []byte) (strin
381381
// 2. avoid paths that temporarily traverse outside the current root,
382382
// i.e. ../../../scope/target/current-root. The localized file will be surrounded by
383383
// different directories than its source, and so an uncleaned path may no longer be valid.
384-
locPath = cleanFilePath(lc.fSys, lc.root, path)
384+
locPath = cleanedRelativePath(lc.fSys, lc.root, path)
385385
}
386386
absPath := filepath.Join(lc.dst, locPath)
387387
if err := lc.fSys.MkdirAll(filepath.Dir(absPath)); err != nil {

api/internal/localizer/localizer_test.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,10 @@ func TestLocalizeFileCleaned(t *testing.T) {
296296
kind: Kustomization
297297
patches:
298298
- path: ../gamma/../../../alpha/beta/./gamma/patch.yaml
299+
- path: /alpha/beta/../beta/./gamma/patch2.yaml
299300
`,
300-
"patch.yaml": podConfiguration,
301+
"patch.yaml": podConfiguration,
302+
"patch2.yaml": podConfiguration,
301303
}
302304
expected, actual := makeFileSystems(t, "/alpha/beta/gamma", kustAndPatch)
303305

@@ -307,8 +309,10 @@ patches:
307309
kind: Kustomization
308310
patches:
309311
- path: patch.yaml
312+
- path: patch2.yaml
310313
`,
311-
"patch.yaml": podConfiguration,
314+
"patch.yaml": podConfiguration,
315+
"patch2.yaml": podConfiguration,
312316
})
313317
checkFSys(t, expected, actual)
314318
}
@@ -1194,19 +1198,40 @@ func TestLocalizeResources(t *testing.T) {
11941198
kind: Kustomization
11951199
resources:
11961200
- pod.yaml
1201+
- /a/b/pod2.yaml
11971202
- ../../alpha
11981203
`,
1199-
"pod.yaml": podConfiguration,
1204+
"pod.yaml": podConfiguration,
1205+
"pod2.yaml": podConfiguration,
12001206
"../../alpha/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
12011207
kind: Kustomization
12021208
namePrefix: my-
12031209
`,
12041210
}
1205-
expected, actual := makeFileSystems(t, "/a/b", kustAndResources)
12061211

1207-
checkRun(t, actual, "/a/b", "/", "/localized-b")
1208-
addFiles(t, expected, "/localized-b/a/b", kustAndResources)
1209-
checkFSys(t, expected, actual)
1212+
// Absolute path of `/a/b/pod2.yaml` is expected to be converted to a path
1213+
// relative to the kustomization root.
1214+
expectedKustAndResources := map[string]string{
1215+
"kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
1216+
kind: Kustomization
1217+
resources:
1218+
- pod.yaml
1219+
- pod2.yaml
1220+
- ../../alpha
1221+
`,
1222+
"pod.yaml": podConfiguration,
1223+
"pod2.yaml": podConfiguration,
1224+
"../../alpha/kustomization.yaml": `apiVersion: kustomize.config.k8s.io/v1beta1
1225+
kind: Kustomization
1226+
namePrefix: my-
1227+
`,
1228+
}
1229+
1230+
expectedFs, actualFs := makeFileSystems(t, "/a/b", kustAndResources)
1231+
1232+
checkRun(t, actualFs, "/a/b", "/", "/localized-b")
1233+
addFiles(t, expectedFs, "/localized-b/a/b", expectedKustAndResources)
1234+
checkFSys(t, expectedFs, actualFs)
12101235
}
12111236

12121237
func TestLocalizePathError(t *testing.T) {

api/internal/localizer/locloader.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,8 @@ func (ll *Loader) Load(path string) ([]byte, error) {
8989
if err != nil {
9090
return nil, errors.WrapPrefixf(err, "invalid file reference")
9191
}
92-
if filepath.IsAbs(path) {
93-
return nil, errors.Errorf("absolute paths not yet supported in alpha: file path %q is absolute", path)
94-
}
9592
if !loader.IsRemoteFile(path) && ll.local {
96-
cleanPath := cleanFilePath(ll.fSys, filesys.ConfirmedDir(ll.Root()), path)
93+
cleanPath := cleanedRelativePath(ll.fSys, filesys.ConfirmedDir(ll.Root()), path)
9794
cleanAbs := filepath.Join(ll.Root(), cleanPath)
9895
dir := filesys.ConfirmedDir(filepath.Dir(cleanAbs))
9996
// target cannot reference newDir, as this load would've failed prior to localize;

api/internal/localizer/locloader_test.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,11 @@ func TestLoadFails(t *testing.T) {
276276
checkNewLoader(req, ldr, &args, "/a", "/a", "/a/newDir", fSys)
277277

278278
cases := map[string]string{
279-
"absolute path": "/a/pod.yaml",
280-
"directory": "b",
281-
"non-existent file": "kubectl.yaml",
282-
"file outside root": "../alpha/beta/gamma/delta/deployment.yaml",
283-
"inside dst": "newDir/pod.yaml",
279+
"directory": "b",
280+
"non-existent file": "kubectl.yaml",
281+
"file outside root": "../alpha/beta/gamma/delta/deployment.yaml",
282+
"inside dst": "newDir/pod.yaml",
283+
"winding inside dst": "/a/test/../newDir/pod.yaml",
284284
}
285285
for name, file := range cases {
286286
file := file
@@ -291,8 +291,6 @@ func TestLoadFails(t *testing.T) {
291291
ldr, _, err := NewLoader("./a/../a", "/a/../a", "/a/newDir", fSys)
292292
req.NoError(err)
293293

294-
req.NoError(fSys.WriteFile("/a/newDir/pod.yaml", []byte(podConfiguration)))
295-
296294
_, err = ldr.Load(file)
297295
req.Error(err)
298296
})

api/internal/localizer/util.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,13 @@ func hasRef(repoURL string) bool {
112112
return repoSpec.Ref != ""
113113
}
114114

115-
// cleanFilePath returns file cleaned, where file is a relative path to root on fSys
116-
func cleanFilePath(fSys filesys.FileSystem, root filesys.ConfirmedDir, file string) string {
117-
abs := root.Join(file)
115+
// cleanedRelativePath returns a cleaned relative path of file to root on fSys
116+
func cleanedRelativePath(fSys filesys.FileSystem, root filesys.ConfirmedDir, file string) string {
117+
abs := file
118+
if !filepath.IsAbs(file) {
119+
abs = root.Join(file)
120+
}
121+
118122
dir, f, err := fSys.CleanedAbs(abs)
119123
if err != nil {
120124
log.Fatalf("cannot clean validated file path %q: %s", abs, err)

api/internal/localizer/util_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,26 @@ func TestLocRootPath_SymlinkPath(t *testing.T) {
301301
require.NoError(t, err)
302302
require.Equal(t, expected, actual)
303303
}
304+
305+
func TestCleanedRelativePath(t *testing.T) {
306+
fSys := filesys.MakeFsInMemory()
307+
require.NoError(t, fSys.MkdirAll("/root/test"))
308+
require.NoError(t, fSys.WriteFile("/root/test/file.yaml", []byte("")))
309+
require.NoError(t, fSys.WriteFile("/root/filetwo.yaml", []byte("")))
310+
311+
// Absolute path is cleaned to relative path
312+
cleanedPath := cleanedRelativePath(fSys, "/root/", "/root/test/file.yaml")
313+
require.Equal(t, "test/file.yaml", cleanedPath)
314+
315+
// Winding absolute path is cleaned to relative path
316+
cleanedPath = cleanedRelativePath(fSys, "/root/", "/root/test/../filetwo.yaml")
317+
require.Equal(t, "filetwo.yaml", cleanedPath)
318+
319+
// Already clean relative path stays the same
320+
cleanedPath = cleanedRelativePath(fSys, "/root/", "test/file.yaml")
321+
require.Equal(t, "test/file.yaml", cleanedPath)
322+
323+
// Winding relative path is cleaned
324+
cleanedPath = cleanedRelativePath(fSys, "/root/", "test/../filetwo.yaml")
325+
require.Equal(t, "filetwo.yaml", cleanedPath)
326+
}

0 commit comments

Comments
 (0)