Skip to content

Commit

Permalink
Refactor admin service config in local app and CLI (#5460)
Browse files Browse the repository at this point in the history
* Refactor admin service config in local app and CLI

* Reload admin config on each client retrieval

* Reload admin config from disk in cmdutil.Helper.Client
  • Loading branch information
begelundmuller authored Aug 19, 2024
1 parent ba7d265 commit dc5c38a
Show file tree
Hide file tree
Showing 18 changed files with 243 additions and 226 deletions.
2 changes: 1 addition & 1 deletion cli/cmd/admin/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func PingCmd(ch *cmdutil.Helper) *cobra.Command {
Short: "Ping",
RunE: func(cmd *cobra.Command, args []string) error {
// Must set here to avoid flag parser overriding it globally
ch.AdminURL = adminURL
ch.AdminURLOverride = adminURL

client, err := ch.Client()
if err != nil {
Expand Down
12 changes: 8 additions & 4 deletions cli/cmd/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func LoginCmd(ch *cmdutil.Helper) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

// updating this as its not required to logout first and login again
// Logout if already logged in
if ch.AdminTokenDefault != "" {
err := Logout(ctx, ch)
if err != nil {
Expand Down Expand Up @@ -51,7 +51,7 @@ func Login(ctx context.Context, ch *cmdutil.Helper, redirectURL string) error {
// In production, the REST and gRPC endpoints are the same, but in development, they're served on different ports.
// We plan to move to connect.build for gRPC, which will allow us to serve both on the same port in development as well.
// Until we make that change, this is a convenient hack for local development (assumes gRPC on port 9090 and REST on port 8080).
authURL := ch.AdminURL
authURL := ch.AdminURL()
if strings.Contains(authURL, "http://localhost:9090") {
authURL = "http://localhost:8080"
}
Expand Down Expand Up @@ -82,8 +82,12 @@ func Login(ctx context.Context, ch *cmdutil.Helper, redirectURL string) error {
if err != nil {
return err
}
// set the default token to the one we just got
ch.AdminTokenDefault = res1.AccessToken

err = ch.ReloadAdminConfig()
if err != nil {
return err
}

ch.PrintfBold("Successfully logged in. Welcome to Rill!\n")
return nil
}
Expand Down
9 changes: 8 additions & 1 deletion cli/cmd/auth/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func LogoutCmd(ch *cmdutil.Helper) *cobra.Command {
}

func Logout(ctx context.Context, ch *cmdutil.Helper) error {
if !ch.IsAuthenticated() {
return nil
}

client, err := ch.Client()
if err != nil {
return err
Expand Down Expand Up @@ -69,7 +73,10 @@ func Logout(ctx context.Context, ch *cmdutil.Helper) error {
return err
}

ch.AdminTokenDefault = ""
err = ch.ReloadAdminConfig()
if err != nil {
return err
}

return nil
}
10 changes: 6 additions & 4 deletions cli/cmd/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ func DeployFlow(ctx context.Context, ch *cmdutil.Helper, opts *Options) error {
}

if localProjectPath != "" {
err = dotrillcloud.SetAll(localProjectPath, ch.AdminURL, &dotrillcloud.Config{
err = dotrillcloud.SetAll(localProjectPath, ch.AdminURL(), &dotrillcloud.Config{
ProjectID: res.Project.Id,
})
if err != nil {
Expand Down Expand Up @@ -440,7 +440,7 @@ func deployWithUploadFlow(ctx context.Context, ch *cmdutil.Helper, opts *Options
return fmt.Errorf("create project failed with error %w", err)
}

err = dotrillcloud.SetAll(localProjectPath, ch.AdminURL, &dotrillcloud.Config{
err = dotrillcloud.SetAll(localProjectPath, ch.AdminURL(), &dotrillcloud.Config{
ProjectID: res.Project.Id,
})
if err != nil {
Expand Down Expand Up @@ -533,16 +533,18 @@ func setDefaultOrg(ctx context.Context, c *client.Client, ch *cmdutil.Helper) er
}

func loginWithTelemetryAndGithubRedirect(ctx context.Context, ch *cmdutil.Helper, remote string) error {
authURL := ch.AdminURL
// NOTE: This is temporary until we migrate to a server that can host HTTP and gRPC on the same port.
authURL := ch.AdminURL()
if strings.Contains(authURL, "http://localhost:9090") {
authURL = "http://localhost:8080"
}

var qry map[string]string
if remote != "" {
qry = map[string]string{"remote": remote}
}

redirectURL, err := urlutil.WithQuery(urlutil.MustJoinURL(authURL, "/github/post-auth-redirect"), qry)
redirectURL, err := urlutil.WithQuery(urlutil.MustJoinURL(authURL, "github", "post-auth-redirect"), qry)
if err != nil {
return err
}
Expand Down
15 changes: 10 additions & 5 deletions cli/cmd/devtool/switch-env.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func SwitchEnvCmd(ch *cmdutil.Helper) *cobra.Command {
return fmt.Errorf("can't switch environment when assuming another user (run `rill sudo user unassume` and try again)")
}

fromEnv, err := adminenv.Infer(ch.AdminURL)
fromEnv, err := adminenv.Infer(ch.AdminURL())
if err != nil {
return err
}
Expand Down Expand Up @@ -78,22 +78,25 @@ func switchEnv(ch *cmdutil.Helper, fromEnv, toEnv string) error {
if err != nil {
return err
}
ch.AdminTokenDefault = toToken // Also set the cfg's token to the one we just got

toURL := adminenv.AdminURL(toEnv)
err = dotrill.SetDefaultAdminURL(toURL)
if err != nil {
return err
}
ch.AdminURL = toURL

err = ch.ReloadAdminConfig()
if err != nil {
return err
}

return nil
}

// switchEnvToDevTemporarily switches the CLI to the "dev" environment (if not already there),
// and then switches it back and returns when the context is cancelled.
func switchEnvToDevTemporarily(ctx context.Context, ch *cmdutil.Helper) {
env, err := adminenv.Infer(ch.AdminURL)
env, err := adminenv.Infer(ch.AdminURL())
if err != nil {
logWarn.Printf("Did not switch CLI to dev environment: failed to infer environment (error: %v)\n", err)
return
Expand Down Expand Up @@ -127,8 +130,10 @@ func switchEnvToDevTemporarily(ctx context.Context, ch *cmdutil.Helper) {
} else {
// Since dev environments are frequently reset, clear the token if it's invalid
_ = dotrill.SetAccessToken("")
_ = ch.ReloadAdminConfig()

_ = dotrill.SetDefaultOrg("")
ch.AdminTokenDefault = ""
ch.Org = ""
}

// Wait for ctx cancellation, then switch back to the previous environment before returning.
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/org/org_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestOrganizationWorkflow(t *testing.T) {
p.OverrideDataOutput(&buf)

helper := &cmdutil.Helper{
AdminURL: "http://localhost:9090",
AdminURLDefault: "http://localhost:9090",
AdminTokenDefault: adminAuthToken.Token().String(),
Printer: p,
}
Expand Down
11 changes: 3 additions & 8 deletions cli/cmd/project/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,12 @@ func DeleteCmd(ch *cmdutil.Helper) *cobra.Command {
return err
}

var deployedID string
rc, err := dotrillcloud.GetAll(path, ch.AdminURL)
rc, err := dotrillcloud.GetAll(path, ch.AdminURL())
if err != nil {
return err
}
if rc != nil {
deployedID = rc.ProjectID
}

if delResp.Id == deployedID {
err = dotrillcloud.Delete(path, ch.AdminURL)
if rc != nil && rc.ProjectID == delResp.Id {
err = dotrillcloud.Delete(path, ch.AdminURL())
if err != nil {
return err
}
Expand Down
39 changes: 12 additions & 27 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ func init() {
cobra.EnableCommandSorting = false
}

// defaultAdminURL is the default admin server URL.
// Users can override it with the "--api-url" flag or by setting "api-url" in ~/.rill/config.yaml.
const defaultAdminURL = "https://admin.rilldata.com"

// rootCmd represents the base command when called without any subcommands.
var rootCmd = &cobra.Command{
Use: "rill <command>",
Expand Down Expand Up @@ -76,37 +72,26 @@ func Execute(ctx context.Context, ver cmdutil.Version) {
}

func runCmd(ctx context.Context, ver cmdutil.Version) error {
// Load admin token from .rill (may later be overridden by flag --api-token)
adminTokenDefault, err := dotrill.GetAccessToken()
if err != nil {
return fmt.Errorf("could not parse access token from ~/.rill: %w", err)
// Create cmdutil Helper
ch := &cmdutil.Helper{
Printer: printer.NewPrinter(printer.FormatHuman),
Version: ver,
Interactive: true,
}
defer ch.Close()

// Load admin URL from .rill (override with --api-url)
adminURL, err := dotrill.GetDefaultAdminURL()
// Load base admin config from ~/.rill
err := ch.ReloadAdminConfig()
if err != nil {
return fmt.Errorf("could not parse default api URL from ~/.rill: %w", err)
}
if adminURL == "" {
adminURL = defaultAdminURL
return err
}

// Load default org from .rill
// Load default org
defaultOrg, err := dotrill.GetDefaultOrg()
if err != nil {
return fmt.Errorf("could not parse default org from ~/.rill: %w", err)
}

// Create cmdutil Helper
ch := &cmdutil.Helper{
Printer: printer.NewPrinter(printer.FormatHuman),
Version: ver,
AdminURL: adminURL,
AdminTokenDefault: adminTokenDefault,
Org: defaultOrg,
Interactive: true,
}
defer ch.Close()
ch.Org = defaultOrg

// Check version
err = update.CheckVersion(ctx, ver.Number)
Expand All @@ -132,7 +117,7 @@ func runCmd(ctx context.Context, ver cmdutil.Version) error {
rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") // Overrides message for help
rootCmd.PersistentFlags().BoolVar(&ch.Interactive, "interactive", true, "Prompt for missing required parameters")
rootCmd.PersistentFlags().Var(&ch.Printer.Format, "format", `Output format (options: "human", "json", "csv")`)
rootCmd.PersistentFlags().StringVar(&ch.AdminURL, "api-url", ch.AdminURL, "Base URL for the cloud API")
rootCmd.PersistentFlags().StringVar(&ch.AdminURLOverride, "api-url", ch.AdminURLOverride, "Base URL for the cloud API")
if !ch.IsDev() {
if err := rootCmd.PersistentFlags().MarkHidden("api-url"); err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestServiceWorkflow(t *testing.T) {
p.OverrideDataOutput(&buf)

helper := &cmdutil.Helper{
AdminURL: "http://localhost:9090",
AdminURLDefault: "http://localhost:9090",
AdminTokenDefault: adminAuthToken.Token().String(),
Org: "myorg",
Printer: p,
Expand Down
6 changes: 1 addition & 5 deletions cli/cmd/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func StartCmd(ch *cmdutil.Helper) *cobra.Command {
allowedOrigins = append(allowedOrigins, localURL)

app, err := local.NewApp(cmd.Context(), &local.AppOptions{
Version: ch.Version,
Ch: ch,
Verbose: verbose,
Debug: debug,
Reset: reset,
Expand All @@ -158,10 +158,6 @@ func StartCmd(ch *cmdutil.Helper) *cobra.Command {
ProjectPath: projectPath,
LogFormat: parsedLogFormat,
Variables: varsMap,
Activity: ch.Telemetry(cmd.Context()),
AdminURL: ch.AdminURL,
AdminToken: ch.AdminToken(),
CMDHelper: ch,
LocalURL: localURL,
AllowedOrigins: allowedOrigins,
})
Expand Down
7 changes: 5 additions & 2 deletions cli/cmd/sudo/user/assume.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ func AssumeCmd(ch *cmdutil.Helper) *cobra.Command {
return err
}

// set the default token to the one we just got
ch.AdminTokenDefault = res.Token
// Load new token
err = ch.ReloadAdminConfig()
if err != nil {
return err
}

// Select org for new user
err = auth.SelectOrgFlow(ctx, ch, true)
Expand Down
7 changes: 4 additions & 3 deletions cli/cmd/sudo/user/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@ func OpenCmd(ch *cmdutil.Helper) *cobra.Command {
Args: cobra.NoArgs,
Short: "Open browser as the current user",
RunE: func(cmd *cobra.Command, args []string) error {
authURL := ch.AdminURL
// NOTE: This is temporary until we migrate to a server that can host HTTP and gRPC on the same port.
authURL := ch.AdminURL()
if strings.Contains(authURL, "http://localhost:9090") {
authURL = "http://localhost:8080"
}

withTokenURI, err := url.JoinPath(authURL, "auth/with-token")
withTokenURI, err := url.JoinPath(authURL, "auth", "with-token")
if err != nil {
return err
}

qry := map[string]string{"token": ch.AdminTokenDefault}
qry := map[string]string{"token": ch.AdminToken()}
withTokenURL, err := urlutil.WithQuery(withTokenURI, qry)
if err != nil {
return err
Expand Down
14 changes: 10 additions & 4 deletions cli/cmd/sudo/user/unassume.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ func UnassumeCmd(ch *cmdutil.Helper) *cobra.Command {
return err
}

// Fetch the original token
originalToken, err := dotrill.GetBackupToken()
if err != nil {
return err
}

if originalToken == "" {
return fmt.Errorf("Original token is not available, you are not assuming any user")
}

// Revoke current token if have original token
// Revoke current token
_, err = client.RevokeCurrentAuthToken(ctx, &adminv1.RevokeCurrentAuthTokenRequest{})
if err != nil {
fmt.Printf("Failed to revoke token (it may have expired). Clearing local token anyway.\n")
}

// Restore the original token as the access token
err = dotrill.SetAccessToken(originalToken)
if err != nil {
return err
}
ch.AdminTokenDefault = originalToken

// Set original_token as empty
// Clear backup token
err = dotrill.SetBackupToken("")
if err != nil {
return err
Expand All @@ -56,6 +56,12 @@ func UnassumeCmd(ch *cmdutil.Helper) *cobra.Command {
return err
}

// Reload access tokens
err = ch.ReloadAdminConfig()
if err != nil {
return err
}

// Select org again for original user
err = auth.SelectOrgFlow(ctx, ch, true)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/user/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestUserWorkflow(t *testing.T) {
p := printer.NewPrinter(printer.FormatHuman)
p.OverrideDataOutput(&buf)
helper := &cmdutil.Helper{
AdminURL: "http://localhost:9090",
AdminURLDefault: "http://localhost:9090",
AdminTokenDefault: adminAuthToken.Token().String(),
Printer: p,
}
Expand Down
Loading

0 comments on commit dc5c38a

Please sign in to comment.