Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show actionable errors for collaborative deployment scenarios #1386

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

lennartkats-db
Copy link
Contributor

Changes

This adds diagnostics for collaborative (production) deployment scenarios, including:

  • Bob deploys a bundle that is normally deployed by Alice, but this fails because Bob can't write to /Users/Alice/.bundle.
  • Charlie deploys a bundle that is normally deployed by Alice, but this fails because he can't create a new pipeline where Alice would be the owner.
  • Alice deploys a bundle where she didn't list herself as one of the CAN_MANAGE users in permissions. That can work, but is probably a mistake.

Tests

Unit tests, manual testing.

@codecov-commenter
Copy link

codecov-commenter commented Jun 2, 2024

Codecov Report

Attention: Patch coverage is 75.56818% with 43 lines in your changes are missing coverage. Please review.

Project coverage is 53.75%. Comparing base (e22dd8a) to head (0b9feab).
Report is 125 commits behind head on main.

Files Patch % Lines
bundle/permissions/permission_diagnostics.go 87.60% 11 Missing and 4 partials ⚠️
libs/filer/workspace_files_client.go 0.00% 14 Missing ⚠️
bundle/config/mutator/run_as.go 81.81% 6 Missing ⚠️
bundle/deploy/terraform/apply.go 0.00% 4 Missing ⚠️
libs/filer/filer.go 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1386      +/-   ##
==========================================
+ Coverage   52.25%   53.75%   +1.50%     
==========================================
  Files         317      352      +35     
  Lines       18004    20410    +2406     
==========================================
+ Hits         9408    10972    +1564     
- Misses       7903     8636     +733     
- Partials      693      802     +109     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lennartkats-db lennartkats-db changed the title [WIP] Show better errors for collaborative deployment scenarios Show better errors for collaborative deployment scenarios Jun 3, 2024
@lennartkats-db lennartkats-db changed the title Show better errors for collaborative deployment scenarios Show actionable errors for collaborative deployment scenarios Jun 3, 2024
return diag.Errorf("cannot write to deployment root (this can indicate a previous deploy was done with a different identity): %s", b.Config.Workspace.RootPath)
permissionError := filer.PermissionError{}
if errors.As(err, &permissionError) {
return permissions.ReportPermissionDenied(ctx, b, b.Config.Workspace.StatePath)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filer now returns a proper PermissionError, simplifying things. And ReportPermissionDenied just adds a bit more context to the error about how to resolve it.

bundle/config/mutator/run_as.go Show resolved Hide resolved
b.Config.GetLocation("resources.quality_monitors"),
b.Config.Workspace.CurrentUser.UserName,
identity,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These diagnostics can be accumulated and returned together. In the (unlikely) scenario a user has defined a model serving endpoint and a quality monitor, they'll only see the error for their model serving endpoint and not the others.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. This is old code but I'll clean it up.

bundle/config/mutator/run_as.go Show resolved Hide resolved
Validate() error

json.Marshaler
json.Unmarshaler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just the campsite rule. Both of already exist in all struct implementing this interface; I'm just making them explicit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, these are superfluous here. They implement this interface by embedding the Go SDK structs, but that is not what we need. See TestCustomMarshallerIsImplemented.

bundle/deploy/files/upload.go Show resolved Hide resolved
libs/diag/diagnostic.go Outdated Show resolved Hide resolved
libs/diag/diagnostic.go Show resolved Hide resolved
libs/diag/id.go Show resolved Hide resolved
libs/filer/filer.go Show resolved Hide resolved
if errors.As(err, &notExistsError) {
// If we still get a 404 error after the succesful mkdir,
// the problem is a permission error.
return PermissionError{absPath}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you observe this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. This is the case where you the dir exists and you have 'view' access but not 'write' access. We previously couldn't recognize this case as a permission error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need integration test coverage for this.

Let's figure out a way to do so, because we don't have any tests that use multiple identities at the moment, and we'll need that in order to test this branch (setup the tree to trigger this path).

Same holds for the permission checks in the rest of this PR. Without integration test coverage we can't guarantee continuity, or even that the assertions made continue to hold.

@lennartkats-db lennartkats-db force-pushed the cp-better-errors branch 2 times, most recently from 8d26485 to 16b80ea Compare July 6, 2024 19:37
@lennartkats-db
Copy link
Contributor Author

@pietern could you take another look?

Validate() error

json.Marshaler
json.Unmarshaler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, these are superfluous here. They implement this interface by embedding the Go SDK structs, but that is not what we need. See TestCustomMarshallerIsImplemented.


func (m *reportPermissionErrors) Name() string {
return "CheckPermissions"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consolidate the naming.

// - assistance: advice on who to contact as to manage this project
func analyzeBundlePermissions(b *bundle.Bundle) (bool, string) {
canManageBundle := false
otherManagers := make(map[string]bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a set; you can use struct{} as value type or libs/set. The bool doesn't do anything.

var managersSlice []string
for manager := range otherManagers {
managersSlice = append(managersSlice, manager)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping.


assistance := "For assistance, contact the owners of this project."
if len(managersSlice) > 0 {
assistance = fmt.Sprintf("For assistance, users or groups with appropriate permissions may include: %s.", strings.Join(managersSlice, ", "))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping.

}

func ReportPermissionDenied(ctx context.Context, b *bundle.Bundle, path string) diag.Diagnostics {
log.Errorf(ctx, "Failed to update %v", path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping. If this is not the case, please include a comment stating why this log statement shouldn't be removed.

assert.EqualError(t, err, fmt.Sprintf("pipelines are not supported when the current deployment user is different from the bundle's run_as identity. Please deploy as the run_as identity. Please refer to the documentation at https://docs.databricks.com/dev-tools/bundles/run-as.html for more details. Location of the unsupported resource: %s:14:5. Current identity: [email protected]. Run as identity: my_service_principal", configPath))
assert.ErrorContains(t, err, "pipelines do not support a setting a run_as user that is different from the owner.\n"+
"Current identity: [email protected]. Run as identity: my_service_principal.\n"+
"See https://docs", configPath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configPath is no longer used.

if errors.As(err, &notExistsError) {
// If we still get a 404 error after the succesful mkdir,
// the problem is a permission error.
return PermissionError{absPath}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need integration test coverage for this.

Let's figure out a way to do so, because we don't have any tests that use multiple identities at the moment, and we'll need that in order to test this branch (setup the tree to trigger this path).

Same holds for the permission checks in the rest of this PR. Without integration test coverage we can't guarantee continuity, or even that the assertions made continue to hold.

@pietern
Copy link
Contributor

pietern commented Jul 15, 2024

@shreyas-goenka Can you take a pass as this as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants