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

Switch shell / connect to use caching_sha2_password by default #919

Merged
merged 1 commit into from
Oct 9, 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 Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.23.1 as build
FROM golang:1.23.2 as build
WORKDIR /app
COPY . .

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ endif
REPO=planetscale
NAME=pscale
BUILD_PKG=github.com/planetscale/cli/cmd/pscale
GORELEASE_CROSS_VERSION ?= v1.23.1
GORELEASE_CROSS_VERSION ?= v1.23.2
SYFT_VERSION ?= 1.9.0

.PHONY: all
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '2'

services:
app:
image: golang:1.23.1
image: golang:1.23.2
volumes:
- .:/work
working_dir: /work
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.goreleaser
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG GORELEASE_CROSS_VERSION=v1.23.1
ARG GORELEASE_CROSS_VERSION=v1.23.2
FROM ghcr.io/goreleaser/goreleaser-cross:${GORELEASE_CROSS_VERSION}

RUN apt-get update && apt-get install -y openssh-client
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/planetscale/cli

go 1.23.1
go 1.23.2

require (
github.com/99designs/keyring v1.2.2
Expand All @@ -23,9 +23,9 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/pkg/errors v0.9.1
github.com/planetscale/planetscale-go v0.108.0
github.com/planetscale/planetscale-go v0.110.0
github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7
github.com/planetscale/psdbproxy v0.0.0-20240927190836-61feaf3c8bdb
github.com/planetscale/psdbproxy v0.0.0-20241009145102-7fdfa92ae3ca
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
Expand All @@ -39,6 +39,7 @@ require (
golang.org/x/sys v0.26.0
golang.org/x/text v0.19.0
gopkg.in/yaml.v2 v2.4.0
vitess.io/vitess v0.10.3-0.20240927074858-3e5371377b43
)

require (
Expand Down Expand Up @@ -91,7 +92,6 @@ require (
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
vitess.io/vitess v0.10.3-0.20240927074858-3e5371377b43 // indirect
)

replace github.com/golang/glog => github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e h1:MZ8D+Z3m2vvqGZLvoQfpaGg/j1fNDr4j03s3PRz4rVY=
github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e/go.mod h1:hwAsSPQdvPa3WcfKfzTXxtEq/HlqwLjQasfO6QbGo4Q=
github.com/planetscale/planetscale-go v0.108.0 h1:KwLhKsntOO2yokjYxfBtUwHN9/n+c6PnYPbsibZ8jmE=
github.com/planetscale/planetscale-go v0.108.0/go.mod h1:2s0/iqbBEBEL5k+3t0+eNztAU3bYxUynLQs4yLrKNDI=
github.com/planetscale/planetscale-go v0.110.0 h1:iaS/4pbP/efBmLtzr+cH8gjhLy1OjAovOgSqL+Gbobk=
github.com/planetscale/planetscale-go v0.110.0/go.mod h1:ldGffCLckkR8fjGDjDFs4WcjlDr8uqg2qRUZhRYBEMI=
github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7 h1:dxdoFKWVDlV1gq8UQC8NWCofLjCEjEHw47gfeojgs28=
github.com/planetscale/psdb v0.0.0-20240109164348-6848e728f6e7/go.mod h1:WZmi4gw3rOK+ryd1inGxgfKwoFV04O7xBCqzWzv0/0U=
github.com/planetscale/psdbproxy v0.0.0-20240927190836-61feaf3c8bdb h1:eJqW2GfcbKOkUCNHBmHOIWrX4sIaYUJ9xljnlNYtVPQ=
github.com/planetscale/psdbproxy v0.0.0-20240927190836-61feaf3c8bdb/go.mod h1:qxC4twwQwRjHb9lt2DB/Ny0CuhJs1rrxskPbBLDljgo=
github.com/planetscale/psdbproxy v0.0.0-20241009145102-7fdfa92ae3ca h1:E5E1yyZ03FzA/6styZr5C2L3DdqhnkZsKSJy5q4JnuU=
github.com/planetscale/psdbproxy v0.0.0-20241009145102-7fdfa92ae3ca/go.mod h1:qxC4twwQwRjHb9lt2DB/Ny0CuhJs1rrxskPbBLDljgo=
github.com/planetscale/vitess-types v0.0.0-20231211191709-770e14433716 h1:FD6vnHCirVPeyn+E6Z0HyXoAqXzjfTcRpgss/63im6w=
github.com/planetscale/vitess-types v0.0.0-20231211191709-770e14433716/go.mod h1:8KWsIjuUBs+xlbfn9wBCxicFZqV8BCPIFoqlOSs+60I=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
Expand Down
19 changes: 18 additions & 1 deletion internal/cmd/connect/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (

"github.com/mattn/go-shellwords"
"github.com/spf13/cobra"

"vitess.io/vitess/go/mysql"
)

func ConnectCmd(ch *cmdutil.Helper) *cobra.Command {
Expand All @@ -34,6 +36,7 @@ func ConnectCmd(ch *cmdutil.Helper) *cobra.Command {
role string
noRandom bool
replica bool
authMethod string
}

cmd := &cobra.Command{
Expand Down Expand Up @@ -95,6 +98,18 @@ argument:
role = cmdutil.ReaderRole
}

authMethod := mysql.CachingSha2Password
if flags.authMethod != "" {
switch flags.authMethod {
case "caching_sha2_password":
authMethod = mysql.CachingSha2Password
case "mysql_native_password":
authMethod = mysql.MysqlNativePassword
default:
return fmt.Errorf("unsupported auth method: %s", flags.authMethod)
}
}

// check whether database and branch exist
dbBranch, err := client.DatabaseBranches.Get(ctx, &planetscale.GetDatabaseBranchRequest{
Organization: ch.Config.Organization,
Expand Down Expand Up @@ -156,7 +171,7 @@ argument:

errCh := make(chan error, 1)
go func() {
errCh <- proxy.Serve(l)
errCh <- proxy.Serve(l, authMethod)
}()

go func() {
Expand Down Expand Up @@ -215,6 +230,8 @@ argument:
cmd.PersistentFlags().StringVar(&flags.role, "role",
"", "Role defines the access level, allowed values are: reader, writer, readwriter, admin. Defaults to 'reader' for replica passwords, otherwise defaults to 'admin'.")
cmd.Flags().BoolVar(&flags.replica, "replica", false, "When enabled, the password will route all reads to the branch's primary replicas and all read-only regions.")
cmd.PersistentFlags().StringVar(&flags.authMethod, "mysql-auth-method",
"", "MySQL auth method defines the authentication method returned for the MySQL protocol. Allowed values are: caching_sha2_password, mysql_native_password. Defaults to 'caching_sha2_password'.")

return cmd
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/database/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
_ "github.com/go-sql-driver/mysql"

"github.com/spf13/cobra"

"vitess.io/vitess/go/mysql"
)

type dumpFlags struct {
Expand Down Expand Up @@ -173,7 +175,10 @@ func dump(ch *cmdutil.Helper, cmd *cobra.Command, flags *dumpFlags, args []strin
defer l.Close()

go func() {
if err := proxy.Serve(l); err != nil {
// We have to use mysql.MysqlNativePassword here because we still end
// up using https://github.com/xelabs/go-mysqlstack which is unmaintained
// and doesn't support caching_sha2_password.
if err := proxy.Serve(l, mysql.MysqlNativePassword); err != nil {
ch.Printer.Println("proxy error: ", err)
}
}()
Expand Down
4 changes: 3 additions & 1 deletion internal/cmd/database/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
ps "github.com/planetscale/planetscale-go/planetscale"

"github.com/spf13/cobra"

"vitess.io/vitess/go/mysql"
)

type restoreFlags struct {
Expand Down Expand Up @@ -127,7 +129,7 @@ func restore(ch *cmdutil.Helper, cmd *cobra.Command, flags *restoreFlags, args [
defer l.Close()

go func() {
if err := proxy.Serve(l); err != nil {
if err := proxy.Serve(l, mysql.MysqlNativePassword); err != nil {
ch.Printer.Println("proxy error: ", err)
}
}()
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ second argument:
runForeground = false
}

mysqlPath, err := cmdutil.MySQLClientPath()
mysqlPath, authMethod, err := cmdutil.MySQLClientPath()
if err != nil {
return err
}
Expand Down Expand Up @@ -210,7 +210,7 @@ second argument:

errCh := make(chan error, 1)
go func() {
errCh <- proxy.Serve(l)
errCh <- proxy.Serve(l, authMethod)
}()

go func() {
Expand Down
47 changes: 39 additions & 8 deletions internal/cmdutil/cmdutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"time"

Expand All @@ -18,6 +20,8 @@ import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
exec "golang.org/x/sys/execabs"

"vitess.io/vitess/go/mysql"
)

const WarnAuthMessage = "not authenticated yet. Please run 'pscale auth login'"
Expand Down Expand Up @@ -166,10 +170,12 @@ func HasHomebrew() bool {
return err == nil
}

var versionRegex = regexp.MustCompile(`Ver ([0-9]+)\.([0-9]+)\.([0-9]+)`)

// MySQLClientPath checks whether the 'mysql' client exists and returns the
// path to the binary. The returned error contains instructions to install the
// client.
func MySQLClientPath() (string, error) {
func MySQLClientPath() (string, mysql.AuthMethodDescription, error) {
// 'brew install mysql-client' installs the client into an unusual path
// https://docs.brew.sh/FAQ#why-should-i-install-homebrew-in-the-default-location
var homebrewPrefix string
Expand All @@ -183,30 +189,55 @@ func MySQLClientPath() (string, error) {
homebrewPrefix = "/home/linuxbrew/.linuxbrew"
}

authMethod := mysql.CachingSha2Password
oldpath := os.Getenv("PATH")
newpath := homebrewPrefix + "/opt/mysql-client/bin/" + string(os.PathListSeparator) + oldpath
newpath := homebrewPrefix + "/opt/mysql-client/bin/" +
homebrewPrefix + "/opt/mysql/bin/" +
string(os.PathListSeparator) + oldpath
defer func() {
if err := os.Setenv("PATH", oldpath); err != nil {
fmt.Println("failed to restore PATH", err)
}
}()

if err := os.Setenv("PATH", newpath); err != nil {
return "", err
return "", authMethod, err
}

path, err := exec.LookPath("mysql")
if err == nil {
return path, nil
if err != nil {
return installInstructions("couldn't find the 'mysql' command-line tool required to run this command.")
}

cmd := exec.Command("mysql", "--version")
out, err := cmd.Output()
if err != nil {
return "", authMethod, fmt.Errorf("failed to run 'mysql --version': %w", err)
}

v := versionRegex.FindStringSubmatch(string(out))
if len(v) != 4 {
return "", authMethod, fmt.Errorf("could not parse server version from: %s", string(out))
}
major, err := strconv.Atoi(v[1])
if err != nil {
return "", authMethod, fmt.Errorf("could not parse server version from: %s", string(out))
}

msg := "couldn't find the 'mysql' command-line tool required to run this command."
if major < 8 {
authMethod = mysql.MysqlNativePassword
}

return path, authMethod, nil
}

func installInstructions(msg string) (string, mysql.AuthMethodDescription, error) {
installURL := "https://planetscale.com/docs/reference/planetscale-environment-setup"

switch runtime.GOOS {
case "darwin":
if HasHomebrew() {
return "", fmt.Errorf("%s\nTo install, run: brew install mysql-client", msg)
return "", mysql.CachingSha2Password, fmt.Errorf("%s\nTo install, run: brew install mysql-client@8.4", msg)
}

installURL = "https://planetscale.com/docs/reference/planetscale-environment-setup#macos-instructions"
Expand All @@ -216,7 +247,7 @@ func MySQLClientPath() (string, error) {
installURL = "https://planetscale.com/docs/reference/planetscale-environment-setup#windows-instructions"
}

return "", fmt.Errorf("%s\nTo install, follow the instructions: %s", msg, installURL)
return "", mysql.CachingSha2Password, fmt.Errorf("%s\nTo install, follow the instructions: %s", msg, installURL)
}

func ParseSSLMode(sslMode string) ps.ExternalDataSourceSSLVerificationMode {
Expand Down
24 changes: 24 additions & 0 deletions internal/mock/keyspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ type BranchKeyspacesService struct {

CreateFn func(context.Context, *ps.CreateBranchKeyspaceRequest) (*ps.Keyspace, error)
CreateFnInvoked bool

ResizeFn func(context.Context, *ps.ResizeKeyspaceRequest) (*ps.KeyspaceResizeRequest, error)
ResizeInvoked bool

CancelResizeFn func(context.Context, *ps.CancelKeyspaceResizeRequest) error
CancelResizeInvoked bool

ResizeStatusFn func(context.Context, *ps.KeyspaceResizeStatusRequest) (*ps.KeyspaceResizeRequest, error)
ResizeStatusInvoked bool
}

func (s *BranchKeyspacesService) List(ctx context.Context, req *ps.ListBranchKeyspacesRequest) ([]*ps.Keyspace, error) {
Expand Down Expand Up @@ -48,3 +57,18 @@ func (s *BranchKeyspacesService) Create(ctx context.Context, req *ps.CreateBranc
s.CreateFnInvoked = true
return s.CreateFn(ctx, req)
}

func (s *BranchKeyspacesService) Resize(ctx context.Context, req *ps.ResizeKeyspaceRequest) (*ps.KeyspaceResizeRequest, error) {
s.ResizeInvoked = true
return s.ResizeFn(ctx, req)
}

func (s *BranchKeyspacesService) CancelResize(ctx context.Context, req *ps.CancelKeyspaceResizeRequest) error {
s.CancelResizeInvoked = true
return s.CancelResizeFn(ctx, req)
}

func (s *BranchKeyspacesService) ResizeStatus(ctx context.Context, req *ps.KeyspaceResizeStatusRequest) (*ps.KeyspaceResizeRequest, error) {
s.ResizeStatusInvoked = true
return s.ResizeStatusFn(ctx, req)
}