boulder/cmd/boulder-publisher/main.go

118 lines
3.0 KiB
Go

package main
import (
"flag"
"os"
ct "github.com/google/certificate-transparency/go"
"google.golang.org/grpc"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/publisher"
pubPB "github.com/letsencrypt/boulder/publisher/proto"
"github.com/letsencrypt/boulder/rpc"
)
const clientName = "Publisher"
type config struct {
Publisher struct {
cmd.ServiceConfig
SubmissionTimeout cmd.ConfigDuration
MaxConcurrentRPCServerRequests int64
}
Statsd cmd.StatsdConfig
Syslog cmd.SyslogConfig
Common struct {
CT struct {
Logs []cmd.LogDescription
IntermediateBundleFilename string
}
}
}
func main() {
configFile := flag.String("config", "", "File path to the configuration file for this service")
flag.Parse()
if *configFile == "" {
flag.Usage()
os.Exit(1)
}
var c config
err := cmd.ReadConfigFile(*configFile, &c)
cmd.FailOnError(err, "Reading JSON config file into config structure")
stats, logger := cmd.StatsAndLogging(c.Statsd, c.Syslog)
scope := metrics.NewStatsdScope(stats, "Publisher")
defer logger.AuditPanic()
logger.Info(cmd.VersionString(clientName))
logs := make([]*publisher.Log, len(c.Common.CT.Logs))
for i, ld := range c.Common.CT.Logs {
logs[i], err = publisher.NewLog(ld.URI, ld.Key)
cmd.FailOnError(err, "Unable to parse CT log description")
}
if c.Common.CT.IntermediateBundleFilename == "" {
logger.AuditErr("No CT submission bundle provided")
os.Exit(1)
}
pemBundle, err := core.LoadCertBundle(c.Common.CT.IntermediateBundleFilename)
cmd.FailOnError(err, "Failed to load CT submission bundle")
bundle := []ct.ASN1Cert{}
for _, cert := range pemBundle {
bundle = append(bundle, ct.ASN1Cert(cert.Raw))
}
amqpConf := c.Publisher.AMQP
sa, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, scope)
cmd.FailOnError(err, "Unable to create SA client")
pubi := publisher.New(
bundle,
logs,
c.Publisher.SubmissionTimeout.Duration,
logger,
scope,
sa)
var grpcSrv *grpc.Server
if c.Publisher.GRPC != nil {
s, l, err := bgrpc.NewServer(c.Publisher.GRPC, scope)
cmd.FailOnError(err, "Unable to setup Publisher gRPC server")
gw := bgrpc.NewPublisherServerWrapper(pubi)
pubPB.RegisterPublisherServer(s, gw)
go func() {
err = s.Serve(l)
cmd.FailOnError(err, "Publisher gRPC service failed")
}()
grpcSrv = s
}
pubs, err := rpc.NewAmqpRPCServer(amqpConf, c.Publisher.MaxConcurrentRPCServerRequests, scope, logger)
cmd.FailOnError(err, "Unable to create Publisher RPC server")
go cmd.CatchSignals(logger, func() {
pubs.Stop()
if grpcSrv != nil {
grpcSrv.GracefulStop()
}
})
err = rpc.NewPublisherServer(pubs, pubi)
cmd.FailOnError(err, "Unable to setup Publisher RPC server")
go cmd.DebugServer(c.Publisher.DebugAddr)
go cmd.ProfileCmd(scope)
err = pubs.Start(amqpConf)
cmd.FailOnError(err, "Unable to run Publisher RPC server")
}