@@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
7
7
package nwo
8
8
9
9
import (
10
+ "bytes"
10
11
"fmt"
11
12
"io"
12
13
"io/ioutil"
@@ -19,7 +20,7 @@ import (
19
20
"text/template"
20
21
"time"
21
22
22
- docker "github.com/fsouza/go-dockerclient"
23
+ "github.com/fsouza/go-dockerclient"
23
24
"github.com/hyperledger/fabric/integration/helpers"
24
25
"github.com/hyperledger/fabric/integration/nwo/commands"
25
26
"github.com/hyperledger/fabric/integration/nwo/fabricconfig"
@@ -30,7 +31,7 @@ import (
30
31
"github.com/tedsuo/ifrit"
31
32
"github.com/tedsuo/ifrit/ginkgomon"
32
33
"github.com/tedsuo/ifrit/grouper"
33
- yaml "gopkg.in/yaml.v2"
34
+ "gopkg.in/yaml.v2"
34
35
)
35
36
36
37
// Organization models information about an Organization. It includes
@@ -134,18 +135,19 @@ type Network struct {
134
135
NetworkID string
135
136
EventuallyTimeout time.Duration
136
137
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
149
151
150
152
colorIndex uint
151
153
}
@@ -307,9 +309,9 @@ func (n *Network) WritePeerConfig(p *Peer, config *fabricconfig.Core) {
307
309
Expect (err ).NotTo (HaveOccurred ())
308
310
}
309
311
310
- // PeerUserMSPDir returns the path to the MSP directory containing the
312
+ // peerUserCrpytoDir returns the path to the directory containing the
311
313
// 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 {
313
315
org := n .Organization (p .Organization )
314
316
Expect (org ).NotTo (BeNil ())
315
317
@@ -320,10 +322,22 @@ func (n *Network) PeerUserMSPDir(p *Peer, user string) string {
320
322
org .Domain ,
321
323
"users" ,
322
324
fmt .Sprintf ("%s@%s" , user , org .Domain ),
323
- "msp" ,
325
+ cryptoMaterialType ,
324
326
)
325
327
}
326
328
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
+
327
341
// PeerUserCert returns the path to the certificate for the specified user in
328
342
// the peer organization.
329
343
func (n * Network ) PeerUserCert (p * Peer , user string ) string {
@@ -356,8 +370,8 @@ func (n *Network) PeerUserKey(p *Peer, user string) string {
356
370
return filepath .Join (keystore , keys [0 ].Name ())
357
371
}
358
372
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 {
361
375
org := n .Organization (p .Organization )
362
376
Expect (org ).NotTo (BeNil ())
363
377
@@ -368,10 +382,20 @@ func (n *Network) PeerLocalMSPDir(p *Peer) string {
368
382
org .Domain ,
369
383
"peers" ,
370
384
fmt .Sprintf ("%s.%s" , p .Name , org .Domain ),
371
- "msp" ,
385
+ cryptoType ,
372
386
)
373
387
}
374
388
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
+
375
399
// PeerCert returns the path to the peer's certificate.
376
400
func (n * Network ) PeerCert (p * Peer ) string {
377
401
org := n .Organization (p .Organization )
@@ -407,9 +431,9 @@ func (n *Network) OrdererOrgMSPDir(o *Organization) string {
407
431
)
408
432
}
409
433
410
- // OrdererLocalMSPDir returns the path to the local MSP directory for the
434
+ // ordererLocalCryptoDir returns the path to the local crypto directory for the
411
435
// Orderer.
412
- func (n * Network ) OrdererLocalMSPDir (o * Orderer ) string {
436
+ func (n * Network ) ordererLocalCryptoDir (o * Orderer , cryptoType string ) string {
413
437
org := n .Organization (o .Organization )
414
438
Expect (org ).NotTo (BeNil ())
415
439
@@ -420,10 +444,22 @@ func (n *Network) OrdererLocalMSPDir(o *Orderer) string {
420
444
org .Domain ,
421
445
"orderers" ,
422
446
fmt .Sprintf ("%s.%s" , o .Name , org .Domain ),
423
- "msp" ,
447
+ cryptoType ,
424
448
)
425
449
}
426
450
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
+
427
463
// ProfileForChannel gets the configtxgen profile name associated with the
428
464
// specified channel.
429
465
func (n * Network ) ProfileForChannel (channelName string ) string {
@@ -512,6 +548,42 @@ func (n *Network) Bootstrap() {
512
548
Expect (err ).NotTo (HaveOccurred ())
513
549
Eventually (sess , n .EventuallyTimeout ).Should (gexec .Exit (0 ))
514
550
}
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
515
587
}
516
588
517
589
// Cleanup attempts to cleanup docker related artifacts that may
@@ -692,6 +764,7 @@ func (n *Network) ConfigTxGen(command Command) (*gexec.Session, error) {
692
764
// Discover starts a gexec.Session for the provided discover command.
693
765
func (n * Network ) Discover (command Command ) (* gexec.Session , error ) {
694
766
cmd := NewCommand (n .Components .Discover (), command )
767
+ cmd .Args = append (cmd .Args , "--peerTLSCA" , n .CACertificateBundlePath )
695
768
return n .StartSession (cmd , command .SessionName ())
696
769
}
697
770
@@ -848,10 +921,35 @@ func (n *Network) NetworkGroupRunner() ifrit.Runner {
848
921
849
922
func (n * Network ) peerCommand (command Command , env ... string ) * exec.Cmd {
850
923
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
+ }
852
940
return cmd
853
941
}
854
942
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
+
855
953
// PeerAdminSession starts a gexec.Session as a peer admin for the provided
856
954
// peer command. This is intended to be used by short running peer cli commands
857
955
// that execute in the context of a peer configuration.
0 commit comments