Skip to content

Commit

Permalink
feat: Add blob storage capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
sjbodzo authored and mikhailswift committed Jun 23, 2022
1 parent 73724b6 commit 94fb9f3
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 55 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM golang:1.18.1-alpine AS build
WORKDIR /src
RUN apk add --no-cache file git
RUN apk update && apk add --no-cache file git
ENV GOMODCACHE /root/.cache/gocache
RUN --mount=target=. --mount=target=/root/.cache,type=cache \
CGO_ENABLED=0 go build -o /out/archivist -ldflags '-s -d -w' ./cmd/archivist; \
Expand Down
118 changes: 76 additions & 42 deletions cmd/archivist/main.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ package main

import (
"context"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"time"

"github.com/testifysec/archivist/internal/storage/filestore"

"github.com/testifysec/archivist-api/pkg/api/archivist"
"github.com/testifysec/archivist/internal/config"
"github.com/testifysec/archivist/internal/server"
"github.com/testifysec/archivist/internal/storage/blob"
"github.com/testifysec/archivist/internal/storage/filestore"
"github.com/testifysec/archivist/internal/storage/mysqlstore"

nested "github.com/antonfisher/nested-logrus-formatter"
Expand All @@ -39,6 +41,7 @@ import (
"github.com/networkservicemesh/sdk/pkg/tools/log"
"github.com/networkservicemesh/sdk/pkg/tools/log/logruslogger"
"github.com/sirupsen/logrus"
"github.com/spiffe/go-spiffe/v2/spiffeid"
"github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig"
"github.com/spiffe/go-spiffe/v2/svid/x509svid"
"github.com/spiffe/go-spiffe/v2/workloadapi"
Expand All @@ -56,28 +59,16 @@ func main() {
)
defer cancel()

// ********************************************************************************
// Setup logging
// ********************************************************************************
logrus.SetFormatter(&nested.Formatter{})
log.EnableTracing(true)
ctx = log.WithLog(ctx, logruslogger.New(ctx, map[string]interface{}{"cmd": os.Args[0]}))

// ********************************************************************************
// Debug self if necessary
// ********************************************************************************

if err := debug.Self(); err != nil {
log.FromContext(ctx).Infof("%s", err)
}

startTime := time.Now()

// enumerating phases

// ********************************************************************************
log.FromContext(ctx).Infof("executing phase 1: get config from environment (time since start: %s)", time.Since(startTime))
// ********************************************************************************
now := time.Now()

cfg := new(config.Config)
Expand All @@ -92,50 +83,36 @@ func main() {
logrus.SetLevel(level)

log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 1: get config from environment")
// ********************************************************************************

log.FromContext(ctx).Infof("executing phase 2: get spiffe svid (time since start: %s)", time.Since(startTime))
// ********************************************************************************
now = time.Now()
var source *workloadapi.X509Source
var svid *x509svid.SVID

log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 2: retrieve spiffe svid")
grpcOptions := make([]grpc.ServerOption, 0)
if cfg.EnableSPIFFE == true {
source, err = workloadapi.NewX509Source(ctx)
if err != nil {
logrus.Fatalf("error getting x509 source: %+v", err)
}
svid, err = source.GetX509SVID()
if err != nil {
logrus.Fatalf("error getting x509 svid: %+v", err)
}
logrus.Infof("SVID: %q", svid.ID)
log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 2: retrieve spiffe svid")
opts := initSpiffeConnection(ctx, cfg)
grpcOptions = append(grpcOptions, opts...)
} else {
log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 2: SKIPPED")
}

// ********************************************************************************
log.FromContext(ctx).Infof("executing phase 3: initializing storage clients (time since start: %s)", time.Since(startTime))
// ********************************************************************************
now = time.Now()

// TODO make the fileserver optional
fileStore, fileStoreCh, err := filestore.NewServer(ctx, cfg.FileDir, cfg.FileServeOn)

mysqlStore, mysqlStoreCh, err := mysqlstore.NewServer(ctx, "", fileStore)
fileStore, fileStoreCh, err := initObjectStore(ctx, cfg)
if err != nil {
logrus.Fatalf("error starting badger mysqlStore: %+v", err)
logrus.Fatalf("error initializing storage clients: %w", err)
}

log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 3: initializing badger")
mysqlStore, mysqlStoreCh, err := mysqlstore.NewServer(ctx, "", fileStore)

log.FromContext(ctx).WithField("duration", time.Since(now)).Infof("completed phase 3: initializing storage clients")
// ********************************************************************************
log.FromContext(ctx).Infof("executing phase 4: create and register grpc service (time since start: %s)", time.Since(startTime))
// ********************************************************************************
now = time.Now()

grpcOptions := make([]grpc.ServerOption, 0)
if cfg.EnableSPIFFE == true {
grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(tlsconfig.MTLSServerConfig(source, source, tlsconfig.AuthorizeAny()))))
}

grpcServer := grpc.NewServer(grpcOptions...)
archivistService := server.NewArchivistServer(mysqlStore)
archivist.RegisterArchivistServer(grpcServer, archivistService)
Expand All @@ -155,9 +132,66 @@ func main() {
<-fileStoreCh
<-mysqlStoreCh

//// ********************************************************************************
log.FromContext(ctx).Infof("exiting, uptime: %v", time.Since(startTime))
//// ********************************************************************************
}

func initSpiffeConnection(ctx context.Context, cfg *config.Config) []grpc.ServerOption {
var source *workloadapi.X509Source
var svid *x509svid.SVID
var authorizer tlsconfig.Authorizer

if cfg.SPIFFETrustedServerId != "" {
trustID := spiffeid.RequireFromString(cfg.SPIFFETrustedServerId)
authorizer = tlsconfig.AuthorizeID(trustID)
} else {
authorizer = tlsconfig.AuthorizeAny()
}

workloadOpts := []workloadapi.X509SourceOption{
workloadapi.WithClientOptions(workloadapi.WithAddr(cfg.SPIFFEAddress)),
}
source, err := workloadapi.NewX509Source(ctx, workloadOpts...)
if err != nil {
logrus.Fatalf("error getting x509 source: %+v", err)
}
opts := []grpc.ServerOption{
grpc.Creds(credentials.NewTLS(tlsconfig.MTLSServerConfig(source, source, authorizer))),
}

svid, err = source.GetX509SVID()
if err != nil {
logrus.Fatalf("error getting x509 svid: %+v", err)
}
logrus.Infof("SVID: %q", svid.ID)
return opts
}

func initObjectStore(ctx context.Context, cfg *config.Config) (archivist.CollectorServer, <-chan error, error) {
switch strings.ToUpper(cfg.StorageBackend) {
case "FILE":
return filestore.NewServer(ctx, cfg.FileDir, cfg.FileServeOn)

case "BLOB":
return blob.NewMinioClient(
ctx,
cfg.BlobStoreEndpoint,
cfg.BlobStoreAccessKeyId,
cfg.BlobStoreSecretAccessKeyId,
cfg.BlobStoreBucketName,
cfg.BlobStoreUseSSL,
)

case "":
errCh := make(chan error)
go func() {
<-ctx.Done()
close(errCh)
}()
return nil, errCh, nil

default:
return nil, nil, fmt.Errorf("unknown storage backend: %s", cfg.StorageBackend)
}
}

func exitOnErrCh(ctx context.Context, cancel context.CancelFunc, errCh <-chan error) {
Expand Down
Empty file modified cmd/archivistctl/main.go
100755 → 100644
Empty file.
3 changes: 3 additions & 0 deletions go.mod
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/go-sql-driver/mysql v1.6.0
github.com/gorilla/handlers v1.5.1
github.com/kelseyhightower/envconfig v1.4.0
github.com/minio/minio-go v6.0.14+incompatible
github.com/networkservicemesh/sdk v1.3.0
github.com/sirupsen/logrus v1.8.1
github.com/spiffe/go-spiffe/v2 v2.0.0
Expand All @@ -25,6 +26,7 @@ require (
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/go-ini/ini v1.66.4 // indirect
github.com/go-logr/logr v1.2.1 // indirect
github.com/go-logr/stdr v1.2.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
Expand All @@ -34,6 +36,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/hashicorp/hcl/v2 v2.10.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/networkservicemesh/api v1.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2H
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/git-bom/gitbom-go v0.0.0-20220502033008-4a48bb2317f7 h1:unHPfG96U9hCpN3oOMPSecP8PjyGhMGw/osjFm90e4o=
github.com/git-bom/gitbom-go v0.0.0-20220502033008-4a48bb2317f7/go.mod h1:xZ9N3/niYCZoKvc7ZlHq54lYvnb/U7l8ORLYf0irM1I=
github.com/go-ini/ini v1.66.4 h1:dKjMqkcbkzfddhIhyglTPgMoJnkvmG+bSLrU9cTHc5M=
github.com/go-ini/ini v1.66.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.1 h1:DX7uPQ4WgAWfoh+NGGlbJQswnYIVvz0SRlLS3rPZQDA=
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
Expand Down Expand Up @@ -187,6 +189,10 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mna/pigeon v0.0.0-20180808201053-bb0192cfc2ae/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
Expand Down
20 changes: 15 additions & 5 deletions internal/config/config.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@ import (
)

type Config struct {
EnableSPIFFE bool `default:"TRUE" desc:"Enable SPIFFE support" split_words:"true"`
ListenOn url.URL `default:"unix:///listen.on.socket" desc:"url to listen on" split_words:"true"`
LogLevel string `default:"INFO" desc:"Log level" split_words:"true"`
ListenOn url.URL `default:"unix:///listen.on.socket" desc:"url to listen on" split_words:"true"`
LogLevel string `default:"INFO" desc:"Log level" split_words:"true"`

FileServeOn string `default:"" desc:"What address to serve files on, leave empty to shut off" split_words:"true"`
FileDir string `default:"/tmp/archivist/" desc:"Directory to store and serve files" split_words:"true"`
EnableSPIFFE bool `default:"TRUE" desc:"Enable SPIFFE support" split_words:"true"`
SPIFFEAddress string `default:"unix:///tmp/spire-agent/public/api.sock" desc:"SPIFFE server address" split_words:"true"`
SPIFFETrustedServerId string `default:"" desc:"Trusted SPIFFE server ID; defaults to any" split_words:"true"`
SQLStoreConnectionString string `default:"root:example@tcp(db)/testify" desc:"SQL store connection string" split_words:"true"`

StorageBackend string `default:"" desc:"Backend to use for attestation storage. Options are FILE, BLOB, or empty string for disabled." split_words:"true"`
FileServeOn string `default:"" desc:"What address to serve files on. Only valid when using FILE storage backend." split_words:"true"`
FileDir string `default:"/tmp/archivist/" desc:"Directory to store and serve files. Only valid when using FILE storage backend." split_words:"true"`
BlobStoreEndpoint string `default:"127.0.0.1:9000" desc:"URL endpoint for blob storage. Only valid when using BLOB storage backend." split_words:"true"`
BlobStoreAccessKeyId string `default:"" desc:"Blob store access key id. Only valid when using BLOB storage backend." split_words:"true"`
BlobStoreSecretAccessKeyId string `default:"" desc:"Blob store secret access key id. Only valid when using BLOB storage backend." split_words:"true"`
BlobStoreUseSSL bool `default:"TRUE" desc:"Use SSL for BLOB storage backend. Only valid when using BLOB storage backend." split_words:"true"`
BlobStoreBucketName string `default:"" desc:"Bucket to use for storage. Only valid when using BLOB storage backend." split_words:"true"`
}

// Process reads config from env
Expand Down
Empty file modified internal/server/server.go
100755 → 100644
Empty file.
Loading

0 comments on commit 94fb9f3

Please sign in to comment.