Merge pull request #58 from carlaKC/configfile-flag

aperture: allow command line flags and add config file
This commit is contained in:
Oliver Gugger
2021-09-28 10:34:03 +02:00
committed by GitHub
3 changed files with 121 additions and 22 deletions

View File

@@ -2,6 +2,7 @@ package aperture
import (
"crypto/tls"
"errors"
"fmt"
"io"
"io/ioutil"
@@ -11,9 +12,11 @@ import (
"sync"
"time"
flags "github.com/jessevdk/go-flags"
"github.com/lightninglabs/aperture/auth"
"github.com/lightninglabs/aperture/mint"
"github.com/lightninglabs/aperture/proxy"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/cert"
"github.com/lightningnetwork/lnd/lnrpc"
@@ -71,10 +74,21 @@ var (
func Main() {
// TODO: Prevent from running twice.
err := run()
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
// Unwrap our error and check whether help was requested from our flag
// library. If the error is not wrapped, Unwrap returns nil. It is
// still safe to check the type of this nil error.
flagErr, isFlagErr := errors.Unwrap(err).(*flags.Error)
isHelpErr := isFlagErr && flagErr.Type == flags.ErrHelp
// If we got a nil error, or help was requested, just exit.
if err == nil || isHelpErr {
os.Exit(0)
}
// Print any other non-help related errors.
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// run sets up the proxy server and runs it. This function blocks until a
@@ -88,10 +102,9 @@ func run() error {
}
// Next, parse configuration file and set up logging.
configFile := filepath.Join(apertureDataDir, defaultConfigFilename)
cfg, err := getConfig(configFile)
cfg, err := getConfig()
if err != nil {
return fmt.Errorf("unable to parse config file: %v", err)
return fmt.Errorf("unable to parse config file: %w", err)
}
err = setupLogging(cfg, interceptor)
if err != nil {
@@ -305,22 +318,66 @@ func fileExists(name string) bool {
// getConfig loads and parses the configuration file then checks it for valid
// content.
func getConfig(configFile string) (*Config, error) {
func getConfig() (*Config, error) {
// Pre-parse command line flags to determine whether we've been pointed
// to a custom config file.
cfg := &Config{}
b, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, err
}
err = yaml.Unmarshal(b, cfg)
if err != nil {
if _, err := flags.Parse(cfg); err != nil {
return nil, err
}
// If a custom config file is provided, we require that it exists.
var mustExist bool
configFile := filepath.Join(apertureDataDir, defaultConfigFilename)
if cfg.ConfigFile != "" {
configFile = lnd.CleanAndExpandPath(cfg.ConfigFile)
mustExist = true
}
// Read our config file, either from the custom path provided or our
// default location.
b, err := ioutil.ReadFile(configFile)
switch {
// If the file was found, unmarshal it.
case err == nil:
err = yaml.Unmarshal(b, cfg)
if err != nil {
return nil, err
}
// If the error is unrelated to the existence of the file, we must
// always return it.
case !os.IsNotExist(err):
return nil, err
// If we require that the config file exists and we got an error
// related to file existence, we must fail.
case mustExist && os.IsNotExist(err):
return nil, fmt.Errorf("config file: %v must exist: %w",
configFile, err)
}
// Finally, parse the remaining command line options again to ensure
// they take precedence.
if _, err := flags.Parse(cfg); err != nil {
return nil, err
}
// Clean and expand our cert and macaroon paths.
cfg.Authenticator.TLSPath = lnd.CleanAndExpandPath(
cfg.Authenticator.TLSPath,
)
cfg.Authenticator.MacDir = lnd.CleanAndExpandPath(
cfg.Authenticator.MacDir,
)
// Then check the configuration that we got from the config file, all
// required values need to be set at this point.
if cfg.ListenAddr == "" {
return nil, fmt.Errorf("missing listen address for server")
if err := cfg.validate(); err != nil {
return nil, err
}
return cfg, nil
}

View File

@@ -1,6 +1,9 @@
package aperture
import (
"errors"
"fmt"
"github.com/btcsuite/btcutil"
"github.com/lightninglabs/aperture/proxy"
)
@@ -26,13 +29,34 @@ type AuthConfig struct {
// LndHost is the hostname of the LND instance to connect to.
LndHost string `long:"lndhost" description:"Hostname of the LND instance to connect to"`
TLSPath string `long:"tlspath"`
TLSPath string `long:"tlspath" description:"Path to LND instance's tls certificate"`
MacDir string `long:"macdir"`
MacDir string `long:"macdir" description:"Directory containing LND instance's macaroons"`
Network string `long:"network"`
Network string `long:"network" description:"The network LND is connected to." choice:"regtest" choice:"simnet" choice:"testnet" choice:"mainnet"`
Disable bool `long:"disable"`
Disable bool `long:"disable" description:"Whether to disable LND auth."`
}
func (a *AuthConfig) validate() error {
// If we're disabled, we don't mind what these values are.
if a.Disable {
return nil
}
if a.LndHost == "" {
return errors.New("lnd host required")
}
if a.TLSPath == "" {
return errors.New("lnd tls required")
}
if a.MacDir == "" {
return errors.New("lnd mac dir required")
}
return nil
}
type TorConfig struct {
@@ -67,11 +91,11 @@ type Config struct {
// directory defined by StaticRoot.
ServeStatic bool `long:"servestatic" description:"Flag to enable or disable static content serving."`
Etcd *EtcdConfig `long:"etcd" description:"Configuration for the etcd instance backing the proxy."`
Etcd *EtcdConfig `group:"etcd" namespace:"etcd"`
Authenticator *AuthConfig `long:"authenticator" description:"Configuration for the authenticator."`
Authenticator *AuthConfig `group:"authenticator" namespace:"authenticator"`
Tor *TorConfig `long:"tor" description:"Configuration for the Tor instance backing the proxy."`
Tor *TorConfig `group:"tor" namespace:"tor"`
// Services is a list of JSON objects in string format, which specify
// each backend service to Aperture.
@@ -80,4 +104,21 @@ type Config struct {
// DebugLevel is a string defining the log level for the service either
// for all subsystems the same or individual level by subsystem.
DebugLevel string `long:"debuglevel" description:"Debug level for the Aperture application and its subsystems."`
// ConfigFile points aperture to an alternative config file.
ConfigFile string `long:"configfile" description:"Custom path to a config file."`
}
func (c *Config) validate() error {
if c.Authenticator != nil {
if err := c.Authenticator.validate(); err != nil {
return err
}
}
if c.ListenAddr == "" {
return fmt.Errorf("missing listen address for server")
}
return nil
}

1
go.mod
View File

@@ -9,6 +9,7 @@ require (
github.com/btcsuite/btcwallet/wtxmgr v1.3.1-0.20210706234807-aaf03fee735a
github.com/fortytw2/leaktest v1.3.0
github.com/golang/protobuf v1.5.2
github.com/jessevdk/go-flags v1.4.0
github.com/lightninglabs/lndclient v0.12.0-9
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210728112744-ebabda671786
github.com/lightningnetwork/lnd/cert v1.0.3