@@ -46,21 +46,23 @@ type HostnameData struct {
46
46
Domain string
47
47
}
48
48
49
- type CommonNameData struct {
50
- Hostname string
51
- Domain string
49
+ type SpecData struct {
50
+ Hostname string
51
+ Domain string
52
+ CommonName string
52
53
}
53
54
54
55
type NodeTemplate struct {
55
- Count int `yaml:"Count"`
56
- Start int `yaml:"Start"`
57
- Hostname string `yaml:"Hostname"`
56
+ Count int `yaml:"Count"`
57
+ Start int `yaml:"Start"`
58
+ Hostname string `yaml:"Hostname"`
59
+ SANS []string `yaml:"SANS"`
58
60
}
59
61
60
62
type NodeSpec struct {
61
- Hostname string `yaml:"Hostname"`
62
- AltHostnames [] string `yaml:"AltHostnames "`
63
- CommonName string `yaml:"CommonName "`
63
+ Hostname string `yaml:"Hostname"`
64
+ CommonName string `yaml:"CommonName "`
65
+ SANS [] string `yaml:"SANS "`
64
66
}
65
67
66
68
type UsersSpec struct {
@@ -132,10 +134,20 @@ PeerOrgs:
132
134
#
133
135
# which obtains its values from the Spec.Hostname and
134
136
# Org.Domain, respectively.
137
+ # - SANS: (Optional) Specifies one or more Subject Alternative Names
138
+ # the be set in the resulting x509. Accepts template
139
+ # variables {{.Hostname}}, {{.Domain}}, {{.CommonName}}
140
+ # NOTE: Two implicit entries are created for you:
141
+ # - {{ .CommonName }}
142
+ # - {{ .Hostname }}
135
143
# ---------------------------------------------------------------------------
136
144
# Specs:
137
145
# - Hostname: foo # implicitly "foo.org1.example.com"
138
146
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
147
+ # SANS:
148
+ # - "bar.{{.Domain}}"
149
+ # - "altfoo.{{.Domain}}"
150
+ # - "{{.Hostname}}.org6.net"
139
151
# - Hostname: bar
140
152
# - Hostname: baz
141
153
@@ -155,6 +167,8 @@ PeerOrgs:
155
167
Count: 1
156
168
# Start: 5
157
169
# Hostname: {{.Prefix}}{{.Index}} # default
170
+ # SANS:
171
+ # - "{{.Hostname}}.alt.{{.Domain}}"
158
172
159
173
# ---------------------------------------------------------------------------
160
174
# "Users"
@@ -234,7 +248,7 @@ func generate() {
234
248
}
235
249
236
250
for _ , orgSpec := range config .PeerOrgs {
237
- err = generateNodeSpec (& orgSpec , "peer" )
251
+ err = renderOrgSpec (& orgSpec , "peer" )
238
252
if err != nil {
239
253
fmt .Printf ("Error processing peer configuration: %s" , err )
240
254
os .Exit (- 1 )
@@ -243,7 +257,7 @@ func generate() {
243
257
}
244
258
245
259
for _ , orgSpec := range config .OrdererOrgs {
246
- generateNodeSpec (& orgSpec , "orderer" )
260
+ renderOrgSpec (& orgSpec , "orderer" )
247
261
if err != nil {
248
262
fmt .Printf ("Error processing orderer configuration: %s" , err )
249
263
os .Exit (- 1 )
@@ -252,12 +266,7 @@ func generate() {
252
266
}
253
267
}
254
268
255
- func parseTemplate (input , defaultInput string , data interface {}) (string , error ) {
256
-
257
- // Use the default if the input is an empty string
258
- if len (input ) == 0 {
259
- input = defaultInput
260
- }
269
+ func parseTemplate (input string , data interface {}) (string , error ) {
261
270
262
271
t , err := template .New ("parse" ).Parse (input )
263
272
if err != nil {
@@ -273,16 +282,51 @@ func parseTemplate(input, defaultInput string, data interface{}) (string, error)
273
282
return output .String (), nil
274
283
}
275
284
276
- func renderCN (domain string , spec NodeSpec ) (string , error ) {
277
- data := CommonNameData {
285
+ func parseTemplateWithDefault (input , defaultInput string , data interface {}) (string , error ) {
286
+
287
+ // Use the default if the input is an empty string
288
+ if len (input ) == 0 {
289
+ input = defaultInput
290
+ }
291
+
292
+ return parseTemplate (input , data )
293
+ }
294
+
295
+ func renderNodeSpec (domain string , spec * NodeSpec ) error {
296
+ data := SpecData {
278
297
Hostname : spec .Hostname ,
279
298
Domain : domain ,
280
299
}
281
300
282
- return parseTemplate (spec .CommonName , defaultCNTemplate , data )
301
+ // Process our CommonName
302
+ cn , err := parseTemplateWithDefault (spec .CommonName , defaultCNTemplate , data )
303
+ if err != nil {
304
+ return err
305
+ }
306
+
307
+ spec .CommonName = cn
308
+ data .CommonName = cn
309
+
310
+ // Save off our original, unprocessed SANS entries
311
+ origSANS := spec .SANS
312
+
313
+ // Set our implicit SANS entries for CN/Hostname
314
+ spec .SANS = []string {cn , spec .Hostname }
315
+
316
+ // Finally, process any remaining SANS entries
317
+ for _ , _san := range origSANS {
318
+ san , err := parseTemplate (_san , data )
319
+ if err != nil {
320
+ return err
321
+ }
322
+
323
+ spec .SANS = append (spec .SANS , san )
324
+ }
325
+
326
+ return nil
283
327
}
284
328
285
- func generateNodeSpec (orgSpec * OrgSpec , prefix string ) error {
329
+ func renderOrgSpec (orgSpec * OrgSpec , prefix string ) error {
286
330
// First process all of our templated nodes
287
331
for i := 0 ; i < orgSpec .Template .Count ; i ++ {
288
332
data := HostnameData {
@@ -291,34 +335,36 @@ func generateNodeSpec(orgSpec *OrgSpec, prefix string) error {
291
335
Domain : orgSpec .Domain ,
292
336
}
293
337
294
- hostname , err := parseTemplate (orgSpec .Template .Hostname , defaultHostnameTemplate , data )
338
+ hostname , err := parseTemplateWithDefault (orgSpec .Template .Hostname , defaultHostnameTemplate , data )
295
339
if err != nil {
296
340
return err
297
341
}
298
342
299
- spec := NodeSpec {Hostname : hostname }
343
+ spec := NodeSpec {
344
+ Hostname : hostname ,
345
+ SANS : orgSpec .Template .SANS ,
346
+ }
300
347
orgSpec .Specs = append (orgSpec .Specs , spec )
301
348
}
302
349
303
350
// Touch up all general node-specs to add the domain
304
351
for idx , spec := range orgSpec .Specs {
305
- finalCN , err := renderCN (orgSpec .Domain , spec )
352
+ err := renderNodeSpec (orgSpec .Domain , & spec )
306
353
if err != nil {
307
354
return err
308
355
}
309
356
310
- orgSpec .Specs [idx ]. CommonName = finalCN
357
+ orgSpec .Specs [idx ] = spec
311
358
}
312
359
313
360
// Process the CA node-spec in the same manner
314
361
if len (orgSpec .CA .Hostname ) == 0 {
315
362
orgSpec .CA .Hostname = "ca"
316
363
}
317
- finalCN , err := renderCN (orgSpec .Domain , orgSpec .CA )
364
+ err := renderNodeSpec (orgSpec .Domain , & orgSpec .CA )
318
365
if err != nil {
319
366
return err
320
367
}
321
- orgSpec .CA .CommonName = finalCN
322
368
323
369
return nil
324
370
}
@@ -346,41 +392,40 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
346
392
os .Exit (1 )
347
393
}
348
394
349
- peerNames := []string {}
350
- for _ , spec := range orgSpec .Specs {
351
- peerNames = append (peerNames , spec .CommonName )
352
- }
353
- generateNodes (peersDir , peerNames , rootCA )
395
+ generateNodes (peersDir , orgSpec .Specs , rootCA )
354
396
355
397
// TODO: add ability to specify usernames
356
- usernames := []string {}
398
+ users := []NodeSpec {}
357
399
for j := 1 ; j <= orgSpec .Users .Count ; j ++ {
358
- usernames = append (usernames , fmt .Sprintf ("%s%d@%s" ,
359
- userBaseName , j , orgName ))
400
+ user := NodeSpec {
401
+ CommonName : fmt .Sprintf ("%s%d@%s" , userBaseName , j , orgName ),
402
+ }
403
+
404
+ users = append (users , user )
360
405
}
361
406
// add an admin user
362
- adminUserName := fmt .Sprintf ("%s@%s" ,
363
- adminBaseName , orgName )
407
+ adminUser := NodeSpec {
408
+ CommonName : fmt .Sprintf ("%s@%s" , adminBaseName , orgName ),
409
+ }
364
410
365
- usernames = append (usernames , adminUserName )
366
- generateNodes (usersDir , usernames , rootCA )
411
+ users = append (users , adminUser )
412
+ generateNodes (usersDir , users , rootCA )
367
413
368
414
// copy the admin cert to the org's MSP admincerts
369
- err = copyAdminCert (usersDir , adminCertsDir , adminUserName )
415
+ err = copyAdminCert (usersDir , adminCertsDir , adminUser . CommonName )
370
416
if err != nil {
371
417
fmt .Printf ("Error copying admin cert for org %s:\n %v\n " ,
372
418
orgName , err )
373
419
os .Exit (1 )
374
420
}
375
421
376
422
// copy the admin cert to each of the org's peer's MSP admincerts
377
- for _ , peerName := range peerNames {
423
+ for _ , spec := range orgSpec . Specs {
378
424
err = copyAdminCert (usersDir ,
379
- filepath .Join (peersDir , peerName , "msp" , "admincerts" ),
380
- adminUserName )
425
+ filepath .Join (peersDir , spec .CommonName , "msp" , "admincerts" ), adminUser .CommonName )
381
426
if err != nil {
382
427
fmt .Printf ("Error copying admin cert for org %s peer %s:\n %v\n " ,
383
- orgName , peerName , err )
428
+ orgName , spec . CommonName , err )
384
429
os .Exit (1 )
385
430
}
386
431
}
@@ -407,17 +452,16 @@ func copyAdminCert(usersDir, adminCertsDir, adminUserName string) error {
407
452
408
453
}
409
454
410
- func generateNodes (baseDir string , nodeNames []string , rootCA * ca.CA ) {
455
+ func generateNodes (baseDir string , nodes []NodeSpec , rootCA * ca.CA ) {
411
456
412
- for _ , nodeName := range nodeNames {
413
- nodeDir := filepath .Join (baseDir , nodeName )
414
- err := msp .GenerateLocalMSP (nodeDir , nodeName , rootCA )
457
+ for _ , node := range nodes {
458
+ nodeDir := filepath .Join (baseDir , node . CommonName )
459
+ err := msp .GenerateLocalMSP (nodeDir , node . CommonName , node . SANS , rootCA )
415
460
if err != nil {
416
- fmt .Printf ("Error generating local MSP for %s:\n %v\n " , nodeName , err )
461
+ fmt .Printf ("Error generating local MSP for %s:\n %v\n " , node , err )
417
462
os .Exit (1 )
418
463
}
419
464
}
420
-
421
465
}
422
466
423
467
func generateOrdererOrg (baseDir string , orgSpec OrgSpec ) {
@@ -442,38 +486,33 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) {
442
486
os .Exit (1 )
443
487
}
444
488
445
- // TODO: add ability to specify orderer names
446
- // for name just use default base name
447
- ordererNames := []string {}
448
- for _ , spec := range orgSpec .Specs {
449
- ordererNames = append (ordererNames , spec .CommonName )
450
- }
451
- generateNodes (orderersDir , ordererNames , rootCA )
489
+ generateNodes (orderersDir , orgSpec .Specs , rootCA )
452
490
453
- adminUserName := fmt .Sprintf ("%s@%s" ,
454
- adminBaseName , orgName )
491
+ adminUser := NodeSpec {
492
+ CommonName : fmt .Sprintf ("%s@%s" , adminBaseName , orgName ),
493
+ }
455
494
456
495
// generate an admin for the orderer org
457
- usernames := []string {}
496
+ users := []NodeSpec {}
458
497
// add an admin user
459
- usernames = append (usernames , adminUserName )
460
- generateNodes (usersDir , usernames , rootCA )
498
+ users = append (users , adminUser )
499
+ generateNodes (usersDir , users , rootCA )
461
500
462
501
// copy the admin cert to the org's MSP admincerts
463
- err = copyAdminCert (usersDir , adminCertsDir , adminUserName )
502
+ err = copyAdminCert (usersDir , adminCertsDir , adminUser . CommonName )
464
503
if err != nil {
465
504
fmt .Printf ("Error copying admin cert for org %s:\n %v\n " ,
466
505
orgName , err )
467
506
os .Exit (1 )
468
507
}
469
508
470
509
// copy the admin cert to each of the org's orderers's MSP admincerts
471
- for _ , ordererName := range ordererNames {
510
+ for _ , spec := range orgSpec . Specs {
472
511
err = copyAdminCert (usersDir ,
473
- filepath .Join (orderersDir , ordererName , "msp" , "admincerts" ), adminUserName )
512
+ filepath .Join (orderersDir , spec . CommonName , "msp" , "admincerts" ), adminUser . CommonName )
474
513
if err != nil {
475
514
fmt .Printf ("Error copying admin cert for org %s orderer %s:\n %v\n " ,
476
- orgName , ordererName , err )
515
+ orgName , spec . CommonName , err )
477
516
os .Exit (1 )
478
517
}
479
518
}
0 commit comments