Skip to content

Commit 9012678

Browse files
committed
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
1 parent 0d17f18 commit 9012678

File tree

12 files changed

+280
-253
lines changed

12 files changed

+280
-253
lines changed

cli/cluster/cmd/common.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ type connectOpts struct {
143143
}
144144

145145
// connectTarantool establishes a connection to Tarantool.
146-
func connectTarantool(uriOpts UriOpts, connOpts connectOpts) (tarantool.Connector, error) {
147-
addr, connectorOpts := MakeConnectOptsFromUriOpts(uriOpts)
146+
func connectTarantool(uriOpts connect.UriOpts, connOpts connectOpts) (tarantool.Connector, error) {
147+
addr, connectorOpts := connect.MakeConnectOptsFromUriOpts(uriOpts)
148148
if connectorOpts.User == "" && connectorOpts.Pass == "" {
149149
connectorOpts.User = connOpts.Username
150150
connectorOpts.Pass = connOpts.Password
@@ -164,8 +164,8 @@ func connectTarantool(uriOpts UriOpts, connOpts connectOpts) (tarantool.Connecto
164164
}
165165

166166
// connectEtcd establishes a connection to etcd.
167-
func connectEtcd(uriOpts UriOpts, connOpts connectOpts) (*clientv3.Client, error) {
168-
etcdOpts := MakeEtcdOptsFromUriOpts(uriOpts)
167+
func connectEtcd(uriOpts connect.UriOpts, connOpts connectOpts) (*clientv3.Client, error) {
168+
etcdOpts := connect.MakeEtcdOptsFromUriOpts(uriOpts)
169169
if etcdOpts.Username == "" && etcdOpts.Password == "" {
170170
etcdOpts.Username = connOpts.Username
171171
etcdOpts.Password = connOpts.Password
@@ -185,7 +185,7 @@ func connectEtcd(uriOpts UriOpts, connOpts connectOpts) (*clientv3.Client, error
185185
}
186186

187187
// doOnStorage determines a storage based on the opts.
188-
func doOnStorage(connOpts connectOpts, opts UriOpts,
188+
func doOnStorage(connOpts connectOpts, opts connect.UriOpts,
189189
tarantoolFunc func(tarantool.Connector) error, etcdFunc func(*clientv3.Client) error) error {
190190
etcdcli, errEtcd := connectEtcd(opts, connOpts)
191191
if errEtcd == nil {
@@ -206,7 +206,7 @@ func createPublisherAndCollector(
206206
publishers libcluster.DataPublisherFactory,
207207
collectors libcluster.CollectorFactory,
208208
connOpts connectOpts,
209-
opts UriOpts) (libcluster.DataPublisher, libcluster.Collector, func(), error) {
209+
opts connect.UriOpts) (libcluster.DataPublisher, libcluster.Collector, func(), error) {
210210
prefix, key, timeout := opts.Prefix, opts.Key, opts.Timeout
211211

212212
var (

cli/cluster/cmd/failover.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/apex/log"
1010
"github.com/google/uuid"
1111
libcluster "github.com/tarantool/tt/lib/cluster"
12+
"github.com/tarantool/tt/lib/connect"
1213
"go.etcd.io/etcd/api/v3/mvccpb"
1314
clientv3 "go.etcd.io/etcd/client/v3"
1415
"gopkg.in/yaml.v2"
@@ -63,7 +64,7 @@ type SwitchStatusCtx struct {
6364
TaskID string
6465
}
6566

66-
func makeEtcdOpts(uriOpts UriOpts) libcluster.EtcdOpts {
67+
func makeEtcdOpts(uriOpts connect.UriOpts) libcluster.EtcdOpts {
6768
opts := libcluster.EtcdOpts{
6869
Endpoints: []string{uriOpts.Endpoint},
6970
Username: uriOpts.Username,
@@ -81,7 +82,7 @@ func makeEtcdOpts(uriOpts UriOpts) libcluster.EtcdOpts {
8182

8283
// Switch master instance.
8384
func Switch(uri *url.URL, switchCtx SwitchCtx) error {
84-
uriOpts, err := ParseUriOpts(uri)
85+
uriOpts, err := connect.ParseUriOpts(uri)
8586
if err != nil {
8687
return fmt.Errorf("invalid URL %q: %w", uri, err)
8788
}
@@ -173,7 +174,7 @@ func Switch(uri *url.URL, switchCtx SwitchCtx) error {
173174

174175
// SwitchStatus shows master switching status.
175176
func SwitchStatus(uri *url.URL, switchCtx SwitchStatusCtx) error {
176-
uriOpts, err := ParseUriOpts(uri)
177+
uriOpts, err := connect.ParseUriOpts(uri)
177178
if err != nil {
178179
return fmt.Errorf("invalid URL %q: %w", uri, err)
179180
}

cli/cluster/cmd/publish.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net/url"
66

77
libcluster "github.com/tarantool/tt/lib/cluster"
8+
"github.com/tarantool/tt/lib/connect"
89
)
910

1011
// PublishCtx contains information abould cluster publish command execution
@@ -33,7 +34,7 @@ type PublishCtx struct {
3334

3435
// PublishUri publishes a configuration to URI.
3536
func PublishUri(publishCtx PublishCtx, uri *url.URL) error {
36-
uriOpts, err := ParseUriOpts(uri)
37+
uriOpts, err := connect.ParseUriOpts(uri)
3738
if err != nil {
3839
return fmt.Errorf("invalid URL %q: %w", uri, err)
3940
}

cli/cluster/cmd/replicaset.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/tarantool/go-tarantool"
1111
"github.com/tarantool/tt/cli/replicaset"
1212
libcluster "github.com/tarantool/tt/lib/cluster"
13+
"github.com/tarantool/tt/lib/connect"
1314
clientv3 "go.etcd.io/etcd/client/v3"
1415
)
1516

@@ -107,7 +108,7 @@ func pickPatchKey(keys []string, force bool, pathMsg string) (int, error) {
107108
func createDataCollectorAndKeyPublisher(
108109
collectors libcluster.DataCollectorFactory,
109110
publishers libcluster.DataPublisherFactory,
110-
opts UriOpts, connOpts connectOpts) (
111+
opts connect.UriOpts, connOpts connectOpts) (
111112
libcluster.DataCollector, replicaset.DataPublisher, func(), error) {
112113
prefix, key, timeout := opts.Prefix, opts.Key, opts.Timeout
113114
var (
@@ -154,7 +155,7 @@ func createDataCollectorAndKeyPublisher(
154155

155156
// Promote promotes an instance by patching the cluster config.
156157
func Promote(uri *url.URL, ctx PromoteCtx) error {
157-
opts, err := ParseUriOpts(uri)
158+
opts, err := connect.ParseUriOpts(uri)
158159
if err != nil {
159160
return fmt.Errorf("invalid URL %q: %w", uri, err)
160161
}
@@ -201,7 +202,7 @@ type DemoteCtx struct {
201202

202203
// Demote demotes an instance by patching the cluster config.
203204
func Demote(uri *url.URL, ctx DemoteCtx) error {
204-
opts, err := ParseUriOpts(uri)
205+
opts, err := connect.ParseUriOpts(uri)
205206
if err != nil {
206207
return fmt.Errorf("invalid URL %q: %w", uri, err)
207208
}
@@ -248,7 +249,7 @@ type ExpelCtx struct {
248249

249250
// Expel expels an instance by patching the cluster config.
250251
func Expel(uri *url.URL, ctx ExpelCtx) error {
251-
opts, err := ParseUriOpts(uri)
252+
opts, err := connect.ParseUriOpts(uri)
252253
if err != nil {
253254
return fmt.Errorf("invalid URL %q: %w", uri, err)
254255
}
@@ -302,7 +303,7 @@ type RolesChangeCtx struct {
302303

303304
// ChangeRole adds/removes a role by patching the cluster config.
304305
func ChangeRole(uri *url.URL, ctx RolesChangeCtx, action replicaset.RolesChangerAction) error {
305-
opts, err := ParseUriOpts(uri)
306+
opts, err := connect.ParseUriOpts(uri)
306307
if err != nil {
307308
return fmt.Errorf("invalid URL %q: %w", uri, err)
308309
}

cli/cluster/cmd/show.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/tarantool/tt/cli/cluster"
88
libcluster "github.com/tarantool/tt/lib/cluster"
9+
"github.com/tarantool/tt/lib/connect"
910
)
1011

1112
// ShowCtx contains information about cluster show command execution context.
@@ -23,7 +24,7 @@ type ShowCtx struct {
2324

2425
// ShowUri shows a configuration from URI.
2526
func ShowUri(showCtx ShowCtx, uri *url.URL) error {
26-
uriOpts, err := ParseUriOpts(uri)
27+
uriOpts, err := connect.ParseUriOpts(uri)
2728
if err != nil {
2829
return fmt.Errorf("invalid URL %q: %w", uri, err)
2930
}

cli/cmd/cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ You could also specify etcd/tarantool username and password with environment var
100100
101101
The priority of credentials:
102102
environment variables < command flags < URL credentials.
103-
`, float64(clustercmd.DefaultUriTimeout)/float64(time.Second),
103+
`, float64(libconnect.DefaultUriTimeout)/float64(time.Second),
104104
libconnect.EtcdUsernameEnv, libconnect.EtcdPasswordEnv,
105105
libconnect.TarantoolUsernameEnv, libconnect.TarantoolPasswordEnv)
106106
failoverUriHelp = fmt.Sprintf(
@@ -129,7 +129,7 @@ You could also specify etcd/tarantool username and password with environment var
129129
130130
The priority of credentials:
131131
environment variables < command flags < URL credentials.
132-
`, float64(clustercmd.DefaultUriTimeout)/float64(time.Second),
132+
`, float64(libconnect.DefaultUriTimeout)/float64(time.Second),
133133
libconnect.EtcdUsernameEnv, libconnect.EtcdPasswordEnv,
134134
libconnect.TarantoolUsernameEnv, libconnect.TarantoolPasswordEnv)
135135
)

lib/connect/opts_etcd.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package connect
2+
3+
import libcluster "github.com/tarantool/tt/lib/cluster"
4+
5+
// MakeEtcdOptsFromUriOpts create etcd connect options from URI options.
6+
func MakeEtcdOptsFromUriOpts(src UriOpts) libcluster.EtcdOpts {
7+
var endpoints []string
8+
if src.Endpoint != "" {
9+
endpoints = []string{src.Endpoint}
10+
}
11+
12+
return libcluster.EtcdOpts{
13+
Endpoints: endpoints,
14+
Username: src.Username,
15+
Password: src.Password,
16+
KeyFile: src.KeyFile,
17+
CertFile: src.CertFile,
18+
CaPath: src.CaPath,
19+
CaFile: src.CaFile,
20+
SkipHostVerify: src.SkipHostVerify || src.SkipPeerVerify,
21+
Timeout: src.Timeout,
22+
}
23+
}

lib/connect/opts_etcd_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package connect_test
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/stretchr/testify/assert"
8+
libcluster "github.com/tarantool/tt/lib/cluster"
9+
"github.com/tarantool/tt/lib/connect"
10+
)
11+
12+
func TestMakeEtcdOptsFromUriOpts(t *testing.T) {
13+
cases := []struct {
14+
Name string
15+
UriOpts connect.UriOpts
16+
Expected libcluster.EtcdOpts
17+
}{
18+
{
19+
Name: "empty",
20+
UriOpts: connect.UriOpts{},
21+
Expected: libcluster.EtcdOpts{},
22+
},
23+
{
24+
Name: "ignored",
25+
UriOpts: connect.UriOpts{
26+
Host: "foo",
27+
Prefix: "foo",
28+
Key: "bar",
29+
Instance: "zoo",
30+
Ciphers: "foo:bar:ciphers",
31+
},
32+
Expected: libcluster.EtcdOpts{},
33+
},
34+
{
35+
Name: "skip_host_verify",
36+
UriOpts: connect.UriOpts{
37+
SkipHostVerify: true,
38+
},
39+
Expected: libcluster.EtcdOpts{
40+
SkipHostVerify: true,
41+
},
42+
},
43+
{
44+
Name: "skip_peer_verify",
45+
UriOpts: connect.UriOpts{
46+
SkipPeerVerify: true,
47+
},
48+
Expected: libcluster.EtcdOpts{
49+
SkipHostVerify: true,
50+
},
51+
},
52+
{
53+
Name: "full",
54+
UriOpts: connect.UriOpts{
55+
Endpoint: "foo",
56+
Host: "host",
57+
Prefix: "prefix",
58+
Key: "key",
59+
Instance: "instance",
60+
Username: "username",
61+
Password: "password",
62+
KeyFile: "key_file",
63+
CertFile: "cert_file",
64+
CaPath: "ca_path",
65+
CaFile: "ca_file",
66+
SkipHostVerify: true,
67+
SkipPeerVerify: true,
68+
Timeout: 2 * time.Second,
69+
},
70+
Expected: libcluster.EtcdOpts{
71+
Endpoints: []string{"foo"},
72+
Username: "username",
73+
Password: "password",
74+
KeyFile: "key_file",
75+
CertFile: "cert_file",
76+
CaPath: "ca_path",
77+
CaFile: "ca_file",
78+
SkipHostVerify: true,
79+
Timeout: 2 * time.Second,
80+
},
81+
},
82+
}
83+
84+
for _, tc := range cases {
85+
t.Run(tc.Name, func(t *testing.T) {
86+
etcdOpts := connect.MakeEtcdOptsFromUriOpts(tc.UriOpts)
87+
88+
assert.Equal(t, tc.Expected, etcdOpts)
89+
})
90+
}
91+
}

lib/connect/opts_tarantool.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package connect
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/tarantool/go-tarantool"
7+
)
8+
9+
// MakeConnectOptsFromUriOpts create Tarantool connect options from
10+
// URI options.
11+
func MakeConnectOptsFromUriOpts(src UriOpts) (string, tarantool.Opts) {
12+
opts := tarantool.Opts{
13+
User: src.Username,
14+
Pass: src.Password,
15+
Ssl: tarantool.SslOpts{
16+
KeyFile: src.KeyFile,
17+
CertFile: src.CertFile,
18+
CaFile: src.CaFile,
19+
Ciphers: src.Ciphers,
20+
},
21+
Timeout: src.Timeout,
22+
}
23+
24+
if opts.Ssl != (tarantool.SslOpts{}) {
25+
opts.Transport = "ssl"
26+
}
27+
28+
return fmt.Sprintf("tcp://%s", src.Host), opts
29+
}

0 commit comments

Comments
 (0)