package main import ( "fmt" "os" "github.com/slackhq/nebula/cert" "gopkg.in/yaml.v3" ) var subCmdNebulaShow = subCmd{ name: "show", descr: "Writes nebula network information to stdout in yaml format", do: func(subCmdCtx subCmdCtx) error { flags := subCmdCtx.flagSet(false) if err := flags.Parse(subCmdCtx.args); err != nil { return fmt.Errorf("parsing flags: %w", err) } hostBootstrap, err := loadHostBootstrap() if err != nil { return fmt.Errorf("loading host bootstrap: %w", err) } caPublicCreds := hostBootstrap.Nebula.CAPublicCredentials caCert, _, err := cert.UnmarshalNebulaCertificateFromPEM([]byte(caPublicCreds.CertPEM)) if err != nil { return fmt.Errorf("unmarshaling ca.crt: %w", err) } if len(caCert.Details.Subnets) != 1 { return fmt.Errorf( "malformed ca.crt, contains unexpected subnets %#v", caCert.Details.Subnets, ) } subnet := caCert.Details.Subnets[0] type outLighthouse struct { PublicAddr string `yaml:"public_addr"` IP string `yaml:"ip"` } out := struct { CACert string `yaml:"ca_cert_pem"` SubnetCIDR string `yaml:"subnet_cidr"` Lighthouses []outLighthouse `yaml:"lighthouses"` }{ CACert: caPublicCreds.CertPEM, SubnetCIDR: subnet.String(), } for _, h := range hostBootstrap.Hosts { if h.Nebula.PublicAddr == "" { continue } out.Lighthouses = append(out.Lighthouses, outLighthouse{ PublicAddr: h.Nebula.PublicAddr, IP: h.IP().String(), }) } if err := yaml.NewEncoder(os.Stdout).Encode(out); err != nil { return fmt.Errorf("yaml encoding to stdout: %w", err) } return nil }, } var subCmdNebula = subCmd{ name: "nebula", descr: "Sub-commands related to the nebula VPN", do: func(subCmdCtx subCmdCtx) error { return subCmdCtx.doSubCmd( subCmdNebulaShow, ) }, }