@@ -3,9 +3,11 @@ package keeper
33import (
44 "bufio"
55 "context"
6+ "crypto/tls"
67 "encoding/json"
78 "fmt"
89 "io"
10+ "net"
911 "os"
1012 "path"
1113 "strconv"
@@ -18,6 +20,8 @@ import (
1820 "github.com/rs/zerolog/log"
1921
2022 "github.com/Altinity/clickhouse-backup/v2/pkg/clickhouse"
23+ "github.com/Altinity/clickhouse-backup/v2/pkg/config"
24+ "github.com/Altinity/clickhouse-backup/v2/pkg/utils"
2125 "github.com/go-zookeeper/zk"
2226)
2327
@@ -59,7 +63,7 @@ type Keeper struct {
5963}
6064
6165// Connect - connect to any zookeeper server from /var/lib/clickhouse/preprocessed_configs/config.xml
62- func (k * Keeper ) Connect (ctx context.Context , ch * clickhouse.ClickHouse ) error {
66+ func (k * Keeper ) Connect (ctx context.Context , ch * clickhouse.ClickHouse , cfg * config. Config ) error {
6367 configFile , doc , err := ch .ParseXML (ctx , "config.xml" )
6468 if err != nil {
6569 return errors .Wrapf (err , "can't parse config.xml from %s, error" , configFile )
@@ -83,6 +87,7 @@ func (k *Keeper) Connect(ctx context.Context, ch *clickhouse.ClickHouse) error {
8387 return errors .WithStack (fmt .Errorf ("/zookeeper/node not exists in %s" , configFile ))
8488 }
8589 keeperHosts := make ([]string , len (nodeList ))
90+ isSecure := false
8691 for i , node := range nodeList {
8792 hostNode := node .SelectElement ("host" )
8893 if hostNode == nil {
@@ -93,11 +98,37 @@ func (k *Keeper) Connect(ctx context.Context, ch *clickhouse.ClickHouse) error {
9398 if portNode != nil {
9499 port = portNode .InnerText ()
95100 }
101+ secureNode := node .SelectElement ("secure" )
102+ if secureNode != nil && (secureNode .InnerText () == "1" || secureNode .InnerText () == "true" ) {
103+ isSecure = true
104+ }
96105 keeperHosts [i ] = fmt .Sprintf ("%s:%s" , hostNode .InnerText (), port )
97106 }
98- conn , _ , err := zk .Connect (keeperHosts , sessionTimeout , zk .WithLogger (newKeeperLogger ()))
99- if err != nil {
100- return err
107+ var conn * zk.Conn
108+ if isSecure {
109+ log .Info ().Msgf ("isSecure=%v, keeperHosts=%v, caPath=%v, certPath=%v, keyPath=%v, skipVerify=%v, use TLS for keeper connection" , isSecure , keeperHosts , cfg .ClickHouse .TLSCa , cfg .ClickHouse .TLSCert , cfg .ClickHouse .TLSKey , cfg .ClickHouse .SkipVerify )
110+ tlsConfig , err := utils .NewTLSConfig (cfg .ClickHouse .TLSCa , cfg .ClickHouse .TLSCert , cfg .ClickHouse .TLSKey , cfg .ClickHouse .SkipVerify )
111+ if err != nil {
112+ return errors .Wrap (err , "can't create TLS config" )
113+ }
114+ conn , _ , err = zk .Connect (keeperHosts , sessionTimeout , zk .WithLogger (newKeeperLogger ()), zk .WithDialer (func (network , address string , timeout time.Duration ) (net.Conn , error ) {
115+ tlsConn , dialErr := tls .DialWithDialer (& net.Dialer {Timeout : timeout }, network , address , tlsConfig )
116+ if dialErr != nil {
117+ log .Error ().Msgf ("TLS dial to %s failed: %v" , address , dialErr )
118+ return nil , dialErr
119+ }
120+ return tlsConn , nil
121+ }))
122+ if err != nil {
123+ log .Error ().Msgf ("zk.Connect with TLS failed: %v" , err )
124+ return err
125+ }
126+ } else {
127+ log .Info ().Msgf ("isSecure=%v, keeperHosts=%v" , isSecure , keeperHosts )
128+ conn , _ , err = zk .Connect (keeperHosts , sessionTimeout , zk .WithLogger (newKeeperLogger ()))
129+ if err != nil {
130+ return err
131+ }
101132 }
102133 if digestNode := zookeeperNode .SelectElement ("digest" ); digestNode != nil {
103134 if err = conn .AddAuth ("digest" , []byte (digestNode .InnerText ())); err != nil {
0 commit comments