9
9
"context"
10
10
"crypto/x509"
11
11
"encoding/base64"
12
+ "encoding/json"
12
13
"encoding/pem"
13
14
"errors"
14
15
"fmt"
@@ -24,6 +25,7 @@ import (
24
25
"github.com/siderolabs/gen/maps"
25
26
"github.com/spf13/cobra"
26
27
"google.golang.org/protobuf/types/known/durationpb"
28
+ "gopkg.in/yaml.v3"
27
29
28
30
"github.com/siderolabs/talos/cmd/talosctl/pkg/talos/helpers"
29
31
machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
@@ -444,47 +446,58 @@ var configNewCmd = &cobra.Command{
444
446
}
445
447
446
448
// configNewCmd represents the `config info` command output template.
447
- var configInfoCmdTemplate = template .Must (template .New ("configInfoCmdTemplate" ).Option ("missingkey=error" ).Parse (strings .TrimSpace (`
449
+ var configInfoCmdTemplate = template .Must (template .New ("configInfoCmdTemplate" ).
450
+ Funcs (template.FuncMap {"join" : strings .Join }).
451
+ Option ("missingkey=error" ).
452
+ Parse (strings .TrimSpace (`
448
453
Current context: {{ .Context }}
449
- Nodes: {{ .Nodes }}
450
- Endpoints: {{ .Endpoints }}
454
+ Nodes: {{ if .Nodes }}{{ join .Nodes ", " }}{{ else }}not defined{{ end }}
455
+ Endpoints: {{ if .Endpoints }}{{ join .Endpoints ", " }}{{ else }}not defined{{ end }}
451
456
{{- if .Roles }}
452
- Roles: {{ .Roles }}{{ end }}
457
+ Roles: {{ join .Roles ", " }}{{ end }}
453
458
{{- if .CertTTL }}
454
459
Certificate expires: {{ .CertTTL }} ({{ .CertNotAfter }}){{ end }}
455
460
` )))
456
461
457
- // configInfoCommand implements `config info` command logic.
458
- func configInfoCommand (config * clientconfig.Config , now time.Time ) (string , error ) {
462
+ type talosconfigInfo struct {
463
+ Context string `json:"context" yaml:"context"`
464
+ Nodes []string `json:"nodes" yaml:"nodes"`
465
+ Endpoints []string `json:"endpoints" yaml:"endpoints"`
466
+ Roles []string `json:"roles" yaml:"roles"`
467
+ CertTTL string `json:"certTTL" yaml:"certTTL"`
468
+ CertNotAfter string `json:"certNotAfter" yaml:"certNotAfter"`
469
+ }
470
+
471
+ // configInfo returns talosct config info.
472
+ func configInfo (config * clientconfig.Config , now time.Time ) (talosconfigInfo , error ) {
459
473
cfgContext , err := getContextData (config )
460
474
if err != nil {
461
- return "" , err
475
+ return talosconfigInfo {} , err
462
476
}
463
477
464
478
var (
465
479
certTTL , certNotAfter string
466
480
roles role.Set
467
- rolesS string
468
481
)
469
482
470
483
if cfgContext .Crt != "" {
471
484
var b []byte
472
485
473
486
b , err = base64 .StdEncoding .DecodeString (cfgContext .Crt )
474
487
if err != nil {
475
- return "" , err
488
+ return talosconfigInfo {} , err
476
489
}
477
490
478
491
block , _ := pem .Decode (b )
479
492
if block == nil {
480
- return "" , fmt .Errorf ("error decoding PEM" )
493
+ return talosconfigInfo {} , fmt .Errorf ("error decoding PEM" )
481
494
}
482
495
483
496
var crt * x509.Certificate
484
497
485
498
crt , err = x509 .ParseCertificate (block .Bytes )
486
499
if err != nil {
487
- return "" , err
500
+ return talosconfigInfo {} , err
488
501
}
489
502
490
503
roles , _ = role .Parse (crt .Subject .Organization )
@@ -493,33 +506,33 @@ func configInfoCommand(config *clientconfig.Config, now time.Time) (string, erro
493
506
certNotAfter = crt .NotAfter .UTC ().Format ("2006-01-02" )
494
507
}
495
508
496
- nodesS := "not defined"
497
- if len ( cfgContext . Nodes ) > 0 {
498
- nodesS = strings . Join ( cfgContext .Nodes , ", " )
499
- }
500
-
501
- endpointsS := "not defined"
502
- if len ( cfgContext . Endpoints ) > 0 {
503
- endpointsS = strings . Join ( cfgContext . Endpoints , ", " )
504
- }
509
+ return talosconfigInfo {
510
+ Context : config . Context ,
511
+ Nodes : cfgContext .Nodes ,
512
+ Endpoints : cfgContext . Endpoints ,
513
+ Roles : roles . Strings (),
514
+ CertTTL : certTTL ,
515
+ CertNotAfter : certNotAfter ,
516
+ }, nil
517
+ }
505
518
506
- if s := roles .Strings (); len (s ) > 0 {
507
- rolesS = strings .Join (s , ", " )
519
+ // configInfoCommand implements `config info` command logic.
520
+ func configInfoCommand (config * clientconfig.Config , now time.Time ) (string , error ) {
521
+ info , err := configInfo (config , now )
522
+ if err != nil {
523
+ return "" , err
508
524
}
509
525
510
526
var res bytes.Buffer
511
- err = configInfoCmdTemplate .Execute (& res , map [string ]string {
512
- "Context" : config .Context ,
513
- "Nodes" : nodesS ,
514
- "Endpoints" : endpointsS ,
515
- "Roles" : rolesS ,
516
- "CertTTL" : certTTL ,
517
- "CertNotAfter" : certNotAfter ,
518
- })
527
+ err = configInfoCmdTemplate .Execute (& res , info )
519
528
520
529
return res .String () + "\n " , err
521
530
}
522
531
532
+ var configInfoCmdFlags struct {
533
+ output string
534
+ }
535
+
523
536
// configInfoCmd represents the `config info` command.
524
537
var configInfoCmd = & cobra.Command {
525
538
Use : "info" ,
@@ -531,14 +544,36 @@ var configInfoCmd = &cobra.Command{
531
544
return err
532
545
}
533
546
534
- res , err := configInfoCommand (c , time .Now ())
535
- if err != nil {
536
- return err
537
- }
547
+ switch configInfoCmdFlags .output {
548
+ case "text" :
549
+ res , err := configInfoCommand (c , time .Now ())
550
+ if err != nil {
551
+ return err
552
+ }
538
553
539
- fmt .Print (res )
554
+ fmt .Print (res )
540
555
541
- return nil
556
+ return nil
557
+ case "json" :
558
+ info , err := configInfo (c , time .Now ())
559
+ if err != nil {
560
+ return err
561
+ }
562
+
563
+ enc := json .NewEncoder (os .Stdout )
564
+ enc .SetIndent ("" , " " )
565
+
566
+ return enc .Encode (& info )
567
+ case "yaml" :
568
+ info , err := configInfo (c , time .Now ())
569
+ if err != nil {
570
+ return err
571
+ }
572
+
573
+ return yaml .NewEncoder (os .Stdout ).Encode (& info )
574
+ default :
575
+ return fmt .Errorf ("unknown output format: %q" , configInfoCmdFlags .output )
576
+ }
542
577
},
543
578
}
544
579
@@ -584,6 +619,8 @@ func init() {
584
619
configNewCmd .Flags ().StringSliceVar (& configNewCmdFlags .roles , "roles" , role .MakeSet (role .Admin ).Strings (), "roles" )
585
620
configNewCmd .Flags ().DurationVar (& configNewCmdFlags .crtTTL , "crt-ttl" , 87600 * time .Hour , "certificate TTL" )
586
621
622
+ configInfoCmd .Flags ().StringVarP (& configInfoCmdFlags .output , "output" , "o" , "text" , "output format (json|yaml|text). Default text." )
623
+
587
624
addCommand (configCmd )
588
625
}
589
626
0 commit comments