From 90126780f956336b3b9081eddfd3da8e4faaefed Mon Sep 17 00:00:00 2001 From: Dmitriy Gertsog Date: Mon, 20 Jan 2025 17:08:52 +0300 Subject: [PATCH] lib: move url parsing to connect package Moves the common URL parsing logic from the `cmd` package to the `connect` package. Part of #TNTP-1081 --- cli/cluster/cmd/common.go | 12 +- cli/cluster/cmd/failover.go | 7 +- cli/cluster/cmd/publish.go | 3 +- cli/cluster/cmd/replicaset.go | 11 +- cli/cluster/cmd/show.go | 3 +- cli/cmd/cluster.go | 4 +- lib/connect/opts_etcd.go | 23 ++ lib/connect/opts_etcd_test.go | 91 ++++++++ lib/connect/opts_tarantool.go | 29 +++ lib/connect/opts_tarantool_test.go | 85 +++++++ .../cmd/uri.go => lib/connect/uriopts.go | 52 +---- .../connect/uriopts_test.go | 213 +++--------------- 12 files changed, 280 insertions(+), 253 deletions(-) create mode 100644 lib/connect/opts_etcd.go create mode 100644 lib/connect/opts_etcd_test.go create mode 100644 lib/connect/opts_tarantool.go create mode 100644 lib/connect/opts_tarantool_test.go rename cli/cluster/cmd/uri.go => lib/connect/uriopts.go (72%) rename cli/cluster/cmd/uri_test.go => lib/connect/uriopts_test.go (53%) diff --git a/cli/cluster/cmd/common.go b/cli/cluster/cmd/common.go index e20436330..1a6189068 100644 --- a/cli/cluster/cmd/common.go +++ b/cli/cluster/cmd/common.go @@ -143,8 +143,8 @@ type connectOpts struct { } // connectTarantool establishes a connection to Tarantool. -func connectTarantool(uriOpts UriOpts, connOpts connectOpts) (tarantool.Connector, error) { - addr, connectorOpts := MakeConnectOptsFromUriOpts(uriOpts) +func connectTarantool(uriOpts connect.UriOpts, connOpts connectOpts) (tarantool.Connector, error) { + addr, connectorOpts := connect.MakeConnectOptsFromUriOpts(uriOpts) if connectorOpts.User == "" && connectorOpts.Pass == "" { connectorOpts.User = connOpts.Username connectorOpts.Pass = connOpts.Password @@ -164,8 +164,8 @@ func connectTarantool(uriOpts UriOpts, connOpts connectOpts) (tarantool.Connecto } // connectEtcd establishes a connection to etcd. -func connectEtcd(uriOpts UriOpts, connOpts connectOpts) (*clientv3.Client, error) { - etcdOpts := MakeEtcdOptsFromUriOpts(uriOpts) +func connectEtcd(uriOpts connect.UriOpts, connOpts connectOpts) (*clientv3.Client, error) { + etcdOpts := connect.MakeEtcdOptsFromUriOpts(uriOpts) if etcdOpts.Username == "" && etcdOpts.Password == "" { etcdOpts.Username = connOpts.Username etcdOpts.Password = connOpts.Password @@ -185,7 +185,7 @@ func connectEtcd(uriOpts UriOpts, connOpts connectOpts) (*clientv3.Client, error } // doOnStorage determines a storage based on the opts. -func doOnStorage(connOpts connectOpts, opts UriOpts, +func doOnStorage(connOpts connectOpts, opts connect.UriOpts, tarantoolFunc func(tarantool.Connector) error, etcdFunc func(*clientv3.Client) error) error { etcdcli, errEtcd := connectEtcd(opts, connOpts) if errEtcd == nil { @@ -206,7 +206,7 @@ func createPublisherAndCollector( publishers libcluster.DataPublisherFactory, collectors libcluster.CollectorFactory, connOpts connectOpts, - opts UriOpts) (libcluster.DataPublisher, libcluster.Collector, func(), error) { + opts connect.UriOpts) (libcluster.DataPublisher, libcluster.Collector, func(), error) { prefix, key, timeout := opts.Prefix, opts.Key, opts.Timeout var ( diff --git a/cli/cluster/cmd/failover.go b/cli/cluster/cmd/failover.go index ccfbc5f50..e7b20b5d4 100644 --- a/cli/cluster/cmd/failover.go +++ b/cli/cluster/cmd/failover.go @@ -9,6 +9,7 @@ import ( "github.com/apex/log" "github.com/google/uuid" libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" "go.etcd.io/etcd/api/v3/mvccpb" clientv3 "go.etcd.io/etcd/client/v3" "gopkg.in/yaml.v2" @@ -63,7 +64,7 @@ type SwitchStatusCtx struct { TaskID string } -func makeEtcdOpts(uriOpts UriOpts) libcluster.EtcdOpts { +func makeEtcdOpts(uriOpts connect.UriOpts) libcluster.EtcdOpts { opts := libcluster.EtcdOpts{ Endpoints: []string{uriOpts.Endpoint}, Username: uriOpts.Username, @@ -81,7 +82,7 @@ func makeEtcdOpts(uriOpts UriOpts) libcluster.EtcdOpts { // Switch master instance. func Switch(uri *url.URL, switchCtx SwitchCtx) error { - uriOpts, err := ParseUriOpts(uri) + uriOpts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } @@ -173,7 +174,7 @@ func Switch(uri *url.URL, switchCtx SwitchCtx) error { // SwitchStatus shows master switching status. func SwitchStatus(uri *url.URL, switchCtx SwitchStatusCtx) error { - uriOpts, err := ParseUriOpts(uri) + uriOpts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } diff --git a/cli/cluster/cmd/publish.go b/cli/cluster/cmd/publish.go index 5000ce876..d934c4a19 100644 --- a/cli/cluster/cmd/publish.go +++ b/cli/cluster/cmd/publish.go @@ -5,6 +5,7 @@ import ( "net/url" libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" ) // PublishCtx contains information abould cluster publish command execution @@ -33,7 +34,7 @@ type PublishCtx struct { // PublishUri publishes a configuration to URI. func PublishUri(publishCtx PublishCtx, uri *url.URL) error { - uriOpts, err := ParseUriOpts(uri) + uriOpts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } diff --git a/cli/cluster/cmd/replicaset.go b/cli/cluster/cmd/replicaset.go index f544d73d3..c511d3b2a 100644 --- a/cli/cluster/cmd/replicaset.go +++ b/cli/cluster/cmd/replicaset.go @@ -10,6 +10,7 @@ import ( "github.com/tarantool/go-tarantool" "github.com/tarantool/tt/cli/replicaset" libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" clientv3 "go.etcd.io/etcd/client/v3" ) @@ -107,7 +108,7 @@ func pickPatchKey(keys []string, force bool, pathMsg string) (int, error) { func createDataCollectorAndKeyPublisher( collectors libcluster.DataCollectorFactory, publishers libcluster.DataPublisherFactory, - opts UriOpts, connOpts connectOpts) ( + opts connect.UriOpts, connOpts connectOpts) ( libcluster.DataCollector, replicaset.DataPublisher, func(), error) { prefix, key, timeout := opts.Prefix, opts.Key, opts.Timeout var ( @@ -154,7 +155,7 @@ func createDataCollectorAndKeyPublisher( // Promote promotes an instance by patching the cluster config. func Promote(uri *url.URL, ctx PromoteCtx) error { - opts, err := ParseUriOpts(uri) + opts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } @@ -201,7 +202,7 @@ type DemoteCtx struct { // Demote demotes an instance by patching the cluster config. func Demote(uri *url.URL, ctx DemoteCtx) error { - opts, err := ParseUriOpts(uri) + opts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } @@ -248,7 +249,7 @@ type ExpelCtx struct { // Expel expels an instance by patching the cluster config. func Expel(uri *url.URL, ctx ExpelCtx) error { - opts, err := ParseUriOpts(uri) + opts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } @@ -302,7 +303,7 @@ type RolesChangeCtx struct { // ChangeRole adds/removes a role by patching the cluster config. func ChangeRole(uri *url.URL, ctx RolesChangeCtx, action replicaset.RolesChangerAction) error { - opts, err := ParseUriOpts(uri) + opts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } diff --git a/cli/cluster/cmd/show.go b/cli/cluster/cmd/show.go index dbfe6036c..eb8e9d30a 100644 --- a/cli/cluster/cmd/show.go +++ b/cli/cluster/cmd/show.go @@ -6,6 +6,7 @@ import ( "github.com/tarantool/tt/cli/cluster" libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" ) // ShowCtx contains information about cluster show command execution context. @@ -23,7 +24,7 @@ type ShowCtx struct { // ShowUri shows a configuration from URI. func ShowUri(showCtx ShowCtx, uri *url.URL) error { - uriOpts, err := ParseUriOpts(uri) + uriOpts, err := connect.ParseUriOpts(uri) if err != nil { return fmt.Errorf("invalid URL %q: %w", uri, err) } diff --git a/cli/cmd/cluster.go b/cli/cmd/cluster.go index 62323f7bc..6af37082b 100644 --- a/cli/cmd/cluster.go +++ b/cli/cmd/cluster.go @@ -100,7 +100,7 @@ You could also specify etcd/tarantool username and password with environment var The priority of credentials: environment variables < command flags < URL credentials. -`, float64(clustercmd.DefaultUriTimeout)/float64(time.Second), +`, float64(libconnect.DefaultUriTimeout)/float64(time.Second), libconnect.EtcdUsernameEnv, libconnect.EtcdPasswordEnv, libconnect.TarantoolUsernameEnv, libconnect.TarantoolPasswordEnv) failoverUriHelp = fmt.Sprintf( @@ -129,7 +129,7 @@ You could also specify etcd/tarantool username and password with environment var The priority of credentials: environment variables < command flags < URL credentials. -`, float64(clustercmd.DefaultUriTimeout)/float64(time.Second), +`, float64(libconnect.DefaultUriTimeout)/float64(time.Second), libconnect.EtcdUsernameEnv, libconnect.EtcdPasswordEnv, libconnect.TarantoolUsernameEnv, libconnect.TarantoolPasswordEnv) ) diff --git a/lib/connect/opts_etcd.go b/lib/connect/opts_etcd.go new file mode 100644 index 000000000..f03a6aa4b --- /dev/null +++ b/lib/connect/opts_etcd.go @@ -0,0 +1,23 @@ +package connect + +import libcluster "github.com/tarantool/tt/lib/cluster" + +// MakeEtcdOptsFromUriOpts create etcd connect options from URI options. +func MakeEtcdOptsFromUriOpts(src UriOpts) libcluster.EtcdOpts { + var endpoints []string + if src.Endpoint != "" { + endpoints = []string{src.Endpoint} + } + + return libcluster.EtcdOpts{ + Endpoints: endpoints, + Username: src.Username, + Password: src.Password, + KeyFile: src.KeyFile, + CertFile: src.CertFile, + CaPath: src.CaPath, + CaFile: src.CaFile, + SkipHostVerify: src.SkipHostVerify || src.SkipPeerVerify, + Timeout: src.Timeout, + } +} diff --git a/lib/connect/opts_etcd_test.go b/lib/connect/opts_etcd_test.go new file mode 100644 index 000000000..38ab4830a --- /dev/null +++ b/lib/connect/opts_etcd_test.go @@ -0,0 +1,91 @@ +package connect_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" +) + +func TestMakeEtcdOptsFromUriOpts(t *testing.T) { + cases := []struct { + Name string + UriOpts connect.UriOpts + Expected libcluster.EtcdOpts + }{ + { + Name: "empty", + UriOpts: connect.UriOpts{}, + Expected: libcluster.EtcdOpts{}, + }, + { + Name: "ignored", + UriOpts: connect.UriOpts{ + Host: "foo", + Prefix: "foo", + Key: "bar", + Instance: "zoo", + Ciphers: "foo:bar:ciphers", + }, + Expected: libcluster.EtcdOpts{}, + }, + { + Name: "skip_host_verify", + UriOpts: connect.UriOpts{ + SkipHostVerify: true, + }, + Expected: libcluster.EtcdOpts{ + SkipHostVerify: true, + }, + }, + { + Name: "skip_peer_verify", + UriOpts: connect.UriOpts{ + SkipPeerVerify: true, + }, + Expected: libcluster.EtcdOpts{ + SkipHostVerify: true, + }, + }, + { + Name: "full", + UriOpts: connect.UriOpts{ + Endpoint: "foo", + Host: "host", + Prefix: "prefix", + Key: "key", + Instance: "instance", + Username: "username", + Password: "password", + KeyFile: "key_file", + CertFile: "cert_file", + CaPath: "ca_path", + CaFile: "ca_file", + SkipHostVerify: true, + SkipPeerVerify: true, + Timeout: 2 * time.Second, + }, + Expected: libcluster.EtcdOpts{ + Endpoints: []string{"foo"}, + Username: "username", + Password: "password", + KeyFile: "key_file", + CertFile: "cert_file", + CaPath: "ca_path", + CaFile: "ca_file", + SkipHostVerify: true, + Timeout: 2 * time.Second, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + etcdOpts := connect.MakeEtcdOptsFromUriOpts(tc.UriOpts) + + assert.Equal(t, tc.Expected, etcdOpts) + }) + } +} diff --git a/lib/connect/opts_tarantool.go b/lib/connect/opts_tarantool.go new file mode 100644 index 000000000..f36930068 --- /dev/null +++ b/lib/connect/opts_tarantool.go @@ -0,0 +1,29 @@ +package connect + +import ( + "fmt" + + "github.com/tarantool/go-tarantool" +) + +// MakeConnectOptsFromUriOpts create Tarantool connect options from +// URI options. +func MakeConnectOptsFromUriOpts(src UriOpts) (string, tarantool.Opts) { + opts := tarantool.Opts{ + User: src.Username, + Pass: src.Password, + Ssl: tarantool.SslOpts{ + KeyFile: src.KeyFile, + CertFile: src.CertFile, + CaFile: src.CaFile, + Ciphers: src.Ciphers, + }, + Timeout: src.Timeout, + } + + if opts.Ssl != (tarantool.SslOpts{}) { + opts.Transport = "ssl" + } + + return fmt.Sprintf("tcp://%s", src.Host), opts +} diff --git a/lib/connect/opts_tarantool_test.go b/lib/connect/opts_tarantool_test.go new file mode 100644 index 000000000..9a780314d --- /dev/null +++ b/lib/connect/opts_tarantool_test.go @@ -0,0 +1,85 @@ +package connect_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/tarantool/go-tarantool" + "github.com/tarantool/tt/lib/connect" +) + +func TestMakeConnectOptsFromUriOpts(t *testing.T) { + cases := []struct { + Name string + UriOpts connect.UriOpts + Expected tarantool.Opts + ExpectedAddr string + }{ + { + Name: "empty", + UriOpts: connect.UriOpts{}, + Expected: tarantool.Opts{}, + ExpectedAddr: "tcp://", + }, + { + Name: "ignored", + UriOpts: connect.UriOpts{ + Endpoint: "localhost:3013", + Prefix: "foo", + Key: "bar", + Instance: "zoo", + CaPath: "ca_path", + SkipHostVerify: true, + SkipPeerVerify: true, + Timeout: 673, + }, + Expected: tarantool.Opts{ + Timeout: 673, + }, + ExpectedAddr: "tcp://", // is this ok? + }, + { + Name: "full", + UriOpts: connect.UriOpts{ + Endpoint: "scheme://foo", + Host: "foo", + Prefix: "prefix", + Key: "key", + Instance: "instance", + Username: "username", + Password: "password", + KeyFile: "key_file", + CertFile: "cert_file", + CaPath: "ca_path", + CaFile: "ca_file", + Ciphers: "foo:bar:ciphers", + SkipHostVerify: true, + SkipPeerVerify: true, + Timeout: 2 * time.Second, + }, + Expected: tarantool.Opts{ + User: "username", + Pass: "password", + Timeout: 2 * time.Second, + Transport: "ssl", + Ssl: tarantool.SslOpts{ + KeyFile: "key_file", + CertFile: "cert_file", + CaFile: "ca_file", + Ciphers: "foo:bar:ciphers", + }, + }, + ExpectedAddr: "tcp://foo", + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + addr, tntOpts := connect.MakeConnectOptsFromUriOpts(tc.UriOpts) + + assert.Equal(t, tc.Expected, tntOpts) + assert.Equal(t, tc.ExpectedAddr, addr) + }) + } +} diff --git a/cli/cluster/cmd/uri.go b/lib/connect/uriopts.go similarity index 72% rename from cli/cluster/cmd/uri.go rename to lib/connect/uriopts.go index 26da47a90..4bf1f2a84 100644 --- a/cli/cluster/cmd/uri.go +++ b/lib/connect/uriopts.go @@ -1,4 +1,4 @@ -package cmd +package connect import ( "fmt" @@ -6,10 +6,6 @@ import ( "strconv" "strings" "time" - - "github.com/tarantool/go-tarantool" - - libcluster "github.com/tarantool/tt/lib/cluster" ) const ( @@ -90,7 +86,7 @@ func ParseUriOpts(uri *url.URL) (UriOpts, error) { if verifyPeerStr != "" { verifyPeerStr = strings.ToLower(verifyPeerStr) if verify, err := strconv.ParseBool(verifyPeerStr); err == nil { - if verify == false { + if !verify { opts.SkipPeerVerify = true } } else { @@ -102,7 +98,7 @@ func ParseUriOpts(uri *url.URL) (UriOpts, error) { if verifyHostStr != "" { verifyHostStr = strings.ToLower(verifyHostStr) if verify, err := strconv.ParseBool(verifyHostStr); err == nil { - if verify == false { + if !verify { opts.SkipHostVerify = true } } else { @@ -122,45 +118,3 @@ func ParseUriOpts(uri *url.URL) (UriOpts, error) { return opts, nil } - -// MakeEtcdOptsFromUriOpts create etcd connect options from URI options. -func MakeEtcdOptsFromUriOpts(src UriOpts) libcluster.EtcdOpts { - var endpoints []string - if src.Endpoint != "" { - endpoints = []string{src.Endpoint} - } - - return libcluster.EtcdOpts{ - Endpoints: endpoints, - Username: src.Username, - Password: src.Password, - KeyFile: src.KeyFile, - CertFile: src.CertFile, - CaPath: src.CaPath, - CaFile: src.CaFile, - SkipHostVerify: src.SkipHostVerify || src.SkipPeerVerify, - Timeout: src.Timeout, - } -} - -// MakeConnectOptsFromUriOpts create Tarantool connect options from -// URI options. -func MakeConnectOptsFromUriOpts(src UriOpts) (string, tarantool.Opts) { - opts := tarantool.Opts{ - User: src.Username, - Pass: src.Password, - Ssl: tarantool.SslOpts{ - KeyFile: src.KeyFile, - CertFile: src.CertFile, - CaFile: src.CaFile, - Ciphers: src.Ciphers, - }, - Timeout: src.Timeout, - } - - if opts.Ssl != (tarantool.SslOpts{}) { - opts.Transport = "ssl" - } - - return fmt.Sprintf("tcp://%s", src.Host), opts -} diff --git a/cli/cluster/cmd/uri_test.go b/lib/connect/uriopts_test.go similarity index 53% rename from cli/cluster/cmd/uri_test.go rename to lib/connect/uriopts_test.go index 72a64c23d..2bcaf44ce 100644 --- a/cli/cluster/cmd/uri_test.go +++ b/lib/connect/uriopts_test.go @@ -1,4 +1,4 @@ -package cmd_test +package connect_test import ( "net/url" @@ -8,10 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tarantool/go-tarantool" - - "github.com/tarantool/tt/cli/cluster/cmd" - libcluster "github.com/tarantool/tt/lib/cluster" + "github.com/tarantool/tt/lib/connect" ) func TestParseUriOpts(t *testing.T) { @@ -19,27 +16,27 @@ func TestParseUriOpts(t *testing.T) { cases := []struct { Url string - Opts cmd.UriOpts + Opts connect.UriOpts Err string }{ { Url: "", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "URL must contain the scheme and the host parts", }, { Url: "host", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "URL must contain the scheme and the host parts", }, { Url: "scheme:///prefix", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "URL must contain the scheme and the host parts", }, { Url: "scheme://localhost", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Timeout: defaultTimeout, @@ -48,7 +45,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost:3013", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost:3013", Host: "localhost:3013", Timeout: defaultTimeout, @@ -57,7 +54,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://user@localhost", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Username: "user", @@ -67,7 +64,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://user:pass@localhost", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Username: "user", @@ -78,7 +75,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost/", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Prefix: "/", @@ -88,7 +85,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost/prefix", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Prefix: "/prefix", @@ -98,7 +95,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost/prefix?key=anykey", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Prefix: "/prefix", @@ -109,7 +106,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost/prefix?name=anyname", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Prefix: "/prefix", @@ -120,7 +117,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?ssl_key_file=/any/kfile", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", KeyFile: "/any/kfile", @@ -130,7 +127,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?ssl_cert_file=/any/certfile", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", CertFile: "/any/certfile", @@ -140,7 +137,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?ssl_ca_path=/any/capath", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", CaPath: "/any/capath", @@ -150,7 +147,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?ssl_ca_file=/any/cafile", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", CaFile: "/any/cafile", @@ -160,7 +157,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?verify_peer=true&verify_host=true", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Timeout: defaultTimeout, @@ -169,7 +166,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?verify_peer=false", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", SkipPeerVerify: true, @@ -179,12 +176,12 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?verify_peer=asd", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "invalid verify_peer, boolean expected", }, { Url: "scheme://localhost?verify_host=false", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", SkipHostVerify: true, @@ -194,12 +191,12 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?verify_host=asd", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "invalid verify_host, boolean expected", }, { Url: "scheme://localhost?timeout=5.5", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost", Host: "localhost", Timeout: time.Duration(float64(5.5) * float64(time.Second)), @@ -208,7 +205,7 @@ func TestParseUriOpts(t *testing.T) { }, { Url: "scheme://localhost?timeout=asd", - Opts: cmd.UriOpts{}, + Opts: connect.UriOpts{}, Err: "invalid timeout, float expected", }, { @@ -218,7 +215,7 @@ func TestParseUriOpts(t *testing.T) { "&ssl_ca_path=capath&ssl_ca_file=cafile" + "&ssl_ciphers=foo:bar:ciphers" + "&verify_peer=true&verify_host=false&timeout=2", - Opts: cmd.UriOpts{ + Opts: connect.UriOpts{ Endpoint: "scheme://localhost:2012", Host: "localhost:2012", Prefix: "/prefix", @@ -243,7 +240,7 @@ func TestParseUriOpts(t *testing.T) { uri, err := url.Parse(tc.Url) require.NoError(t, err) - opts, err := cmd.ParseUriOpts(uri) + opts, err := connect.ParseUriOpts(uri) if tc.Err != "" { assert.ErrorContains(t, err, tc.Err) } else { @@ -252,159 +249,3 @@ func TestParseUriOpts(t *testing.T) { }) } } - -func TestMakeEtcdOptsFromUriOpts(t *testing.T) { - cases := []struct { - Name string - UriOpts cmd.UriOpts - Expected libcluster.EtcdOpts - }{ - { - Name: "empty", - UriOpts: cmd.UriOpts{}, - Expected: libcluster.EtcdOpts{}, - }, - { - Name: "ignored", - UriOpts: cmd.UriOpts{ - Host: "foo", - Prefix: "foo", - Key: "bar", - Instance: "zoo", - Ciphers: "foo:bar:ciphers", - }, - Expected: libcluster.EtcdOpts{}, - }, - { - Name: "skip_host_verify", - UriOpts: cmd.UriOpts{ - SkipHostVerify: true, - }, - Expected: libcluster.EtcdOpts{ - SkipHostVerify: true, - }, - }, - { - Name: "skip_peer_verify", - UriOpts: cmd.UriOpts{ - SkipPeerVerify: true, - }, - Expected: libcluster.EtcdOpts{ - SkipHostVerify: true, - }, - }, - { - Name: "full", - UriOpts: cmd.UriOpts{ - Endpoint: "foo", - Host: "host", - Prefix: "prefix", - Key: "key", - Instance: "instance", - Username: "username", - Password: "password", - KeyFile: "key_file", - CertFile: "cert_file", - CaPath: "ca_path", - CaFile: "ca_file", - SkipHostVerify: true, - SkipPeerVerify: true, - Timeout: 2 * time.Second, - }, - Expected: libcluster.EtcdOpts{ - Endpoints: []string{"foo"}, - Username: "username", - Password: "password", - KeyFile: "key_file", - CertFile: "cert_file", - CaPath: "ca_path", - CaFile: "ca_file", - SkipHostVerify: true, - Timeout: 2 * time.Second, - }, - }, - } - - for _, tc := range cases { - t.Run(tc.Name, func(t *testing.T) { - etcdOpts := cmd.MakeEtcdOptsFromUriOpts(tc.UriOpts) - - assert.Equal(t, tc.Expected, etcdOpts) - }) - } -} - -func TestMakeConnectOptsFromUriOpts(t *testing.T) { - cases := []struct { - Name string - UriOpts cmd.UriOpts - Expected tarantool.Opts - ExpectedAddr string - }{ - { - Name: "empty", - UriOpts: cmd.UriOpts{}, - Expected: tarantool.Opts{}, - ExpectedAddr: "tcp://", - }, - { - Name: "ignored", - UriOpts: cmd.UriOpts{ - Endpoint: "localhost:3013", - Prefix: "foo", - Key: "bar", - Instance: "zoo", - CaPath: "ca_path", - SkipHostVerify: true, - SkipPeerVerify: true, - Timeout: 673, - }, - Expected: tarantool.Opts{ - Timeout: 673, - }, - ExpectedAddr: "tcp://", // is this ok? - }, - { - Name: "full", - UriOpts: cmd.UriOpts{ - Endpoint: "scheme://foo", - Host: "foo", - Prefix: "prefix", - Key: "key", - Instance: "instance", - Username: "username", - Password: "password", - KeyFile: "key_file", - CertFile: "cert_file", - CaPath: "ca_path", - CaFile: "ca_file", - Ciphers: "foo:bar:ciphers", - SkipHostVerify: true, - SkipPeerVerify: true, - Timeout: 2 * time.Second, - }, - Expected: tarantool.Opts{ - User: "username", - Pass: "password", - Timeout: 2 * time.Second, - Transport: "ssl", - Ssl: tarantool.SslOpts{ - KeyFile: "key_file", - CertFile: "cert_file", - CaFile: "ca_file", - Ciphers: "foo:bar:ciphers", - }, - }, - ExpectedAddr: "tcp://foo", - }, - } - - for _, tc := range cases { - t.Run(tc.Name, func(t *testing.T) { - addr, tntOpts := cmd.MakeConnectOptsFromUriOpts(tc.UriOpts) - - assert.Equal(t, tc.Expected, tntOpts) - assert.Equal(t, tc.ExpectedAddr, addr) - }) - } -}