This commit is contained in:
Lennart Kats 2025-01-13 10:56:43 +01:00
parent f8f804fe17
commit b2fa0d83d3
No known key found for this signature in database
GPG Key ID: 1EB8B57673197023
2 changed files with 38 additions and 4 deletions

View File

@ -2,10 +2,12 @@ package mutator
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config" "github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/diag" "github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/iamutil" "github.com/databricks/cli/libs/iamutil"
@ -146,8 +148,39 @@ func validateProductionMode(ctx context.Context, b *bundle.Bundle, isPrincipalUs
} }
} }
if !isPrincipalUsed && !isRunAsSet(r) { // We need to verify that there is only a single deployment of the current target.
return diag.Errorf("'run_as' must be set for all jobs when using 'mode: production'") // The best way to enforce this is to explicitly set root_path.
advice := "set 'workspace.root_path' to make sure only one copy is deployed"
adviceDetail := fmt.Sprintf(
"A common practice is to use a username or principal name in this path, i.e. use\n"+
"\n"+
" root_path: /Workspace/Users/%s/.bundle/${bundle.name}/${bundle.target}",
b.Config.Workspace.CurrentUser.UserName,
)
if !isExplicitRootSet(b) {
cmdio.LogString(ctx, fmt.Sprintf("root_path is not set: %s", b.Config.Bundle.Target))
if isRunAsSet(r) || isPrincipalUsed {
// Just setting run_as is not enough to guarantee a single deployment,
// and neither is setting a principal.
// We only show a warning for these cases since we didn't historically
// report an error for them.
return diag.Diagnostics{
{
Severity: diag.Recommendation,
Summary: "target with 'mode: production' should " + advice,
Detail: adviceDetail,
Locations: b.Config.GetLocations("targets." + b.Config.Bundle.Target),
},
}
}
return diag.Diagnostics{
{
Severity: diag.Error,
Summary: "target with 'mode: production' must " + advice,
Detail: adviceDetail,
Locations: b.Config.GetLocations("targets." + b.Config.Bundle.Target),
},
}
} }
return nil return nil
} }

View File

@ -321,7 +321,8 @@ 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(), "run_as") assert.ErrorContains(t, diags.Error(), "A common practice is to use a username or principal name in this path, i.e. use\n\n root_path: /Workspace/Users/lennart@company.com/.bundle/${bundle.name}/${bundle.target}")
assert.NotNil(t, diags[0].Locations)
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"
@ -329,7 +330,7 @@ func TestProcessTargetModeProduction(t *testing.T) {
b.Config.Workspace.ResourcePath = "/Shared/.bundle/x/y/resources" b.Config.Workspace.ResourcePath = "/Shared/.bundle/x/y/resources"
diags = validateProductionMode(context.Background(), b, false) diags = validateProductionMode(context.Background(), b, false)
require.ErrorContains(t, diags.Error(), "production") assert.ErrorContains(t, diags.Error(), "A common practice is to use a username or principal name in this path, i.e. use\n\n root_path: /Workspace/Users/lennart@company.com/.bundle/${bundle.name}/${bundle.target}")
permissions := []resources.Permission{ permissions := []resources.Permission{
{ {