Skip to content

Commit

Permalink
Implemented vault nodes storage.
Browse files Browse the repository at this point in the history
  • Loading branch information
nickeskov committed Aug 29, 2023
1 parent cf2d336 commit 3af1be5
Show file tree
Hide file tree
Showing 7 changed files with 443 additions and 61 deletions.
91 changes: 79 additions & 12 deletions cmd/nodemon/nodemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"flag"
"fmt"
"log"
"os"
"os/signal"
Expand All @@ -16,6 +15,7 @@ import (
"nodemon/pkg/analysis"
"nodemon/pkg/analysis/criteria"
"nodemon/pkg/api"
"nodemon/pkg/clients"
"nodemon/pkg/entities"
"nodemon/pkg/messaging/pair"
"nodemon/pkg/messaging/pubsub"
Expand Down Expand Up @@ -54,6 +54,53 @@ func main() {
}
}

type nodemonVaultConfig struct {
address string
user string
password string
mountPath string
secretPath string
}

func (n *nodemonVaultConfig) present() bool {
return n.address != ""
}

func newNodemonVaultConfig() *nodemonVaultConfig {
c := new(nodemonVaultConfig)
flag.StringVar(&c.address, "vault-address", "", "Vault server address.")
flag.StringVar(&c.user, "vault-user", "", "Vault user.")
flag.StringVar(&c.password, "vault-password", "", "Vault user's password.")
flag.StringVar(&c.mountPath, "vault-mount-path", "gonodemonitoring",
"Vault mount path for nodemon nodes storage.")
flag.StringVar(&c.secretPath, "vault-secret-path", "",
"Vault secret where nodemon nodes will be saved")
return c
}

func (n *nodemonVaultConfig) validate(logger *zap.Logger) error {
if n.address == "" { // skip further validation
return nil
}
if n.user == "" {
logger.Error("Empty vault user.")
return errInvalidParameters
}
if n.password == "" {
logger.Error("Empty vault password.")
return errInvalidParameters
}
if len(n.mountPath) == 0 {
logger.Error("Empty vault mount path")
return errInvalidParameters
}
if len(n.secretPath) == 0 {
logger.Error("Empty vault secret path")
return errInvalidParameters
}
return nil
}

type nodemonConfig struct {
storage string
nodes string
Expand All @@ -67,6 +114,7 @@ type nodemonConfig struct {
apiReadTimeout time.Duration
baseTargetThreshold int
logLevel string
vault *nodemonVaultConfig
}

func newNodemonConfig() *nodemonConfig {
Expand Down Expand Up @@ -95,31 +143,34 @@ func newNodemonConfig() *nodemonConfig {
"HTTP API read timeout. Default value is 30s.")
flag.StringVar(&c.logLevel, "log-level", "INFO",
"Logging level. Supported levels: DEBUG, INFO, WARN, ERROR, FATAL. Default logging level INFO.")
c.vault = newNodemonVaultConfig()
return c
}

func (c *nodemonConfig) validate(zap *zap.Logger) error {
if len(c.storage) == 0 || len(strings.Fields(c.storage)) > 1 {
zap.Error(fmt.Sprintf("Invalid storage path '%s'", c.storage))
return errInvalidParameters
func (c *nodemonConfig) validate(logger *zap.Logger) error {
if !c.vault.present() {
if len(c.storage) == 0 || len(strings.Fields(c.storage)) > 1 {
logger.Error("Invalid storage path", zap.String("path", c.storage))
return errInvalidParameters
}
}
if c.interval <= 0 {
zap.Error(fmt.Sprintf("Invalid polling interval '%s'", c.interval.String()))
logger.Error("Invalid polling interval", zap.Stringer("interval", c.interval))
return errInvalidParameters
}
if c.timeout <= 0 {
zap.Error(fmt.Sprintf("Invalid network timeout '%s'", c.timeout.String()))
logger.Error("Invalid network timeout", zap.Stringer("timeout", c.timeout))
return errInvalidParameters
}
if c.retention <= 0 {
zap.Error(fmt.Sprintf("Invalid retention duration '%s'", c.retention.String()))
logger.Error("Invalid retention duration", zap.Stringer("retention", c.retention))
return errInvalidParameters
}
if c.baseTargetThreshold == 0 {
zap.Error(fmt.Sprintf("Invalid base target threshold '%d'", c.baseTargetThreshold))
logger.Error("Invalid base target threshold", zap.Int("threshold", c.baseTargetThreshold))
return errInvalidParameters
}
return nil
return c.vault.validate(logger)
}

func (c *nodemonConfig) runDiscordPairServer() bool { return c.nanomsgPairDiscordURL != "" }
Expand Down Expand Up @@ -148,7 +199,23 @@ func run() error {
ctx, done := signal.NotifyContext(context.Background(), os.Interrupt)
defer done()

ns, err := nodes.NewJSONStorage(cfg.storage, strings.Fields(cfg.nodes), logger)
var ns nodes.Storage
if cfg.vault.present() {
cl, clErr := clients.NewVaultSimpleClient(ctx, logger, cfg.vault.address, cfg.vault.user, cfg.vault.password)
if clErr != nil {
logger.Error("failed to create vault client", zap.Error(err))
}
ns, err = nodes.NewJSONVaultStorage(
ctx,
cl,
cfg.vault.mountPath,
cfg.vault.secretPath,
strings.Fields(cfg.nodes),
logger,
)
} else {
ns, err = nodes.NewJSONFileStorage(cfg.storage, strings.Fields(cfg.nodes), logger)
}
if err != nil {
logger.Error("failed to initialize nodes storage", zap.Error(err))
return err
Expand Down Expand Up @@ -226,7 +293,7 @@ func runMessagingServices(
cfg *nodemonConfig,
alerts <-chan entities.Alert,
logger *zap.Logger,
ns *nodes.JSONStorage,
ns nodes.Storage,
es *events.Storage,
) {
go func() {
Expand Down
17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ go 1.19
require (
github.com/bwmarrin/discordgo v0.27.1
github.com/go-chi/chi v4.1.2+incompatible
github.com/hashicorp/vault/api v1.9.2
github.com/hashicorp/vault/api/auth/userpass v0.4.1
github.com/pkg/errors v0.9.1
github.com/procyon-projects/chrono v1.1.2
github.com/stretchr/testify v1.8.4
Expand All @@ -20,23 +22,37 @@ require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark v0.8.0 // indirect
github.com/consensys/gnark-crypto v0.9.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/zerolog v1.29.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/tidwall/btree v1.4.2 // indirect
github.com/tidwall/gjson v1.14.3 // indirect
github.com/tidwall/grect v0.1.4 // indirect
Expand All @@ -55,6 +71,7 @@ require (
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
golang.org/x/tools v0.12.0 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.55.0 // indirect
Expand Down
Loading

0 comments on commit 3af1be5

Please sign in to comment.