Skip to content

Commit

Permalink
add gcloud auth autologin command
Browse files Browse the repository at this point in the history
  • Loading branch information
gartnera committed Jun 18, 2023
1 parent 9952bb5 commit 4a89115
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 5 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ wget -O - https://github.com/gartnera/gcloud/releases/download/v0.0.7/gcloud_0.0
go install github.com/gartnera/gcloud@latest
```

## Current Commands
## Current Upstream Commands

- `gcloud auth application-default login` (code flow)
- `gcloud auth application-default print-access-token`
Expand All @@ -45,6 +45,10 @@ go install github.com/gartnera/gcloud@latest
- `gcloud container clusters get-credentials`
- `gcloud config config-helper --format=client.authentication.k8s.io/v1` (used by `gcloud container clusters get-credentials`)

## Current Unique Commands

- `gcloud auth autologin` (login only if needed)

## Current Features

- service account impersonation via `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT`
5 changes: 3 additions & 2 deletions auth/application_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ func (m *ApplicationCredentialManager) BrowserFlowLogin(ctx context.Context, quo

func (m *ApplicationCredentialManager) AutoDetectLogin(ctx context.Context, quotaProject string) error {
if detectBrowserAvailable() {
fmt.Println("browser avaliable)")
return m.BrowserFlowLogin(ctx, quotaProject)
}

Expand Down Expand Up @@ -374,6 +373,8 @@ type googleAccountLoginCallback struct {
values chan url.Values
}

const loginCompleteMessage = "<html><head><title>Login complete</title></head><body>Login complete. You can close this page now.</body></html>"

func (cb *googleAccountLoginCallback) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
Expand All @@ -383,7 +384,7 @@ func (cb *googleAccountLoginCallback) ServeHTTP(w http.ResponseWriter, r *http.R
}

cb.values <- r.URL.Query()
_, _ = w.Write([]byte("Login complete, you can close this page now"))
_, _ = w.Write([]byte(loginCompleteMessage))
}

func (cb *googleAccountLoginCallback) wait() (string, error) {
Expand Down
38 changes: 38 additions & 0 deletions auth/autologin_cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package auth

import (
"context"
"fmt"
"net/http"
"time"

"github.com/spf13/cobra"
)

var autoLoginCmd = &cobra.Command{
Use: "autologin",
DisableFlagParsing: true,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

tokenCtx, cancel := context.WithTimeout(ctx, 300*time.Millisecond)
defer cancel()
_, err := TokenCtx(tokenCtx)
if err == nil {
return nil
}

reqCtx, cancel := context.WithTimeout(ctx, 300*time.Millisecond)
defer cancel()
// do nothing if we're not online
req, _ := http.NewRequestWithContext(reqCtx, "GET", "https://connectivitycheck.gstatic.com/generate_204", nil)
_, err = http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("skipping gcloud auth autologin because of connectivity check fail: %w", err)
}

m := EnvApplicationCredentialManager()
return m.AutoDetectLogin(ctx, "")
},
}
3 changes: 2 additions & 1 deletion auth/login_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
)

var loginCmd = &cobra.Command{
Use: "login",
Use: "login",
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

Expand Down
1 change: 1 addition & 0 deletions auth/root_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func GetRootCmd() *cobra.Command {
rootCmd.AddCommand(configureDockerCmd)
rootCmd.AddCommand(dockerHelperCmd)
rootCmd.AddCommand(loginCmd)
rootCmd.AddCommand(autoLoginCmd)

rootCmd.AddCommand(printAccessTokenCmd)
registerConfigHelperCmd(rootCmd)
Expand Down
14 changes: 13 additions & 1 deletion auth/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ func identityTokenToToken(token *identityToken, isIdentity bool) *oauth2.Token {
}
}

func TokenSourceCtx(ctx context.Context) (*CachingTokenSource, error) {
return maybeGetImpersonatedTokenSource(ctx)
}

// TokenSource returns a cached application default credentials or falls back to the compute token source
func TokenSource() (*CachingTokenSource, error) {
return maybeGetImpersonatedTokenSource(context.Background())
return TokenSourceCtx(context.Background())
}

func Token() (*oauth2.Token, error) {
Expand All @@ -67,6 +71,14 @@ func Token() (*oauth2.Token, error) {
return ts.Token()
}

func TokenCtx(ctx context.Context) (*oauth2.Token, error) {
ts, err := TokenSourceCtx(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get token: %w", err)
}
return ts.Token()
}

// easily impersonate a service account and maintain the TokenSource interface
var ImpersonateServiceAccount = ""

Expand Down

0 comments on commit 4a89115

Please sign in to comment.