Permalink
Browse files

Fix/misc (#862)

* MySQL compatable SQL

* Mark not found errors properly

* Skip tests in sqlite mode

* variable rename

* Add URL for available domains

* split log and map admin clients

* Add min and max interval to domain info output

* Add vrf key handler

* Refresh domain list periodically

This change allows the sequencer to detect new domains.
This is especially important when a Key Transparency cluster is
being brought up for the first time since the sequencer starts before
any domains have been initialized.

* fixup tests

* Code review
  • Loading branch information...
gdbelvin committed Nov 22, 2017
1 parent 0025f9a commit e7150778d4abf5dfcc75e42909dc63634c02baf3
@@ -70,10 +70,10 @@ func main() {
if err != nil {
glog.Exitf("Error Dialing %v: %v", ktURL, err)
}
ktclient := gpb.NewKeyTransparencyServiceClient(cc)
mcc := gpb.NewMutationServiceClient(cc)
ktClient := gpb.NewKeyTransparencyServiceClient(cc)
mClient := gpb.NewMutationServiceClient(cc)
config, err := ktclient.GetDomainInfo(ctx, &pb.GetDomainInfoRequest{DomainId: *domainID})
config, err := ktClient.GetDomainInfo(ctx, &pb.GetDomainInfoRequest{DomainId: *domainID})
if err != nil {
glog.Exitf("Could not read domain info %v:", err)
}
@@ -87,7 +87,7 @@ func main() {
store := fake.NewMonitorStorage()
// Create monitoring background process.
mon, err := monitor.NewFromConfig(mcc, config, signer, store)
mon, err := monitor.NewFromConfig(mClient, config, signer, store)
if err != nil {
glog.Exitf("Failed to initialize monitor: %v", err)
}
@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"flag"
"time"
"github.com/google/keytransparency/core/adminserver"
"github.com/google/keytransparency/core/mutator/entry"
@@ -41,8 +42,9 @@ var (
serverDBPath = flag.String("db", "db", "Database connection string")
// Info to connect to the trillian map and log.
mapURL = flag.String("map-url", "", "URL of Trilian Map Server")
logURL = flag.String("log-url", "", "URL of Trillian Log Server for Signed Map Heads")
mapURL = flag.String("map-url", "", "URL of Trillian Map Server")
logURL = flag.String("log-url", "", "URL of Trillian Log Server for Signed Map Heads")
refresh = flag.Duration("domain-refresh", 5*time.Second, "Time to detect new domain")
)
func openDB() *sql.DB {
@@ -70,7 +72,8 @@ func main() {
}
tlog := trillian.NewTrillianLogClient(lconn)
tmap := trillian.NewTrillianMapClient(mconn)
tadmin := trillian.NewTrillianAdminClient(mconn)
logAdmin := trillian.NewTrillianAdminClient(lconn)
mapAdmin := trillian.NewTrillianAdminClient(mconn)
// Database tables
sqldb := openDB()
@@ -91,12 +94,12 @@ func main() {
keygen := func(ctx context.Context, spec *keyspb.Specification) (proto.Message, error) {
return der.NewProtoFromSpec(spec)
}
adminServer := adminserver.New(adminStorage, tadmin, keygen)
adminServer := adminserver.New(adminStorage, logAdmin, mapAdmin, keygen)
glog.Infof("Signer starting")
// Run servers
ctx := context.Background()
signer.StartSequencingAll(ctx)
signer.StartSequencingAll(ctx, *refresh)
run(adminServer)
glog.Errorf("Signer exiting")
@@ -18,24 +18,26 @@ import (
"flag"
"net/http"
"github.com/google/keytransparency/cmd/serverutil"
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus/promhttp"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
"github.com/google/keytransparency/cmd/serverutil"
ktpb "github.com/google/keytransparency/core/proto/keytransparency_v1_grpc"
gpb "github.com/google/keytransparency/core/proto/keytransparency_v1_grpc"
_ "github.com/google/trillian/crypto/keys/der/proto"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
)
var (
addr = flag.String("metrics-addr", ":8081", "The ip:port to publish metrics on")
addr = flag.String("addr", ":8080", "The ip:port to serve on")
keyFile = flag.String("tls-key", "genfiles/server.key", "TLS private key file")
certFile = flag.String("tls-cert", "genfiles/server.crt", "TLS cert file")
)
func run(svr ktpb.KeyTransparencyAdminServiceServer) {
func run(svr gpb.KeyTransparencyAdminServiceServer) {
// Wire up gRPC and HTTP servers.
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
if err != nil {
@@ -51,15 +53,15 @@ func run(svr ktpb.KeyTransparencyAdminServiceServer) {
glog.Exitf("Failed opening cert file %v: %v", *certFile, err)
}
gwmux, err := serverutil.GrpcGatewayMux(*addr, tcreds,
ktpb.RegisterKeyTransparencyAdminServiceHandlerFromEndpoint)
gpb.RegisterKeyTransparencyAdminServiceHandlerFromEndpoint)
if err != nil {
glog.Exitf("Failed setting up REST proxy: %v", err)
}
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
mux.Handle("/", gwmux)
ktpb.RegisterKeyTransparencyAdminServiceServer(grpcServer, svr)
gpb.RegisterKeyTransparencyAdminServiceServer(grpcServer, svr)
reflection.Register(grpcServer)
grpc_prometheus.Register(grpcServer)
grpc_prometheus.EnableHandlingTimeHistogram()
@@ -40,6 +40,7 @@ import (
gpb "github.com/google/keytransparency/core/proto/keytransparency_v1_grpc"
gauth "github.com/google/keytransparency/impl/google/authentication"
_ "github.com/google/trillian/crypto/keys/der/proto"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
)
@@ -82,17 +82,19 @@ var (
)
type server struct {
storage adminstorage.Storage
client tpb.TrillianAdminClient
keygen keys.ProtoGenerator
storage adminstorage.Storage
logAdmin tpb.TrillianAdminClient
mapAdmin tpb.TrillianAdminClient
keygen keys.ProtoGenerator
}
// New returns a KeyTransparencyAdminService implementation.
func New(storage adminstorage.Storage, client tpb.TrillianAdminClient, keygen keys.ProtoGenerator) gpb.KeyTransparencyAdminServiceServer {
func New(storage adminstorage.Storage, logAdmin, mapAdmin tpb.TrillianAdminClient, keygen keys.ProtoGenerator) gpb.KeyTransparencyAdminServiceServer {
return &server{
storage: storage,
client: client,
keygen: keygen,
storage: storage,
logAdmin: logAdmin,
mapAdmin: mapAdmin,
keygen: keygen,
}
}
@@ -124,20 +126,22 @@ func (s *server) ListDomains(ctx context.Context, in *pb.ListDomainsRequest) (*p
// fetchDomainInfo converts an amdin.Domain object into a pb.Domain object by fetching the relevant info from Trillian.
func (s *server) fetchDomainInfo(ctx context.Context, d *adminstorage.Domain) (*pb.Domain, error) {
logTree, err := s.client.GetTree(ctx, &tpb.GetTreeRequest{TreeId: d.LogID})
logTree, err := s.logAdmin.GetTree(ctx, &tpb.GetTreeRequest{TreeId: d.LogID})
if err != nil {
return nil, err
}
mapTree, err := s.client.GetTree(ctx, &tpb.GetTreeRequest{TreeId: d.MapID})
mapTree, err := s.mapAdmin.GetTree(ctx, &tpb.GetTreeRequest{TreeId: d.MapID})
if err != nil {
return nil, err
}
return &pb.Domain{
DomainId: d.Domain,
Log: logTree,
Map: mapTree,
Vrf: d.VRF,
Deleted: d.Deleted,
DomainId: d.Domain,
Log: logTree,
Map: mapTree,
Vrf: d.VRF,
MinInterval: ptypes.DurationProto(d.MinInterval),
MaxInterval: ptypes.DurationProto(d.MaxInterval),
Deleted: d.Deleted,
}, nil
}
@@ -177,13 +181,13 @@ func (s *server) CreateDomain(ctx context.Context, in *pb.CreateDomainRequest) (
// Create Trillian keys.
logTreeArgs := *logArgs
logTreeArgs.Tree.Description = fmt.Sprintf("KT domain %s's SMH Log", in.GetDomainId())
logTree, err := s.client.CreateTree(ctx, &logTreeArgs)
logTree, err := s.logAdmin.CreateTree(ctx, &logTreeArgs)
if err != nil {
return nil, fmt.Errorf("CreateTree(log): %v", err)
}
mapTreeArgs := *mapArgs
mapTreeArgs.Tree.Description = fmt.Sprintf("KT domain %s's Map", in.GetDomainId())
mapTree, err := s.client.CreateTree(ctx, &mapTreeArgs)
mapTree, err := s.mapAdmin.CreateTree(ctx, &mapTreeArgs)
if err != nil {
return nil, fmt.Errorf("CreateTree(map): %v", err)
}
@@ -25,6 +25,7 @@ import (
"github.com/google/trillian"
"github.com/google/trillian/crypto/keys/der"
"github.com/google/trillian/crypto/keyspb"
"github.com/google/trillian/storage/testdb"
"github.com/google/trillian/testonly/integration"
pb "github.com/google/keytransparency/core/proto/keytransparency_v1_proto"
@@ -37,6 +38,10 @@ func vrfKeyGen(ctx context.Context, spec *keyspb.Specification) (proto.Message,
}
func TestCreateRead(t *testing.T) {
// We can only run the integration tests if there is a MySQL instance available.
if provider := testdb.Default(); !provider.IsMySQL() {
t.Skipf("Skipping map integration test, SQL driver is %v", provider.Driver)
}
ctx := context.Background()
storage := fake.NewAdminStorage()
@@ -45,7 +50,7 @@ func TestCreateRead(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create trillian map server: %v", err)
}
svr := New(storage, mapEnv.AdminClient, vrfKeyGen)
svr := New(storage, mapEnv.AdminClient, mapEnv.AdminClient, vrfKeyGen)
for _, tc := range []struct {
domainID string
@@ -17,6 +17,7 @@ package keyserver
import (
"context"
"database/sql"
"github.com/google/keytransparency/core/adminstorage"
"github.com/google/keytransparency/core/authentication"
@@ -31,6 +32,7 @@ import (
"github.com/golang/protobuf/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
authzpb "github.com/google/keytransparency/core/proto/authorization_proto"
tpb "github.com/google/keytransparency/core/proto/keytransparency_v1_proto"
@@ -358,9 +360,12 @@ func (s *Server) GetDomainInfo(ctx context.Context, in *tpb.GetDomainInfoRequest
return nil, grpc.Errorf(codes.InvalidArgument, "Please specify a domain_id")
}
domain, err := s.admin.Read(ctx, in.DomainId, false)
if err != nil {
if err == sql.ErrNoRows {
glog.Errorf("adminstorage.Read(%v): %v", in.DomainId, err)
return nil, grpc.Errorf(codes.Internal, "Cannot fetch domain info")
return nil, status.Errorf(codes.NotFound, "Domain %v not found", in.DomainId)
} else if err != nil {
glog.Errorf("adminstorage.Read(%v): %v", in.DomainId, err)
return nil, grpc.Errorf(codes.Internal, "Cannot fetch domain info for %v", in.DomainId)
}
logTree, err := s.tadmin.GetTree(ctx, &trillian.GetTreeRequest{TreeId: domain.LogID})

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit e715077

Please sign in to comment.