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

ACLs: Modify superuser command and add migrate flow #8087

Merged
merged 7 commits into from
Aug 20, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/esti.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ jobs:
fi

run-system-aws-s3-basic-auth:
name: Run latest lakeFS app on AWS S3
name: Run latest lakeFS app on AWS S3 + Basic Auth
needs: [deploy-image, login-to-amazon-ecr]
runs-on: ubuntu-22.04
env:
Expand Down
35 changes: 33 additions & 2 deletions cmd/lakefs/cmd/superuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import (
var superuserCmd = &cobra.Command{
Use: "superuser",
Short: "Create additional user with admin credentials",
Long: `Create additional user with admin credentials.
This command can be used to import an admin user when moving from lakeFS version
with previously configured users to a lakeFS with basic auth version.
To do that provide the user name as well as the access key ID to import.
If the wrong user or credentials were chosen it is possible to delete the user and perform the action again.
`,
Run: func(cmd *cobra.Command, args []string) {
cfg := loadConfig()
if cfg.Auth.UIConfig.RBAC == config.AuthRBACExternal {
Expand Down Expand Up @@ -60,7 +66,32 @@ var superuserCmd = &cobra.Command{
fmt.Printf("Failed to open KV store: %s\n", err)
os.Exit(1)
}
authService := acl.NewAuthService(kvStore, crypt.NewSecretStore([]byte(cfg.Auth.Encrypt.SecretKey)), authparams.ServiceCache(cfg.Auth.Cache))

var authService auth.Service
secretStore := crypt.NewSecretStore([]byte(cfg.Auth.Encrypt.SecretKey))
authLogger := logger.WithField("service", "auth_api")
addToAdmins := true
switch {
case cfg.IsAuthBasic():
authService = auth.NewBasicAuthService(kvStore, secretStore, authparams.ServiceCache(cfg.Auth.Cache), authLogger)
addToAdmins = false
case cfg.IsAuthUISimplified() && cfg.IsAuthenticationTypeAPI(): // ACL server
authService, err = auth.NewAPIAuthService(
cfg.Auth.API.Endpoint,
cfg.Auth.API.Token.SecureValue(),
cfg.Auth.AuthenticationAPI.ExternalPrincipalsEnabled,
secretStore,
authparams.ServiceCache(cfg.Auth.Cache),
authLogger)
if err != nil {
fmt.Printf("Failed to initialize auth service: %s\n", err)
os.Exit(1)
}
// TODO (niro): This needs to be removed
default:
authService = acl.NewAuthService(kvStore, secretStore, authparams.ServiceCache(cfg.Auth.Cache))
}

authMetadataManager := auth.NewKVMetadataManager(version.Version, cfg.Installation.FixedID, cfg.Database.Type, kvStore)

metadataProvider := stats.BuildMetadataProvider(logger, cfg)
Expand All @@ -72,7 +103,7 @@ var superuserCmd = &cobra.Command{
},
AccessKeyID: accessKeyID,
SecretAccessKey: secretAccessKey,
}, true)
}, addToAdmins)
if err != nil {
fmt.Printf("Failed to setup admin user: %s\n", err)
os.Exit(1)
Expand Down
2 changes: 1 addition & 1 deletion contrib/auth/acl/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (s *AuthService) ListUserCredentials(ctx context.Context, username string,
if err != nil {
return nil, nil, err
}
creds, err := model.ConvertCredDataList(s.secretStore, msgs)
creds, err := model.ConvertCredDataList(s.secretStore, msgs, false)
if err != nil {
return nil, nil, err
}
Expand Down
23 changes: 23 additions & 0 deletions esti/golden/lakefs/help.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
lakeFS is a data lake management platform

Usage:
lakefs [command]

Available Commands:
completion Generate completion script
flare collect configuration, environment variables, and logs for debugging and troubleshooting
help Help about any command
migrate Manage migrations
run Run lakeFS
setup Setup a new lakeFS instance with initial credentials
superuser Create additional user with admin credentials

Flags:
-c, --config string config file (default is $HOME/.lakefs.yaml)
-h, --help help for lakefs
--local-settings Use lakeFS local default configuration
--quickstart Use lakeFS quickstart configuration
-t, --toggle Help message for toggle
-v, --version version for lakefs

Use "lakefs [command] --help" for more information about a command.
7 changes: 2 additions & 5 deletions esti/lakectl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,9 @@ func TestLakectlAuthUsers(t *testing.T) {
"ID": userName,
}
isSupported := !isBasicAuth()
expected := "Not implemented\n501 Not Implemented\n"
if isSupported {
expected = "user not found\n404 Not Found\n"
}

// Not Found
RunCmdAndVerifyFailure(t, Lakectl()+" auth users delete --id "+userName, false, expected, vars)
RunCmdAndVerifyFailure(t, Lakectl()+" auth users delete --id "+userName, false, "user not found\n404 Not Found\n", vars)

// Check unique
if isSupported {
Expand All @@ -427,6 +423,7 @@ func TestLakectlAuthUsers(t *testing.T) {
RunCmdAndVerifyFailure(t, Lakectl()+" auth users create --id "+userName, false, "Already exists\n409 Conflict\n", vars)

// Cleanup
expected := "user not found\n404 Not Found\n"
if isSupported {
expected = "User deleted successfully\n"
}
Expand Down
14 changes: 13 additions & 1 deletion esti/lakectl_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ var (
rePhysicalAddress = regexp.MustCompile(`/data/[0-9a-v]{20}/(?:[0-9a-v]{20}(?:,.+)?)?`)
reVariable = regexp.MustCompile(`\$\{([^${}]+)}`)
rePreSignURL = regexp.MustCompile(`https://\S+\?\S+`)
reSecretAccessKey = regexp.MustCompile(`secret_access_key: \S{16,128}`)
reAccessKeyID = regexp.MustCompile(`access_key_id: AKIA\S{12,124}`)
)

func lakectlLocation() string {
return viper.GetString("lakectl_dir") + "/lakectl"
return viper.GetString("binaries_dir") + "/lakectl"
}

func LakectlWithParams(accessKeyID, secretAccessKey, endPointURL string) string {
Expand Down Expand Up @@ -145,6 +147,8 @@ func sanitize(output string, vars map[string]string) string {
s = normalizeCommitID(s)
s = normalizeChecksum(s)
s = normalizeShortCommitID(s)
s = normalizeAccessKeyID(s)
s = normalizeSecretAccessKey(s)
return s
}

Expand Down Expand Up @@ -267,3 +271,11 @@ func normalizeEndpoint(output string, endpoint string) string {
func normalizePreSignURL(output string) string {
return rePreSignURL.ReplaceAllString(output, "<PRE_SIGN_URL>")
}

func normalizeAccessKeyID(output string) string {
return reAccessKeyID.ReplaceAllString(output, "access_key_id: <ACCESS_KEY_ID>")
}

func normalizeSecretAccessKey(output string) string {
return reSecretAccessKey.ReplaceAllString(output, "secret_access_key: <SECRET_ACCESS_KEY>")
}
34 changes: 34 additions & 0 deletions esti/lakefs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package esti

import "testing"

func TestLakefsHelp(t *testing.T) {
RunCmdAndVerifySuccessWithFile(t, Lakefs(), false, "lakefs/help", emptyVars)
RunCmdAndVerifySuccessWithFile(t, Lakefs()+" --help", false, "lakefs/help", emptyVars)
RunCmdAndVerifySuccessWithFile(t, Lakefs(), true, "lakefs/help", emptyVars)
RunCmdAndVerifySuccessWithFile(t, Lakefs()+" --help", true, "lakefs/help", emptyVars)
}

func TestLakefsSuperuser_basic(t *testing.T) {
RequirePostgresDB(t)
lakefsCmd := Lakefs()
outputString := "credentials:\n access_key_id: <ACCESS_KEY_ID>\n secret_access_key: <SECRET_ACCESS_KEY>\n"
username := t.Name()
expectFailure := false
if isBasicAuth() {
lakefsCmd = LakefsWithBasicAuth()
outputString = "already exists"
expectFailure = true
}
runCmdAndVerifyContainsText(t, lakefsCmd+" superuser --user-name "+username, expectFailure, false, outputString, nil)
}

func TestLakefsSuperuser_alreadyExists(t *testing.T) {
RequirePostgresDB(t)
lakefsCmd := Lakefs()
if isBasicAuth() {
lakefsCmd = LakefsWithBasicAuth()
}
// On init - the AdminUsername is already created and expected error should be "already exist" (also in basic auth mode)
RunCmdAndVerifyFailureContainsText(t, lakefsCmd+" superuser --user-name "+AdminUsername, false, "already exists", nil)
}
41 changes: 41 additions & 0 deletions esti/lakefs_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package esti

import (
"strconv"
"testing"

"github.com/spf13/viper"
)

func LakefsWithParams(connectionString string) string {
return LakefsWithParamsWithBasicAuth(connectionString, false)
}

func LakefsWithParamsWithBasicAuth(connectionString string, basicAuth bool) string {
lakefsCmdline := "LAKEFS_DATABASE_TYPE=postgres" +
" LAKEFS_DATABASE_POSTGRES_CONNECTION_STRING=" + connectionString +
" LAKEFS_AUTH_INTERNAL_BASIC=" + strconv.FormatBool(basicAuth) +
" LAKEFS_BLOCKSTORE_TYPE=" + viper.GetString("blockstore_type") +
" LAKEFS_AUTH_ENCRYPT_SECRET_KEY='some random secret string' " + lakefsLocation()

return lakefsCmdline
}

func lakefsLocation() string {
return viper.GetString("binaries_dir") + "/lakefs"
}

func LakefsWithBasicAuth() string {
return LakefsWithParamsWithBasicAuth(viper.GetString("database_connection_string"), true)
}

func Lakefs() string {
return LakefsWithParams(viper.GetString("database_connection_string"))
}

func RequirePostgresDB(t *testing.T) {
dbString := viper.GetString("database_connection_string")
if dbString == "" {
t.Skip("skip test - not postgres")
}
}
3 changes: 2 additions & 1 deletion esti/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
const (
DefaultAdminAccessKeyID = "AKIAIOSFDNN7EXAMPLEQ"
DefaultAdminSecretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
AdminUsername = "esti"
)

type (
Expand Down Expand Up @@ -234,7 +235,7 @@ func TestMain(m *testing.M) {
}

params := testutil.SetupTestingEnvParams{
Name: "esti",
Name: AdminUsername,
StorageNS: "esti-system-testing",
}

Expand Down
2 changes: 1 addition & 1 deletion esti/ops/docker-compose-acl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ services:
- ESTI_SETUP_LAKEFS
- ESTI_AWS_SECRET_ACCESS_KEY
- ESTI_ENDPOINT_URL=http://lakefs:8000
- ESTI_LAKECTL_DIR=/app
- ESTI_BINARIES_DIR=/app
- ESTI_DATABASE_CONNECTION_STRING=postgres://lakefs:lakefs@postgres/postgres?sslmode=disable
- ESTI_GOTEST_FLAGS
- ESTI_FLAGS
Expand Down
2 changes: 1 addition & 1 deletion esti/ops/docker-compose-dynamodb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ services:
- ESTI_SETUP_LAKEFS
- ESTI_AWS_SECRET_ACCESS_KEY
- ESTI_ENDPOINT_URL=http://lakefs:8000
- ESTI_LAKECTL_DIR=/app
- ESTI_BINARIES_DIR=/app
- ESTI_DATABASE_KV_ENABLED
- ESTI_KV_MIGRATION=${ESTI_KV_MIGRATION:-none}
- ESTI_POST_MIGRATE
Expand Down
2 changes: 1 addition & 1 deletion esti/ops/docker-compose-external-db.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ services:
- ESTI_SETUP_LAKEFS
- ESTI_AWS_SECRET_ACCESS_KEY
- ESTI_ENDPOINT_URL=http://lakefs:8000
- ESTI_LAKECTL_DIR=/app
- ESTI_BINARIES_DIR=/app
- ESTI_GOTEST_FLAGS
- ESTI_FLAGS
- ESTI_LARGE_OBJECT_PATH
Expand Down
2 changes: 1 addition & 1 deletion esti/ops/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ services:
- ESTI_SETUP_LAKEFS
- ESTI_AWS_SECRET_ACCESS_KEY
- ESTI_ENDPOINT_URL=http://lakefs:8000
- ESTI_LAKECTL_DIR=/app
- ESTI_BINARIES_DIR=/app
- ESTI_DATABASE_CONNECTION_STRING=postgres://lakefs:lakefs@postgres/postgres?sslmode=disable
- ESTI_GOTEST_FLAGS
- ESTI_FLAGS
Expand Down
Loading
Loading