github.com/letsencrypt/boulder@v0.20251208.0/cmd/boulder-sa/main.go (about)

     1  package notmain
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"os"
     7  
     8  	"github.com/jmhodges/clock"
     9  
    10  	"github.com/letsencrypt/boulder/cmd"
    11  	"github.com/letsencrypt/boulder/config"
    12  	"github.com/letsencrypt/boulder/features"
    13  	bgrpc "github.com/letsencrypt/boulder/grpc"
    14  	"github.com/letsencrypt/boulder/sa"
    15  	sapb "github.com/letsencrypt/boulder/sa/proto"
    16  )
    17  
    18  type Config struct {
    19  	SA struct {
    20  		cmd.ServiceConfig
    21  		DB          cmd.DBConfig
    22  		ReadOnlyDB  cmd.DBConfig `validate:"-"`
    23  		IncidentsDB cmd.DBConfig `validate:"-"`
    24  
    25  		Features features.Config
    26  
    27  		// Max simultaneous SQL queries caused by a single RPC.
    28  		ParallelismPerRPC int `validate:"omitempty,min=1"`
    29  		// LagFactor is how long to sleep before retrying a read request that may
    30  		// have failed solely due to replication lag.
    31  		LagFactor config.Duration `validate:"-"`
    32  	}
    33  
    34  	Syslog        cmd.SyslogConfig
    35  	OpenTelemetry cmd.OpenTelemetryConfig
    36  }
    37  
    38  func main() {
    39  	grpcAddr := flag.String("addr", "", "gRPC listen address override")
    40  	debugAddr := flag.String("debug-addr", "", "Debug server address override")
    41  	configFile := flag.String("config", "", "File path to the configuration file for this service")
    42  	flag.Parse()
    43  	if *configFile == "" {
    44  		flag.Usage()
    45  		os.Exit(1)
    46  	}
    47  
    48  	var c Config
    49  	err := cmd.ReadConfigFile(*configFile, &c)
    50  	cmd.FailOnError(err, "Reading JSON config file into config structure")
    51  
    52  	features.Set(c.SA.Features)
    53  
    54  	if *grpcAddr != "" {
    55  		c.SA.GRPC.Address = *grpcAddr
    56  	}
    57  	if *debugAddr != "" {
    58  		c.SA.DebugAddr = *debugAddr
    59  	}
    60  
    61  	scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.SA.DebugAddr)
    62  	defer oTelShutdown(context.Background())
    63  	logger.Info(cmd.VersionString())
    64  
    65  	dbMap, err := sa.InitWrappedDb(c.SA.DB, scope, logger)
    66  	cmd.FailOnError(err, "While initializing dbMap")
    67  
    68  	dbReadOnlyMap := dbMap
    69  	if c.SA.ReadOnlyDB != (cmd.DBConfig{}) {
    70  		dbReadOnlyMap, err = sa.InitWrappedDb(c.SA.ReadOnlyDB, scope, logger)
    71  		cmd.FailOnError(err, "While initializing dbReadOnlyMap")
    72  	}
    73  
    74  	dbIncidentsMap := dbMap
    75  	if c.SA.IncidentsDB != (cmd.DBConfig{}) {
    76  		dbIncidentsMap, err = sa.InitWrappedDb(c.SA.IncidentsDB, scope, logger)
    77  		cmd.FailOnError(err, "While initializing dbIncidentsMap")
    78  	}
    79  
    80  	clk := clock.New()
    81  
    82  	parallel := max(c.SA.ParallelismPerRPC, 1)
    83  
    84  	tls, err := c.SA.TLS.Load(scope)
    85  	cmd.FailOnError(err, "TLS config")
    86  
    87  	saroi, err := sa.NewSQLStorageAuthorityRO(
    88  		dbReadOnlyMap, dbIncidentsMap, scope, parallel, c.SA.LagFactor.Duration, clk, logger)
    89  	cmd.FailOnError(err, "Failed to create read-only SA impl")
    90  
    91  	sai, err := sa.NewSQLStorageAuthorityWrapping(saroi, dbMap, scope)
    92  	cmd.FailOnError(err, "Failed to create SA impl")
    93  
    94  	start, err := bgrpc.NewServer(c.SA.GRPC, logger).WithCheckInterval(c.SA.HealthCheckInterval.Duration).Add(
    95  		&sapb.StorageAuthorityReadOnly_ServiceDesc, saroi).Add(
    96  		&sapb.StorageAuthority_ServiceDesc, sai).Build(
    97  		tls, scope, clk)
    98  	cmd.FailOnError(err, "Unable to setup SA gRPC server")
    99  
   100  	cmd.FailOnError(start(), "SA gRPC service failed")
   101  }
   102  
   103  func init() {
   104  	cmd.RegisterCommand("boulder-sa", main, &cmd.ConfigValidator{Config: &Config{}})
   105  }