Skip to content

Commit 944adf2

Browse files
committed
[FAB-11960] Introduce TLS to integration tests
This change set makes integration tests run with TLS. Change-Id: I917f512b3765e52ec27d17830e93e091b360f322 Signed-off-by: yacovm <yacovm@il.ibm.com>
1 parent a006c86 commit 944adf2

File tree

6 files changed

+151
-40
lines changed

6 files changed

+151
-40
lines changed

integration/discovery/discovery_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ func toDiscoveredPeer(n *nwo.Network, p *nwo.Peer, chaincodes ...string) Discove
355355

356356
return DiscoveredPeer{
357357
MSPID: n.Organization(p.Organization).MSPID,
358-
Endpoint: fmt.Sprintf("0.0.0.0:%d", n.PeerPort(p, nwo.ListenPort)),
358+
Endpoint: fmt.Sprintf("127.0.0.1:%d", n.PeerPort(p, nwo.ListenPort)),
359359
Identity: string(peerCert),
360360
Chaincodes: chaincodes,
361361
}

integration/nwo/command.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ type WorkingDirer interface {
2424
WorkingDir() string
2525
}
2626

27+
func ConnectsToOrderer(c Command) bool {
28+
for _, arg := range c.Args() {
29+
if arg == "--orderer" {
30+
return true
31+
}
32+
}
33+
return false
34+
}
35+
2736
func NewCommand(path string, command Command) *exec.Cmd {
2837
cmd := exec.Command(path, command.Args()...)
2938
cmd.Env = os.Environ()

integration/nwo/core_template.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ logging:
2222
peer:
2323
id: {{ Peer.ID }}
2424
networkId: {{ .NetworkID }}
25-
address: 0.0.0.0:{{ .PeerPort Peer "Listen" }}
26-
addressAutoDetect: false
27-
listenAddress: 0.0.0.0:{{ .PeerPort Peer "Listen" }}
25+
address: 127.0.0.1:{{ .PeerPort Peer "Listen" }}
26+
addressAutoDetect: true
27+
listenAddress: 127.0.0.1:{{ .PeerPort Peer "Listen" }}
2828
chaincodeListenAddress: 0.0.0.0:{{ .PeerPort Peer "Chaincode" }}
2929
gomaxprocs: -1
3030
keepalive:
@@ -36,7 +36,7 @@ peer:
3636
interval: 60s
3737
timeout: 20s
3838
gossip:
39-
bootstrap: 0.0.0.0:{{ .PeerPort Peer "Listen" }}
39+
bootstrap: 127.0.0.1:{{ .PeerPort Peer "Listen" }}
4040
useLeaderElection: true
4141
orgLeader: false
4242
endpoint:
@@ -61,7 +61,7 @@ peer:
6161
aliveTimeInterval: 5s
6262
aliveExpirationTimeout: 25s
6363
reconnectInterval: 25s
64-
externalEndpoint: 0.0.0.0:{{ .PeerPort Peer "Listen" }}
64+
externalEndpoint: 127.0.0.1:{{ .PeerPort Peer "Listen" }}
6565
election:
6666
startupGracePeriod: 15s
6767
membershipSampleInterval: 1s
@@ -72,24 +72,24 @@ peer:
7272
transientstoreMaxBlockRetention: 1000
7373
pushAckTimeout: 3s
7474
events:
75-
address: 0.0.0.0:{{ .PeerPort Peer "Events" }}
75+
address: 127.0.0.1:{{ .PeerPort Peer "Events" }}
7676
buffersize: 100
7777
timeout: 10ms
7878
timewindow: 15m
7979
keepalive:
8080
minInterval: 60s
8181
tls:
82-
enabled: false
82+
enabled: true
8383
clientAuthRequired: false
8484
cert:
85-
file: tls/server.crt
85+
file: {{ .PeerLocalTLSDir Peer }}/server.crt
8686
key:
87-
file: tls/server.key
87+
file: {{ .PeerLocalTLSDir Peer }}/server.key
8888
rootcert:
89-
file: tls/ca.crt
89+
file: {{ .PeerLocalTLSDir Peer }}/ca.crt
9090
clientRootCAs:
9191
files:
92-
- tls/ca.crt
92+
- {{ .PeerLocalTLSDir Peer }}/ca.crt
9393
authentication:
9494
timewindow: 15m
9595
fileSystemPath: filesystem

integration/nwo/crypto_template.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ PeerOrgs:{{ range .PeerOrgs }}
4343
Count: {{ .Users }}
4444
Specs:{{ range $w.PeersInOrg .Name }}
4545
- Hostname: {{ .Name }}
46+
SANS:
47+
- localhost
48+
- 127.0.0.1
49+
- ::1
4650
{{- end }}
4751
{{- end }}
4852
{{- end }}

integration/nwo/network.go

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
77
package nwo
88

99
import (
10+
"bytes"
1011
"fmt"
1112
"io"
1213
"io/ioutil"
@@ -19,7 +20,7 @@ import (
1920
"text/template"
2021
"time"
2122

22-
docker "github.com/fsouza/go-dockerclient"
23+
"github.com/fsouza/go-dockerclient"
2324
"github.com/hyperledger/fabric/integration/helpers"
2425
"github.com/hyperledger/fabric/integration/nwo/commands"
2526
"github.com/hyperledger/fabric/integration/nwo/fabricconfig"
@@ -30,7 +31,7 @@ import (
3031
"github.com/tedsuo/ifrit"
3132
"github.com/tedsuo/ifrit/ginkgomon"
3233
"github.com/tedsuo/ifrit/grouper"
33-
yaml "gopkg.in/yaml.v2"
34+
"gopkg.in/yaml.v2"
3435
)
3536

3637
// Organization models information about an Organization. It includes
@@ -134,18 +135,19 @@ type Network struct {
134135
NetworkID string
135136
EventuallyTimeout time.Duration
136137

137-
PortsByBrokerID map[string]Ports
138-
PortsByOrdererID map[string]Ports
139-
PortsByPeerID map[string]Ports
140-
Organizations []*Organization
141-
SystemChannel *SystemChannel
142-
Channels []*Channel
143-
Consensus *Consensus
144-
Orderers []*Orderer
145-
Peers []*Peer
146-
Profiles []*Profile
147-
Consortiums []*Consortium
148-
Templates *Templates
138+
CACertificateBundlePath string
139+
PortsByBrokerID map[string]Ports
140+
PortsByOrdererID map[string]Ports
141+
PortsByPeerID map[string]Ports
142+
Organizations []*Organization
143+
SystemChannel *SystemChannel
144+
Channels []*Channel
145+
Consensus *Consensus
146+
Orderers []*Orderer
147+
Peers []*Peer
148+
Profiles []*Profile
149+
Consortiums []*Consortium
150+
Templates *Templates
149151

150152
colorIndex uint
151153
}
@@ -307,9 +309,9 @@ func (n *Network) WritePeerConfig(p *Peer, config *fabricconfig.Core) {
307309
Expect(err).NotTo(HaveOccurred())
308310
}
309311

310-
// PeerUserMSPDir returns the path to the MSP directory containing the
312+
// peerUserCrpytoDir returns the path to the directory containing the
311313
// certificates and keys for the specified user of the peer.
312-
func (n *Network) PeerUserMSPDir(p *Peer, user string) string {
314+
func (n *Network) peerUserCrpytoDir(p *Peer, user, cryptoMaterialType string) string {
313315
org := n.Organization(p.Organization)
314316
Expect(org).NotTo(BeNil())
315317

@@ -320,10 +322,22 @@ func (n *Network) PeerUserMSPDir(p *Peer, user string) string {
320322
org.Domain,
321323
"users",
322324
fmt.Sprintf("%s@%s", user, org.Domain),
323-
"msp",
325+
cryptoMaterialType,
324326
)
325327
}
326328

329+
// PeerUserMSPDir returns the path to the MSP directory containing the
330+
// certificates and keys for the specified user of the peer.
331+
func (n *Network) PeerUserMSPDir(p *Peer, user string) string {
332+
return n.peerUserCrpytoDir(p, user, "msp")
333+
}
334+
335+
// PeerUserTLSDir returns the path to the TLS directory containing the
336+
// certificates and keys for the specified user of the peer.
337+
func (n *Network) PeerUserTLSDir(p *Peer, user string) string {
338+
return n.peerUserCrpytoDir(p, user, "tls")
339+
}
340+
327341
// PeerUserCert returns the path to the certificate for the specified user in
328342
// the peer organization.
329343
func (n *Network) PeerUserCert(p *Peer, user string) string {
@@ -356,8 +370,8 @@ func (n *Network) PeerUserKey(p *Peer, user string) string {
356370
return filepath.Join(keystore, keys[0].Name())
357371
}
358372

359-
// PeerLocalMSPDir returns the path to the local MSP directory for the peer.
360-
func (n *Network) PeerLocalMSPDir(p *Peer) string {
373+
// peerLocalCryptoDir returns the path to the local crypto directory for the peer.
374+
func (n *Network) peerLocalCryptoDir(p *Peer, cryptoType string) string {
361375
org := n.Organization(p.Organization)
362376
Expect(org).NotTo(BeNil())
363377

@@ -368,10 +382,20 @@ func (n *Network) PeerLocalMSPDir(p *Peer) string {
368382
org.Domain,
369383
"peers",
370384
fmt.Sprintf("%s.%s", p.Name, org.Domain),
371-
"msp",
385+
cryptoType,
372386
)
373387
}
374388

389+
// PeerLocalMSPDir returns the path to the local MSP directory for the peer.
390+
func (n *Network) PeerLocalMSPDir(p *Peer) string {
391+
return n.peerLocalCryptoDir(p, "msp")
392+
}
393+
394+
// PeerLocalTLSDir returns the path to the local TLS directory for the peer.
395+
func (n *Network) PeerLocalTLSDir(p *Peer) string {
396+
return n.peerLocalCryptoDir(p, "tls")
397+
}
398+
375399
// PeerCert returns the path to the peer's certificate.
376400
func (n *Network) PeerCert(p *Peer) string {
377401
org := n.Organization(p.Organization)
@@ -407,9 +431,9 @@ func (n *Network) OrdererOrgMSPDir(o *Organization) string {
407431
)
408432
}
409433

410-
// OrdererLocalMSPDir returns the path to the local MSP directory for the
434+
// ordererLocalCryptoDir returns the path to the local crypto directory for the
411435
// Orderer.
412-
func (n *Network) OrdererLocalMSPDir(o *Orderer) string {
436+
func (n *Network) ordererLocalCryptoDir(o *Orderer, cryptoType string) string {
413437
org := n.Organization(o.Organization)
414438
Expect(org).NotTo(BeNil())
415439

@@ -420,10 +444,22 @@ func (n *Network) OrdererLocalMSPDir(o *Orderer) string {
420444
org.Domain,
421445
"orderers",
422446
fmt.Sprintf("%s.%s", o.Name, org.Domain),
423-
"msp",
447+
cryptoType,
424448
)
425449
}
426450

451+
// OrdererLocalMSPDir returns the path to the local MSP directory for the
452+
// Orderer.
453+
func (n *Network) OrdererLocalMSPDir(o *Orderer) string {
454+
return n.ordererLocalCryptoDir(o, "msp")
455+
}
456+
457+
// OrdererLocalTLSDir returns the path to the local TLS directory for the
458+
// Orderer.
459+
func (n *Network) OrdererLocalTLSDir(o *Orderer) string {
460+
return n.ordererLocalCryptoDir(o, "tls")
461+
}
462+
427463
// ProfileForChannel gets the configtxgen profile name associated with the
428464
// specified channel.
429465
func (n *Network) ProfileForChannel(channelName string) string {
@@ -512,6 +548,42 @@ func (n *Network) Bootstrap() {
512548
Expect(err).NotTo(HaveOccurred())
513549
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
514550
}
551+
552+
n.concatenateTLSCACertificates()
553+
}
554+
555+
// concatenateTLSCACertificates concatenates all TLS CA certificates
556+
// into a single file to be used by peer CLI
557+
func (n *Network) concatenateTLSCACertificates() {
558+
tlsCertificatesFilePath := filepath.Join(n.RootDir, "crypto", "tlsCACerts.pem")
559+
concatenatedTLSCABytes := bytes.Buffer{}
560+
for _, tlsCertPath := range n.listTLSCACertificates() {
561+
certBytes, err := ioutil.ReadFile(tlsCertPath)
562+
Expect(err).NotTo(HaveOccurred())
563+
concatenatedTLSCABytes.Write(certBytes)
564+
}
565+
err := ioutil.WriteFile(tlsCertificatesFilePath, concatenatedTLSCABytes.Bytes(), 0660)
566+
Expect(err).NotTo(HaveOccurred())
567+
n.CACertificateBundlePath = tlsCertificatesFilePath
568+
}
569+
570+
// listTLSCACertificates returns the paths of all TLS CA certificates
571+
// in the network, across all organizations.
572+
func (n *Network) listTLSCACertificates() []string {
573+
fileName2Path := make(map[string]string)
574+
filepath.Walk(filepath.Join(n.RootDir, "crypto"), func(path string, info os.FileInfo, err error) error {
575+
// File starts with "tlsca" and has "-cert.pem" in it
576+
if strings.Index(info.Name(), "tlsca") == 0 && strings.Contains(info.Name(), "-cert.pem") {
577+
fileName2Path[info.Name()] = path
578+
}
579+
return nil
580+
})
581+
582+
var tlsCACertificates []string
583+
for _, path := range fileName2Path {
584+
tlsCACertificates = append(tlsCACertificates, path)
585+
}
586+
return tlsCACertificates
515587
}
516588

517589
// Cleanup attempts to cleanup docker related artifacts that may
@@ -692,6 +764,7 @@ func (n *Network) ConfigTxGen(command Command) (*gexec.Session, error) {
692764
// Discover starts a gexec.Session for the provided discover command.
693765
func (n *Network) Discover(command Command) (*gexec.Session, error) {
694766
cmd := NewCommand(n.Components.Discover(), command)
767+
cmd.Args = append(cmd.Args, "--peerTLSCA", n.CACertificateBundlePath)
695768
return n.StartSession(cmd, command.SessionName())
696769
}
697770

@@ -848,10 +921,35 @@ func (n *Network) NetworkGroupRunner() ifrit.Runner {
848921

849922
func (n *Network) peerCommand(command Command, env ...string) *exec.Cmd {
850923
cmd := NewCommand(n.Components.Peer(), command)
851-
cmd.Env = append(env, cmd.Env...)
924+
cmd.Env = append(cmd.Env, env...)
925+
if ConnectsToOrderer(command) {
926+
cmd.Args = append(cmd.Args, "--tls")
927+
cmd.Args = append(cmd.Args, "--cafile", n.CACertificateBundlePath)
928+
}
929+
930+
// In case we have a peer invoke with multiple certificates,
931+
// we need to mimic the correct peer CLI usage,
932+
// so we count the number of --peerAddresses usages
933+
// we have, and add the same (concatenated TLS CA certificates file)
934+
// the same number of times to bypass the peer CLI sanity checks
935+
requiredPeerAddresses := flagCount("--peerAddresses", cmd.Args)
936+
for i := 0; i < requiredPeerAddresses; i++ {
937+
cmd.Args = append(cmd.Args, "--tlsRootCertFiles")
938+
cmd.Args = append(cmd.Args, n.CACertificateBundlePath)
939+
}
852940
return cmd
853941
}
854942

943+
func flagCount(flag string, args []string) int {
944+
var c int
945+
for _, arg := range args {
946+
if arg == flag {
947+
c++
948+
}
949+
}
950+
return c
951+
}
952+
855953
// PeerAdminSession starts a gexec.Session as a peer admin for the provided
856954
// peer command. This is intended to be used by short running peer cli commands
857955
// that execute in the context of a peer configuration.

integration/nwo/orderer_template.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ General:
1313
ListenAddress: 127.0.0.1
1414
ListenPort: {{ .OrdererPort Orderer "Listen" }}
1515
TLS:
16-
Enabled: false
17-
PrivateKey: tls/server.key
18-
Certificate: tls/server.crt
16+
Enabled: true
17+
PrivateKey: {{ $w.OrdererLocalTLSDir Orderer }}/server.key
18+
Certificate: {{ $w.OrdererLocalTLSDir Orderer }}/server.crt
1919
RootCAs:
20-
- tls/ca.crt
20+
- {{ $w.OrdererLocalTLSDir Orderer }}/ca.crt
2121
ClientAuthRequired: false
2222
ClientRootCAs:
2323
Keepalive:

0 commit comments

Comments
 (0)