mirror of https://github.com/databricks/cli.git
Remove base path checks during sync (#576)
## Changes Earlier we removed recursive deletion from sync. This makes it safe enough for us to not restrict sync to just the namespace of the user. This PR removes that base path validation. Note: If the sync destination is under `/Repos` we still only create missing directories required if the path is under my namespace ie matches `/Repos/@me/` ## Tests Manually Before: ``` shreyas.goenka@THW32HFW6T hello-bundle % cli bundle deploy Starting upload of bundle files Error: path must be nested under /Users/shreyas.goenka@databricks.com or /Repos/shreyas.goenka@databricks.com ``` After: ``` shreyas.goenka@THW32HFW6T hello-bundle % cli bundle deploy Starting upload of bundle files Uploaded bundle files at /Shared/common-test/hello-bundle/files! Starting resource deployment Resource deployment completed! ```
This commit is contained in:
parent
9a0888126c
commit
a7a109a5d8
|
@ -13,42 +13,6 @@ import (
|
||||||
"github.com/databricks/databricks-sdk-go/service/workspace"
|
"github.com/databricks/databricks-sdk-go/service/workspace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Return if the child path is nested under the parent path.
|
|
||||||
func isPathNestedUnder(child, parent string) bool {
|
|
||||||
child = path.Clean(child)
|
|
||||||
parent = path.Clean(parent)
|
|
||||||
|
|
||||||
// Traverse up the tree as long as "child" is contained in "parent".
|
|
||||||
for len(child) > len(parent) && strings.HasPrefix(child, parent) {
|
|
||||||
child = path.Dir(child)
|
|
||||||
if child == parent {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the specified path is nested under one of the allowed base paths.
|
|
||||||
func checkPathNestedUnderBasePaths(me *iam.User, p string) error {
|
|
||||||
validBasePaths := []string{
|
|
||||||
path.Clean(fmt.Sprintf("/Users/%s", me.UserName)),
|
|
||||||
path.Clean(fmt.Sprintf("/Repos/%s", me.UserName)),
|
|
||||||
}
|
|
||||||
|
|
||||||
givenBasePath := path.Clean(p)
|
|
||||||
match := false
|
|
||||||
for _, basePath := range validBasePaths {
|
|
||||||
if isPathNestedUnder(givenBasePath, basePath) {
|
|
||||||
match = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !match {
|
|
||||||
return fmt.Errorf("path must be nested under %s", strings.Join(validBasePaths, " or "))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func repoPathForPath(me *iam.User, remotePath string) string {
|
func repoPathForPath(me *iam.User, remotePath string) string {
|
||||||
base := path.Clean(fmt.Sprintf("/Repos/%s", me.UserName))
|
base := path.Clean(fmt.Sprintf("/Repos/%s", me.UserName))
|
||||||
remotePath = path.Clean(remotePath)
|
remotePath = path.Clean(remotePath)
|
||||||
|
@ -66,11 +30,6 @@ func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClie
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = checkPathNestedUnderBasePaths(me, remotePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that the remote path exists.
|
// Ensure that the remote path exists.
|
||||||
// If it is a repo, it has to exist.
|
// If it is a repo, it has to exist.
|
||||||
// If it is a workspace path, it may not exist.
|
// If it is a workspace path, it may not exist.
|
||||||
|
|
|
@ -7,37 +7,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPathNestedUnderBasePaths(t *testing.T) {
|
|
||||||
me := iam.User{
|
|
||||||
UserName: "jane@doe.com",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not nested under allowed base paths.
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com/."))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com/.."))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/john@doe.com"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.comsuffix/foo"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos/"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Repos"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com/."))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com/.."))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/john@doe.com"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.comsuffix/foo"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users/"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/Users"))
|
|
||||||
assert.Error(t, checkPathNestedUnderBasePaths(&me, "/"))
|
|
||||||
|
|
||||||
// Nested under allowed base paths.
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com/foo"))
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com/./foo"))
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Repos/jane@doe.com/foo/bar/qux"))
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com/foo"))
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com/./foo"))
|
|
||||||
assert.NoError(t, checkPathNestedUnderBasePaths(&me, "/Users/jane@doe.com/foo/bar/qux"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathToRepoPath(t *testing.T) {
|
func TestPathToRepoPath(t *testing.T) {
|
||||||
me := iam.User{
|
me := iam.User{
|
||||||
UserName: "jane@doe.com",
|
UserName: "jane@doe.com",
|
||||||
|
|
Loading…
Reference in New Issue