mirror of https://github.com/databricks/cli.git
Use the friendly name of service principals when shortening their name (#1770)
## Summary Use the friendly name of service principals when shortening their name. This change is helpful for the prefix in development mode. Instead of adding a prefix like `[dev 1706906c-c0a2-4c25-9f57-3a7aa3cb8123]`, we'll prefix like `[dev my_principal]`.
This commit is contained in:
parent
f2dee890b8
commit
e220f9ddd6
|
@ -33,7 +33,7 @@ func (m *populateCurrentUser) Apply(ctx context.Context, b *bundle.Bundle) diag.
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Config.Workspace.CurrentUser = &config.User{
|
b.Config.Workspace.CurrentUser = &config.User{
|
||||||
ShortName: auth.GetShortUserName(me.UserName),
|
ShortName: auth.GetShortUserName(me),
|
||||||
User: me,
|
User: me,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ func TestAccBundleInitHelpers(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
funcName: "{{short_name}}",
|
funcName: "{{short_name}}",
|
||||||
expected: auth.GetShortUserName(me.UserName),
|
expected: auth.GetShortUserName(me),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
funcName: "{{user_name}}",
|
funcName: "{{user_name}}",
|
||||||
|
|
|
@ -4,12 +4,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/databricks/cli/libs/textutil"
|
"github.com/databricks/cli/libs/textutil"
|
||||||
|
"github.com/databricks/databricks-sdk-go/service/iam"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get a short-form username, based on the user's primary email address.
|
// Get a short-form username, based on the user's primary email address.
|
||||||
// We leave the full range of unicode letters in tact, but remove all "special" characters,
|
// We leave the full range of unicode letters in tact, but remove all "special" characters,
|
||||||
// including dots, which are not supported in e.g. experiment names.
|
// including dots, which are not supported in e.g. experiment names.
|
||||||
func GetShortUserName(emailAddress string) string {
|
func GetShortUserName(user *iam.User) string {
|
||||||
local, _, _ := strings.Cut(emailAddress, "@")
|
name := user.UserName
|
||||||
|
if IsServicePrincipal(user.UserName) && user.DisplayName != "" {
|
||||||
|
name = user.DisplayName
|
||||||
|
}
|
||||||
|
local, _, _ := strings.Cut(name, "@")
|
||||||
return textutil.NormalizeString(local)
|
return textutil.NormalizeString(local)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,70 +3,111 @@ package auth
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/databricks/databricks-sdk-go/service/iam"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetShortUserName(t *testing.T) {
|
func TestGetShortUserName(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
email string
|
user *iam.User
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
email: "test.user.1234@example.com",
|
user: &iam.User{
|
||||||
|
UserName: "test.user.1234@example.com",
|
||||||
|
},
|
||||||
expected: "test_user_1234",
|
expected: "test_user_1234",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: "tést.üser@example.com",
|
user: &iam.User{
|
||||||
|
UserName: "tést.üser@example.com",
|
||||||
|
},
|
||||||
expected: "tést_üser",
|
expected: "tést_üser",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: "test$.user@example.com",
|
user: &iam.User{
|
||||||
|
UserName: "test$.user@example.com",
|
||||||
|
},
|
||||||
expected: "test_user",
|
expected: "test_user",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `jöhn.dœ@domain.com`, // Using non-ASCII characters.
|
user: &iam.User{
|
||||||
|
UserName: `jöhn.dœ@domain.com`, // Using non-ASCII characters.
|
||||||
|
},
|
||||||
expected: "jöhn_dœ",
|
expected: "jöhn_dœ",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `first+tag@email.com`, // The plus (+) sign is used for "sub-addressing" in some email services.
|
user: &iam.User{
|
||||||
|
UserName: `first+tag@email.com`, // The plus (+) sign is used for "sub-addressing" in some email services.
|
||||||
|
},
|
||||||
expected: "first_tag",
|
expected: "first_tag",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `email@sub.domain.com`, // Using a sub-domain.
|
user: &iam.User{
|
||||||
|
UserName: `email@sub.domain.com`, // Using a sub-domain.
|
||||||
|
},
|
||||||
expected: "email",
|
expected: "email",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `"_quoted"@domain.com`, // Quoted strings can be part of the local-part.
|
user: &iam.User{
|
||||||
|
UserName: `"_quoted"@domain.com`, // Quoted strings can be part of the local-part.
|
||||||
|
},
|
||||||
expected: "quoted",
|
expected: "quoted",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `name-o'mally@website.org`, // Single quote in the local-part.
|
user: &iam.User{
|
||||||
|
UserName: `name-o'mally@website.org`, // Single quote in the local-part.
|
||||||
|
},
|
||||||
expected: "name_o_mally",
|
expected: "name_o_mally",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `user%domain@external.com`, // Percent sign can be used for email routing in legacy systems.
|
user: &iam.User{
|
||||||
|
UserName: `user%domain@external.com`, // Percent sign can be used for email routing in legacy systems.
|
||||||
|
},
|
||||||
expected: "user_domain",
|
expected: "user_domain",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `long.name.with.dots@domain.net`, // Multiple dots in the local-part.
|
user: &iam.User{
|
||||||
|
UserName: `long.name.with.dots@domain.net`, // Multiple dots in the local-part.
|
||||||
|
},
|
||||||
expected: "long_name_with_dots",
|
expected: "long_name_with_dots",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `me&you@together.com`, // Using an ampersand (&) in the local-part.
|
user: &iam.User{
|
||||||
|
UserName: `me&you@together.com`, // Using an ampersand (&) in the local-part.
|
||||||
|
},
|
||||||
expected: "me_you",
|
expected: "me_you",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `user!def!xyz@domain.org`, // The exclamation mark can be valid in some legacy systems.
|
user: &iam.User{
|
||||||
|
UserName: `user!def!xyz@domain.org`, // The exclamation mark can be valid in some legacy systems.
|
||||||
|
},
|
||||||
expected: "user_def_xyz",
|
expected: "user_def_xyz",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: `admin@ιντερνετ.com`, // Domain in non-ASCII characters (IDN or Internationalized Domain Name).
|
user: &iam.User{
|
||||||
|
UserName: `admin@ιντερνετ.com`, // Domain in non-ASCII characters (IDN or Internationalized Domain Name).
|
||||||
|
},
|
||||||
expected: "admin",
|
expected: "admin",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
user: &iam.User{
|
||||||
|
UserName: `1706906c-c0a2-4c25-9f57-3a7aa3cb8123`,
|
||||||
|
DisplayName: "my-service-principal",
|
||||||
|
},
|
||||||
|
expected: "my_service_principal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
user: &iam.User{
|
||||||
|
UserName: `1706906c-c0a2-4c25-9f57-3a7aa3cb8123`,
|
||||||
|
// This service princpal has DisplayName (it's an optional property)
|
||||||
|
},
|
||||||
|
expected: "1706906c_c0a2_4c25_9f57_3a7aa3cb8123",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
assert.Equal(t, tt.expected, GetShortUserName(tt.email))
|
assert.Equal(t, tt.expected, GetShortUserName(tt.user))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ func loadHelpers(ctx context.Context) template.FuncMap {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return auth.GetShortUserName(cachedUser.UserName), nil
|
return auth.GetShortUserName(cachedUser), nil
|
||||||
},
|
},
|
||||||
// Get the default workspace catalog. If there is no default, or if
|
// Get the default workspace catalog. If there is no default, or if
|
||||||
// Unity Catalog is not enabled, return an empty string.
|
// Unity Catalog is not enabled, return an empty string.
|
||||||
|
|
Loading…
Reference in New Issue