Skip to content

Commit f17cd65

Browse files
committed
Add custon http.Transport for supporting TLS (close #6)
1 parent 10d10b4 commit f17cd65

18 files changed

+212
-30
lines changed

.github/workflows/test.yml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
6+
jobs:
7+
lint:
8+
name: Lint
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v2
13+
- name: golangci-lint
14+
uses: golangci/golangci-lint-action@v2
15+
with:
16+
version: latest
17+
18+
test:
19+
name: Test
20+
needs: lint
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v2
25+
- name: Test
26+
run: |
27+
make test

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
.envrc

.idea/.gitignore

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/mysqlrouter-go.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile_test

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM golang:1.18
2+
3+
WORKDIR /go/src/mysqlrouter-go
4+
COPY . .

README.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ client for getting mysql-router information.
77

88
Supported version
99
-----------------
10-
- 20190715 (8.0.17 - 8.0.27)
10+
- 20190715 (8.0.17 - 8.0.29)
1111

1212
Enable HTTP Server and REST API
1313
-------------------------------
@@ -16,14 +16,16 @@ See [MySQL Router 8.0.17 and the REST API by lefred](https://lefred.be/content/m
1616
Usage
1717
-----
1818
```go
19-
mr, err := mysqlrouter.New("https://mysqlrouter-test.xzy.pw", "luis", "luis")
20-
routes, err := mr.GetAllRoutes()
19+
mysqlrouter.New("http://localhost:8080", "luis", "luis", nil)
2120
```
2221

23-
See [example](example/main.go)
22+
See [example](example/main.go) and [client_test.go](client_test.go)
2423

2524
Supported endpoint
2625
-------------------
26+
### server
27+
- [x] HTTPS with verify
28+
2729
### cluster
2830
- [x] /metadata
2931
- [x] /metadata/metadata_name/config
@@ -38,3 +40,9 @@ Supported endpoint
3840
- [x] /routes/route_name/health
3941
- [x] /routes/route_name/destinations
4042
- [x] /routes/route_name/connections
43+
44+
Developer
45+
---------
46+
```shell
47+
$ cd docker-compose && make local
48+
```

app_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
)
88

99
func TestClient_GetRouterStatus(t *testing.T) {
10-
setup()
10+
setupWithoutTLS()
1111

1212
routerStatus, err := client.GetRouterStatus()
1313
assert.NoError(t, err)

client.go

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mysqlrouter
22

33
import (
44
"errors"
5+
"net/http"
56
)
67

78
const apiVer = "20190715"
@@ -11,25 +12,29 @@ type Client struct {
1112
URL string
1213
Username string
1314
Password string
14-
SkipTLSVerify bool
15+
Options *Options
1516
}
1617

17-
func newClient(url, user, pass string, skipTLSVerify bool) *Client {
18+
type Options struct {
19+
Transport *http.Transport
20+
}
21+
22+
func newClient(url, user, pass string, Options *Options) *Client {
1823
return &Client{
1924
URL: url + "/api/" + apiVer,
2025
Username: user,
2126
Password: pass,
22-
SkipTLSVerify: skipTLSVerify,
27+
Options: Options,
2328
}
2429
}
2530

2631
// New creates a new API client.
27-
func New(url, user, pass string, skipTLSVerify bool) (*Client, error) {
28-
if url == "" {
32+
func New(url, user, pass string, Options *Options) (*Client, error) {
33+
if url == "" {
2934
return nil, errors.New(errEmptyClientInformation)
3035
}
3136

32-
client := newClient(url, user, pass, skipTLSVerify)
37+
client := newClient(url, user, pass, Options)
3338

3439
err := client.verifyConnection()
3540
if err != nil {

client_test.go

+66-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,77 @@
11
package mysqlrouter
22

3+
import (
4+
"crypto/tls"
5+
"crypto/x509"
6+
"github.com/stretchr/testify/assert"
7+
"io/ioutil"
8+
"net/http"
9+
"path/filepath"
10+
"testing"
11+
)
12+
313
var (
414
client *Client
515
)
616

7-
func setup() {
17+
func setupWithoutTLS() {
818
var err error
9-
client, err = New("https://mysqlrouter-test.xzy.pw", "luis", "luis", false)
19+
client, err = New("http://mysql-router-http:8080", "root", "mysql", nil)
1020
if err != nil {
1121
panic(err)
1222
}
1323
}
24+
25+
// TestNewClientWithSkipTLSVerify check a connection with InsecureSkipVerify: true
26+
func TestNewClientWithSkipTLSVerify(t *testing.T) {
27+
opts := &Options{
28+
Transport: &http.Transport{
29+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
30+
},
31+
}
32+
33+
_, err := New("https://mysql-router-https:8443", "root", "mysql", opts)
34+
assert.NoError(t, err)
35+
}
36+
37+
// TestNewClientWithTLS check a connection with certificates
38+
func TestNewClientWithTLS(t *testing.T) {
39+
certPath, err := filepath.Abs("docker-compose/mysql-router/certs/localhost.crt")
40+
if err != nil {
41+
assert.NoError(t, err)
42+
}
43+
keyPath, err := filepath.Abs("docker-compose/mysql-router/certs/localhost.key")
44+
if err != nil {
45+
assert.NoError(t, err)
46+
}
47+
caPath, err := filepath.Abs("docker-compose/mysql-router/certs/localCA.crt")
48+
if err != nil {
49+
assert.NoError(t, err)
50+
}
51+
52+
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
53+
if err != nil {
54+
assert.NoError(t, err)
55+
}
56+
57+
caCert, err := ioutil.ReadFile(caPath)
58+
if err != nil {
59+
assert.NoError(t, err)
60+
}
61+
caCertPool := x509.NewCertPool()
62+
caCertPool.AppendCertsFromPEM(caCert)
63+
64+
tlsConfig := &tls.Config{
65+
Certificates: []tls.Certificate{cert},
66+
RootCAs: caCertPool,
67+
}
68+
69+
opts := &Options{
70+
Transport: &http.Transport{
71+
TLSClientConfig: tlsConfig,
72+
},
73+
}
74+
75+
_, err = New("https://mysql-router-https:8443", "root", "mysql", opts)
76+
assert.NoError(t, err)
77+
}

docker-compose

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 892cc420a884d9494f62d77f9644c432e000b033

entrypoint.sh

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
echo "=============================================================================================="
6+
echo "To check any other containers log,"
7+
echo "run \"docker-compose up --build --force-recreate --always-recreate-deps --renew-anon-volumes\""
8+
echo "=============================================================================================="
9+
10+
readonly MAX_TRIES=120
11+
12+
attempt_num=0
13+
until curl -I -s http://mysql-router-http:8080 -k >/dev/null; do
14+
echo "Waiting for mysql router(http) ($attempt_num/$MAX_TRIES)"
15+
sleep $((attempt_num++))
16+
if ((attempt_num == MAX_TRIES)); then
17+
exit 1
18+
fi
19+
done
20+
21+
attempt_num=0
22+
until curl -I -s https://mysql-router-https:8443 -k >/dev/null; do
23+
echo "Waiting for mysql router(https) ($attempt_num/$MAX_TRIES)"
24+
sleep $((attempt_num++))
25+
if ((attempt_num == MAX_TRIES)); then
26+
exit 1
27+
fi
28+
done
29+
30+
echo "mysql router is ready."
31+
32+
#
33+
# start go test
34+
#
35+
36+
cd /go/src/mysqlrouter-go
37+
go test -v .
38+

example/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
)
88

99
func main() {
10-
mr, err := mysqlrouter.New("https://mysqlrouter-test.xzy.pw", "luis", "luis", false)
10+
mr, err := mysqlrouter.New("http://localhost:8080", "root", "mysql", nil)
1111
if err != nil {
1212
panic(err)
1313
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/rluisr/mysqlrouter-go
22

3-
go 1.17
3+
go 1.18
44

55
require github.com/stretchr/testify v1.6.1
66

metadata_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var (
1111
)
1212

1313
func TestClient_GetAllMetadata(t *testing.T) {
14-
setup()
14+
setupWithoutTLS()
1515

1616
metadatas, err := client.GetAllMetadata()
1717
assert.NoError(t, err)
@@ -21,15 +21,15 @@ func TestClient_GetAllMetadata(t *testing.T) {
2121
}
2222

2323
func TestClient_GetMetadataConfig(t *testing.T) {
24-
setup()
24+
setupWithoutTLS()
2525

2626
metadataConfig, err := client.GetMetadataConfig(metadata)
2727
assert.NoError(t, err)
2828
assert.NotEmpty(t, metadataConfig)
2929
}
3030

3131
func TestClient_GetMetadataStatus(t *testing.T) {
32-
setup()
32+
setupWithoutTLS()
3333

3434
metadataStatus, err := client.GetMetadataStatus(metadata)
3535
assert.NoError(t, err)

request.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package mysqlrouter
22

33
import (
4-
"crypto/tls"
54
"errors"
65
"fmt"
76
"io/ioutil"
87
"net/http"
98
)
109

1110
func (c *Client) request(url string) ([]byte, error) {
12-
if c.SkipTLSVerify {
13-
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
14-
}
15-
1611
client := &http.Client{}
1712

13+
if c.Options != nil {
14+
if c.Options.Transport != nil {
15+
client.Transport = c.Options.Transport
16+
}
17+
}
18+
1819
req, err := http.NewRequest("GET", url, nil)
1920
if err != nil {
2021
return nil, err

0 commit comments

Comments
 (0)