mirror of https://github.com/databricks/cli.git
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
|
package permissions
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/databricks/cli/bundle/config/resources"
|
||
|
"github.com/databricks/cli/libs/diag"
|
||
|
"github.com/databricks/databricks-sdk-go/service/workspace"
|
||
|
)
|
||
|
|
||
|
type WorkspacePathPermissions struct {
|
||
|
Path string
|
||
|
Permissions []resources.Permission
|
||
|
}
|
||
|
|
||
|
func ObjectAclToResourcePermissions(path string, acl []workspace.WorkspaceObjectAccessControlResponse) *WorkspacePathPermissions {
|
||
|
permissions := make([]resources.Permission, 0)
|
||
|
for _, a := range acl {
|
||
|
// Skip the admin group because it's added to all resources by default.
|
||
|
if a.GroupName == "admins" {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
for _, pl := range a.AllPermissions {
|
||
|
permissions = append(permissions, resources.Permission{
|
||
|
Level: convertWorkspaceObjectPermissionLevel(pl.PermissionLevel),
|
||
|
GroupName: a.GroupName,
|
||
|
UserName: a.UserName,
|
||
|
ServicePrincipalName: a.ServicePrincipalName,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return &WorkspacePathPermissions{Permissions: permissions, Path: path}
|
||
|
}
|
||
|
|
||
|
func (p WorkspacePathPermissions) Compare(perms []resources.Permission) diag.Diagnostics {
|
||
|
var diags diag.Diagnostics
|
||
|
|
||
|
// Check the permissions in the workspace and see if they are all set in the bundle.
|
||
|
ok, missing := containsAll(p.Permissions, perms)
|
||
|
if !ok {
|
||
|
diags = diags.Append(diag.Diagnostic{
|
||
|
Severity: diag.Warning,
|
||
|
Summary: "untracked permissions apply to target workspace path",
|
||
|
Detail: fmt.Sprintf("The following permissions apply to the workspace folder at %q but are not configured in the bundle:\n%s", p.Path, toString(missing)),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return diags
|
||
|
}
|
||
|
|
||
|
// containsAll checks if permA contains all permissions in permB.
|
||
|
func containsAll(permA []resources.Permission, permB []resources.Permission) (bool, []resources.Permission) {
|
||
|
missing := make([]resources.Permission, 0)
|
||
|
for _, a := range permA {
|
||
|
found := false
|
||
|
for _, b := range permB {
|
||
|
if a == b {
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
missing = append(missing, a)
|
||
|
}
|
||
|
}
|
||
|
return len(missing) == 0, missing
|
||
|
}
|
||
|
|
||
|
// convertWorkspaceObjectPermissionLevel converts matching object permission levels to bundle ones.
|
||
|
// If there is no matching permission level, it returns permission level as is, for example, CAN_EDIT.
|
||
|
func convertWorkspaceObjectPermissionLevel(level workspace.WorkspaceObjectPermissionLevel) string {
|
||
|
switch level {
|
||
|
case workspace.WorkspaceObjectPermissionLevelCanRead:
|
||
|
return CAN_VIEW
|
||
|
default:
|
||
|
return string(level)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func toString(p []resources.Permission) string {
|
||
|
var sb strings.Builder
|
||
|
for _, perm := range p {
|
||
|
sb.WriteString(fmt.Sprintf("- %s\n", perm.String()))
|
||
|
}
|
||
|
return sb.String()
|
||
|
}
|