cloud/{apigw,lib/component}: add cockroachdb client, sample schema
This sets up some boilerplate to connect to CockroachDB servers,
including test in-memory servers.
We also add a first pass apigw user table schema, as the first user of
this new functionality. We exercise that, in turn, in a test.
We also rename component.Configuration to component.ComponentConfig.
There's a stutter in there, but it makes sense with
component.CockroachConfig alongside.
Change-Id: I76691146b87ce135d60db179b3f51eee16525df7
Reviewed-on: https://review.monogon.dev/c/monogon/+/912
Reviewed-by: Leopold Schabel <leo@monogon.tech>
Vouch-Run-CI: Leopold Schabel <leo@monogon.tech>
Tested-by: Jenkins CI
diff --git a/cloud/apigw/server/server.go b/cloud/apigw/server/server.go
index b3b80bf..a068e84 100644
--- a/cloud/apigw/server/server.go
+++ b/cloud/apigw/server/server.go
@@ -15,13 +15,15 @@
"k8s.io/klog/v2"
apb "source.monogon.dev/cloud/api"
+ "source.monogon.dev/cloud/apigw/model"
"source.monogon.dev/cloud/lib/component"
)
// Config is the main configuration of the apigw server. It's usually populated
// from flags via RegisterFlags, but can also be set manually (eg. in tests).
type Config struct {
- component.Configuration
+ Component component.ComponentConfig
+ Database component.CockroachConfig
PublicListenAddress string
}
@@ -29,7 +31,8 @@
// RegisterFlags registers the component configuration to be provided by flags.
// This must be called exactly once before then calling flags.Parse().
func (c *Config) RegisterFlags() {
- c.Configuration.RegisterFlags("apigw")
+ c.Component.RegisterFlags("apigw")
+ c.Database.RegisterFlags("apigw_db")
flag.StringVar(&c.PublicListenAddress, "apigw_public_grpc_listen_address", ":8080", "Address to listen at for public/user gRPC connections for apigw")
}
@@ -51,8 +54,8 @@
}
func (s *Server) startInternalGRPC(ctx context.Context) {
- g := grpc.NewServer(s.Config.GRPCServerOptions()...)
- lis, err := net.Listen("tcp", s.Config.GRPCListenAddress)
+ g := grpc.NewServer(s.Config.Component.GRPCServerOptions()...)
+ lis, err := net.Listen("tcp", s.Config.Component.GRPCListenAddress)
if err != nil {
klog.Exitf("Could not listen: %v", err)
}
@@ -97,6 +100,20 @@
// Start runs the two listeners of the server. The process will fail (via
// klog.Exit) if any of the listeners/servers fail to start.
func (s *Server) Start(ctx context.Context) {
+ if s.Config.Database.Migrations == nil {
+ klog.Infof("Using default migrations source.")
+ m, err := model.MigrationsSource()
+ if err != nil {
+ klog.Exitf("failed to prepare migrations source: %w", err)
+ }
+ s.Config.Database.Migrations = m
+ }
+
+ klog.Infof("Running migrations...")
+ if err := s.Config.Database.MigrateUp(); err != nil {
+ klog.Exitf("Migrations failed: %v", err)
+ }
+ klog.Infof("Migrations done.")
s.startInternalGRPC(ctx)
s.startPublic(ctx)
}