vitess.io/vitess@v0.16.2/go/test/endtoend/encryption/encryptedreplication/encrypted_replication_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package encryptedreplication 18 19 import ( 20 "flag" 21 "os" 22 "os/exec" 23 "path" 24 "testing" 25 26 "github.com/stretchr/testify/require" 27 28 "vitess.io/vitess/go/test/endtoend/cluster" 29 "vitess.io/vitess/go/test/endtoend/encryption" 30 "vitess.io/vitess/go/vt/log" 31 ) 32 33 var ( 34 clusterInstance *cluster.LocalProcessCluster 35 keyspace = "test_keyspace" 36 hostname = "localhost" 37 shardName = "0" 38 cell = "zone1" 39 certDirectory string 40 ) 41 42 // This test makes sure that we can use SSL replication with Vitess 43 func TestSecure(t *testing.T) { 44 defer cluster.PanicHandler(t) 45 testReplicationBase(t, true) 46 testReplicationBase(t, false) 47 } 48 49 // This test makes sure that we can use SSL replication with Vitess. 50 func testReplicationBase(t *testing.T, isClientCertPassed bool) { 51 flag.Parse() 52 53 // initialize cluster 54 _, err := initializeCluster(t) 55 require.Nil(t, err, "setup failed") 56 57 defer teardownCluster() 58 59 primaryTablet := *clusterInstance.Keyspaces[0].Shards[0].Vttablets[0] 60 replicaTablet := *clusterInstance.Keyspaces[0].Shards[0].Vttablets[1] 61 62 if isClientCertPassed { 63 replicaTablet.VttabletProcess.ExtraArgs = append(replicaTablet.VttabletProcess.ExtraArgs, "--db_flags", "2048", 64 "--db_ssl_ca", path.Join(certDirectory, "ca-cert.pem"), 65 "--db_ssl_cert", path.Join(certDirectory, "client-cert.pem"), 66 "--db_ssl_key", path.Join(certDirectory, "client-key.pem"), 67 ) 68 } 69 70 // start the tablets 71 for _, tablet := range []cluster.Vttablet{primaryTablet, replicaTablet} { 72 _ = tablet.VttabletProcess.Setup() 73 } 74 75 // Reparent using SSL (this will also check replication works) 76 err = clusterInstance.VtctlclientProcess.InitializeShard(keyspace, shardName, clusterInstance.Cell, primaryTablet.TabletUID) 77 if isClientCertPassed { 78 require.NoError(t, err) 79 } else { 80 require.Error(t, err) 81 } 82 83 err = clusterInstance.StartVTOrc(keyspace) 84 require.NoError(t, err) 85 } 86 87 func initializeCluster(t *testing.T) (int, error) { 88 var mysqlProcesses []*exec.Cmd 89 clusterInstance = cluster.NewCluster(cell, hostname) 90 91 // Start topo server 92 if err := clusterInstance.StartTopo(); err != nil { 93 return 1, err 94 } 95 96 // create certs directory 97 log.Info("Creating certificates") 98 certDirectory = path.Join(clusterInstance.TmpDirectory, "certs") 99 _ = encryption.CreateDirectory(certDirectory, 0700) 100 101 err := encryption.ExecuteVttlstestCommand("CreateCA", "--root", certDirectory) 102 require.NoError(t, err) 103 104 err = encryption.ExecuteVttlstestCommand("CreateSignedCert", "--root", certDirectory, "--common-name", "Mysql Server", "--serial", "01", "server") 105 require.NoError(t, err) 106 107 err = encryption.ExecuteVttlstestCommand("CreateSignedCert", "--root", certDirectory, "--common-name", "Mysql Client", "--serial", "02", "client") 108 require.NoError(t, err) 109 110 extraMyCnf := path.Join(certDirectory, "secure.cnf") 111 f, err := os.Create(extraMyCnf) 112 require.NoError(t, err) 113 114 _, err = f.WriteString("require_secure_transport=" + "true\n") 115 require.NoError(t, err) 116 _, err = f.WriteString("ssl-ca=" + certDirectory + "/ca-cert.pem\n") 117 require.NoError(t, err) 118 _, err = f.WriteString("ssl-cert=" + certDirectory + "/server-cert.pem\n") 119 require.NoError(t, err) 120 _, err = f.WriteString("ssl-key=" + certDirectory + "/server-key.pem\n") 121 require.NoError(t, err) 122 123 err = f.Close() 124 require.NoError(t, err) 125 126 err = os.Setenv("EXTRA_MY_CNF", extraMyCnf) 127 128 require.NoError(t, err) 129 130 for _, keyspaceStr := range []string{keyspace} { 131 KeyspacePtr := &cluster.Keyspace{Name: keyspaceStr} 132 keyspace := *KeyspacePtr 133 if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspace.Name); err != nil { 134 return 1, err 135 } 136 shard := &cluster.Shard{ 137 Name: shardName, 138 } 139 for i := 0; i < 2; i++ { 140 // instantiate vttablet object with reserved ports 141 tabletUID := clusterInstance.GetAndReserveTabletUID() 142 tablet := clusterInstance.NewVttabletInstance("replica", tabletUID, cell) 143 144 // Start Mysqlctl process 145 tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory) 146 proc, err := tablet.MysqlctlProcess.StartProcess() 147 if err != nil { 148 return 1, err 149 } 150 mysqlProcesses = append(mysqlProcesses, proc) 151 // start vttablet process 152 tablet.VttabletProcess = cluster.VttabletProcessInstance( 153 tablet.HTTPPort, 154 tablet.GrpcPort, 155 tablet.TabletUID, 156 clusterInstance.Cell, 157 shardName, 158 keyspace.Name, 159 clusterInstance.VtctldProcess.Port, 160 tablet.Type, 161 clusterInstance.TopoProcess.Port, 162 clusterInstance.Hostname, 163 clusterInstance.TmpDirectory, 164 clusterInstance.VtTabletExtraArgs, 165 clusterInstance.DefaultCharset) 166 tablet.Alias = tablet.VttabletProcess.TabletPath 167 shard.Vttablets = append(shard.Vttablets, tablet) 168 } 169 keyspace.Shards = append(keyspace.Shards, *shard) 170 clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, keyspace) 171 } 172 for _, proc := range mysqlProcesses { 173 err := proc.Wait() 174 if err != nil { 175 return 1, err 176 } 177 } 178 return 0, nil 179 } 180 181 func teardownCluster() { 182 clusterInstance.Teardown() 183 }