Compare commits

...

3 Commits

Author SHA1 Message Date
Lennart Kats 543612313c
Merge remote-tracking branch 'origin/cp-encourage-root-path' into cp-encourage-root-path 2024-09-09 09:24:14 +02:00
Lennart Kats dc63c7cd63
Extend message 2024-09-09 09:20:17 +02:00
Lennart Kats 821239e45d
Add nil check 2024-09-02 14:00:28 +02:00
2 changed files with 17 additions and 11 deletions

View File

@ -2,6 +2,7 @@ package mutator
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle"
@ -132,15 +133,19 @@ func validateProductionMode(ctx context.Context, b *bundle.Bundle, isPrincipalUs
// We need to verify that there is only a single deployment of the current target. // We need to verify that there is only a single deployment of the current target.
// The best way to enforce this is to explicitly set root_path. // The best way to enforce this is to explicitly set root_path.
advice := fmt.Sprintf(
"set 'workspace.root_path' to make sure only one copy is deployed. A common practice is to use a username or principal name in this path, i.e. root_path: /Users/%s/.bundle/${bundle.name}/${bundle.target}",
b.Config.Workspace.CurrentUser.UserName,
)
if !isExplicitRootSet(b) { if !isExplicitRootSet(b) {
if isRunAsSet(r) || isPrincipalUsed { if isRunAsSet(r) || isPrincipalUsed {
// Just setting run_as is not enough to guarantee a single deployment, // Just setting run_as is not enough to guarantee a single deployment,
// and neither is setting a principal. // and neither is setting a principal.
// We only show a warning for these cases since we didn't historically // We only show a warning for these cases since we didn't historically
// report an error for them. // report an error for them.
return diag.Warningf("target with 'mode: production' should specify explicit 'workspace.root_path' to make sure only one copy is deployed") return diag.Warningf("target with 'mode: production' should " + advice)
} }
return diag.Errorf("target with 'mode: production' must specify explicit 'workspace.root_path' to make sure only one copy is deployed") return diag.Errorf("target with 'mode: production' must " + advice)
} }
return nil return nil
} }
@ -158,10 +163,10 @@ func isRunAsSet(r config.Resources) bool {
} }
func isExplicitRootSet(b *bundle.Bundle) bool { func isExplicitRootSet(b *bundle.Bundle) bool {
targetConfig, ok := b.Config.Targets[b.Config.Bundle.Target] if b.Config.Targets == nil {
if !ok || targetConfig == nil {
return false return false
} }
targetConfig := b.Config.Targets[b.Config.Bundle.Target]
if targetConfig.Workspace == nil { if targetConfig.Workspace == nil {
return false return false
} }

View File

@ -32,9 +32,6 @@ func mockBundle(mode config.Mode) *bundle.Bundle {
Branch: "main", Branch: "main",
}, },
}, },
Targets: map[string]*config.Target{
"": {},
},
Workspace: config.Workspace{ Workspace: config.Workspace{
CurrentUser: &config.User{ CurrentUser: &config.User{
ShortName: "lennart", ShortName: "lennart",
@ -280,14 +277,14 @@ func TestProcessTargetModeProduction(t *testing.T) {
b := mockBundle(config.Production) b := mockBundle(config.Production)
diags := validateProductionMode(context.Background(), b, false) diags := validateProductionMode(context.Background(), b, false)
require.ErrorContains(t, diags.Error(), "target with 'mode: production' must specify explicit 'workspace.root_path' to make sure only one copy is deployed") require.ErrorContains(t, diags.Error(), "target with 'mode: production' must set 'workspace.root_path' to make sure only one copy is deployed. A common practice is to use a username or principal name in this path, i.e. root_path: /Users/lennart@company.com/.bundle/${bundle.name}/${bundle.target}")
b.Config.Workspace.StatePath = "/Shared/.bundle/x/y/state" b.Config.Workspace.StatePath = "/Shared/.bundle/x/y/state"
b.Config.Workspace.ArtifactPath = "/Shared/.bundle/x/y/artifacts" b.Config.Workspace.ArtifactPath = "/Shared/.bundle/x/y/artifacts"
b.Config.Workspace.FilePath = "/Shared/.bundle/x/y/files" b.Config.Workspace.FilePath = "/Shared/.bundle/x/y/files"
diags = validateProductionMode(context.Background(), b, false) diags = validateProductionMode(context.Background(), b, false)
require.ErrorContains(t, diags.Error(), "target with 'mode: production' must specify explicit 'workspace.root_path' to make sure only one copy is deployed") require.ErrorContains(t, diags.Error(), "target with 'mode: production' must set 'workspace.root_path' to make sure only one copy is deployed. A common practice is to use a username or principal name in this path, i.e. root_path: /Users/lennart@company.com/.bundle/${bundle.name}/${bundle.target}")
permissions := []resources.Permission{ permissions := []resources.Permission{
{ {
@ -337,8 +334,12 @@ func TestProcessTargetModeProductionOkWithRootPath(t *testing.T) {
require.Error(t, diags.Error()) require.Error(t, diags.Error())
// ... but we're okay if we specify a root path // ... but we're okay if we specify a root path
b.Config.Targets[""].Workspace = &config.Workspace{ b.Config.Targets = map[string]*config.Target{
RootPath: "some-root-path", "": {
Workspace: &config.Workspace{
RootPath: "some-root-path",
},
},
} }
diags = validateProductionMode(context.Background(), b, false) diags = validateProductionMode(context.Background(), b, false)
require.NoError(t, diags.Error()) require.NoError(t, diags.Error())