Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ func (m *bundlePermissions) Apply(ctx context.Context, b *bundle.Bundle) diag.Di
return diag.FromErr(err)
}

// Target permissions follow root permissions when SelectTarget merges the lists.
targetPermissionsStart := len(b.Config.Permissions)
if b.Target != nil {
targetPermissionsStart -= len(b.Target.Permissions)
}

for _, group := range b.Config.Resources.AllResources() {
key := group.Description.PluralName
lm, ok := levelsMap[key]
Expand All @@ -124,6 +130,7 @@ func (m *bundlePermissions) Apply(ctx context.Context, b *bundle.Bundle) diag.Di
permissions,
key,
lm,
targetPermissionsStart,
)...)
writePermissions(field, permissions)
}
Expand Down Expand Up @@ -187,17 +194,24 @@ func convertPermissions(
resourcePermissions []resources.Permission,
resourceName string,
lm map[string]string,
targetPermissionsStart int,
) []resources.Permission {
var permissions []resources.Permission
for _, p := range bundlePermissions {
for i, p := range bundlePermissions {
level, ok := lm[string(p.Level)]
// If there is no bundle permission level defined in the map, it means
// it's not applicable for the resource, therefore skipping
if !ok {
continue
}

if notifyForPermissionOverlap(ctx, p, resourcePermissions, resourceName) {
if i >= targetPermissionsStart && resourceName == "jobs" && p.GroupName != "" {
// A job-level group permission takes precedence over the target-level one.
overlap, _ := isPermissionOverlap(p, resourcePermissions, resourceName)
if overlap {
continue
}
} else if notifyForPermissionOverlap(ctx, p, resourcePermissions, resourceName) {
continue
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/bundle/config/mutator"
"github.com/databricks/cli/bundle/config/resources"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn"
Expand Down Expand Up @@ -223,6 +224,58 @@ func TestWarningOnOverlapPermission(t *testing.T) {
require.Contains(t, b.Config.Resources.Jobs["job_2"].Permissions, resources.JobPermission{Level: "CAN_VIEW", GroupName: "TestGroup"})
}

func TestTargetGroupPermissionOverridesJobWithoutWarning(t *testing.T) {
for _, tc := range []struct {
name string
rootPermissions []resources.Permission
wantWarnings int
}{
{name: "target only"},
{
name: "root and target",
rootPermissions: []resources.Permission{
{Level: permissions.CAN_VIEW, GroupName: "TestGroup"},
},
wantWarnings: 1,
},
} {
t.Run(tc.name, func(t *testing.T) {
b := &bundle.Bundle{
Config: config.Root{
Permissions: tc.rootPermissions,
Targets: map[string]*config.Target{
"dev-ci": {
Permissions: []resources.Permission{
{Level: permissions.CAN_VIEW, GroupName: "TestGroup"},
},
Resources: &config.Resources{
Jobs: map[string]*resources.Job{
"job_1": {
JobSettings: jobs.JobSettings{Name: "job_1"},
Permissions: []resources.JobPermission{
{Level: "CAN_MANAGE_RUN", GroupName: "TestGroup"},
},
},
},
},
},
},
},
}

diags := bundle.ApplySeq(t.Context(), b, mutator.SelectTarget("dev-ci"), ApplyBundlePermissions())
require.Len(t, diags, tc.wantWarnings)
if tc.wantWarnings > 0 {
require.Equal(t, diag.Warning, diags[0].Severity)
require.Equal(t, "'jobs' already has permissions set for 'TestGroup' group", diags[0].Summary)
}
require.Equal(t, []resources.JobPermission{
{Level: "CAN_MANAGE_RUN", GroupName: "TestGroup"},
}, b.Config.Resources.Jobs["job_1"].Permissions)
})
}
}

func TestAllResourcesExplicitlyDefinedForPermissionsSupport(t *testing.T) {
r := config.Resources{}

Expand Down
Loading