Implement config generator
This commit adds code to allow the generation of a default client configuration. The generator is run instead of the regular client code, when the option -generate-config is passed on the command line.
This commit is contained in:
parent
da24ae70b6
commit
c65853d1f9
3 changed files with 87 additions and 40 deletions
|
@ -20,9 +20,12 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"git.cacert.org/cacert-gosigner/pkg/protocol"
|
||||
"git.cacert.org/cacert-gosignerclient/internal/client"
|
||||
|
@ -42,9 +45,9 @@ const (
|
|||
|
||||
func main() {
|
||||
var (
|
||||
showVersion, verbose bool
|
||||
configFile, logLevel string
|
||||
logger *logrus.Logger
|
||||
showVersion, verbose, generateConfig bool
|
||||
configFile, logLevel string
|
||||
logger *logrus.Logger
|
||||
)
|
||||
|
||||
logger = logrus.New()
|
||||
|
@ -56,6 +59,12 @@ func main() {
|
|||
flag.StringVar(&configFile, "config", defaultConfigFile, "signer client configuration file")
|
||||
flag.BoolVar(&showVersion, "version", false, "show version")
|
||||
flag.BoolVar(&verbose, "verbose", false, "verbose output")
|
||||
flag.BoolVar(
|
||||
&generateConfig,
|
||||
"generate-config",
|
||||
false,
|
||||
"generate a configuration file with default values instead of running the client",
|
||||
)
|
||||
flag.StringVar(&logLevel, "loglevel", "INFO", "log level")
|
||||
|
||||
flag.Parse()
|
||||
|
@ -71,9 +80,45 @@ func main() {
|
|||
|
||||
logger.SetLevel(parsedLevel)
|
||||
|
||||
if generateConfig {
|
||||
if err = generateDefaultConfig(); err != nil {
|
||||
logger.WithError(err).Fatal("could not generate default configuration")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err := startClient(configFile, logger); err != nil {
|
||||
logger.WithError(err).Fatal("client failure")
|
||||
}
|
||||
}
|
||||
|
||||
func generateDefaultConfig() error {
|
||||
const defaultBaseConfiguration = `---
|
||||
serial:
|
||||
device: /dev/ttyUSB0
|
||||
baud: 112500
|
||||
`
|
||||
|
||||
cfg, err := config.LoadConfiguration(strings.NewReader(
|
||||
defaultBaseConfiguration))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not load empty configuration: %w", err)
|
||||
}
|
||||
|
||||
enc := yaml.NewEncoder(os.Stdout)
|
||||
|
||||
if err = enc.Encode(cfg); err != nil {
|
||||
return fmt.Errorf("could not encode: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func startClient(configFile string, logger *logrus.Logger) error {
|
||||
clientConfig, err := config.New(configFile)
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("could not configure client")
|
||||
return fmt.Errorf("could not configure client: %w", err)
|
||||
}
|
||||
|
||||
commands := make(chan *protocol.Command)
|
||||
|
@ -81,12 +126,12 @@ func main() {
|
|||
|
||||
clientHandler, err := handler.New(clientConfig, logger, commands, callbacks)
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("could not setup client handler")
|
||||
return fmt.Errorf("could not setup client handler: %w", err)
|
||||
}
|
||||
|
||||
signerClient, err := client.New(clientConfig, logger, clientHandler, commands, callbacks)
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("could not setup client")
|
||||
return fmt.Errorf("could not setup client: %w", err)
|
||||
}
|
||||
|
||||
defer func() { _ = signerClient.Close() }()
|
||||
|
@ -94,6 +139,8 @@ func main() {
|
|||
logger.Info("setup complete, starting client operation")
|
||||
|
||||
if err = signerClient.Run(context.Background()); err != nil {
|
||||
logger.WithError(err).Fatal("error in client")
|
||||
return fmt.Errorf("error in client: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -432,24 +432,16 @@ func (c *Client) updateCRL(d *messages.FetchCRLResponse) ([]*protocol.Command, e
|
|||
}
|
||||
|
||||
func (c *Client) buildCRLFileName(caName string) string {
|
||||
return path.Join(c.config.PublicDataDirectory, fmt.Sprintf("%s.crl", caName))
|
||||
return path.Join(c.config.PublicCRLDirectory, fmt.Sprintf("%s.crl", caName))
|
||||
}
|
||||
|
||||
func (c *Client) buildCertificateFileName(caName string, certFormat string) string {
|
||||
return path.Join(c.config.PublicDataDirectory, fmt.Sprintf("%s.%s", caName, certFormat))
|
||||
}
|
||||
|
||||
func (c *Client) ensurePublicDataDirectory() error {
|
||||
if err := os.MkdirAll(c.config.PublicDataDirectory, worldReadableDirPerm); err != nil {
|
||||
return fmt.Errorf("could not create public CA data directory %s: %w", c.config.PublicDataDirectory, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return path.Join(c.config.PublicCRLDirectory, fmt.Sprintf("%s.%s", caName, certFormat))
|
||||
}
|
||||
|
||||
func (c *Client) writeCertificate(caName string, derBytes []byte) error {
|
||||
if err := c.ensurePublicDataDirectory(); err != nil {
|
||||
return err
|
||||
if err := os.MkdirAll(c.config.PublicCRLDirectory, worldReadableDirPerm); err != nil {
|
||||
return fmt.Errorf("could not create public CA data directory %s: %w", c.config.PublicCRLDirectory, err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(
|
||||
|
@ -470,8 +462,8 @@ func (c *Client) writeCertificate(caName string, derBytes []byte) error {
|
|||
}
|
||||
|
||||
func (c *Client) writeCRL(caName string, crlBytes []byte) error {
|
||||
if err := c.ensurePublicDataDirectory(); err != nil {
|
||||
return err
|
||||
if err := os.MkdirAll(c.config.PublicCRLDirectory, worldReadableDirPerm); err != nil {
|
||||
return fmt.Errorf("could not create public CA data directory %s: %w", c.config.PublicCRLDirectory, err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(c.buildCRLFileName(caName), crlBytes, worldReadableFilePerm); err != nil {
|
||||
|
|
|
@ -52,26 +52,28 @@ type Serial struct {
|
|||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
Serial Serial `yaml:"serial"`
|
||||
HealthInterval time.Duration `yaml:"health-interval"`
|
||||
HealthStart time.Duration `yaml:"health-start"`
|
||||
FetchCRLStart time.Duration `yaml:"fetch-crl-start"`
|
||||
FetchCRLInterval time.Duration `yaml:"fetch-crl-interval"`
|
||||
ResponseAnnounceTimeout time.Duration `yaml:"response-announce-timeout"`
|
||||
ResponseDataTimeout time.Duration `yaml:"response-data-timeout"`
|
||||
PublicDataDirectory string `yaml:"public-data-directory"`
|
||||
Serial Serial `yaml:"serial"`
|
||||
HealthInterval time.Duration `yaml:"health-interval"`
|
||||
HealthStart time.Duration `yaml:"health-start"`
|
||||
FetchCRLStart time.Duration `yaml:"fetch-crl-start"`
|
||||
FetchCRLInterval time.Duration `yaml:"fetch-crl-interval"`
|
||||
ResponseAnnounceTimeout time.Duration `yaml:"response-announce-timeout"`
|
||||
ResponseDataTimeout time.Duration `yaml:"response-data-timeout"`
|
||||
PublicCRLDirectory string `yaml:"public-crl-directory"`
|
||||
PublicCertificateDirectory string `yaml:"public-certificate-directory"`
|
||||
}
|
||||
|
||||
func (c *ClientConfig) UnmarshalYAML(n *yaml.Node) error {
|
||||
data := struct {
|
||||
Serial Serial `yaml:"serial"`
|
||||
HealthInterval time.Duration `yaml:"health-interval"`
|
||||
HealthStart time.Duration `yaml:"health-start"`
|
||||
FetchCRLStart time.Duration `yaml:"fetch-crl-start"`
|
||||
FetchCRLInterval time.Duration `yaml:"fetch-crl-interval"`
|
||||
ResponseAnnounceTimeout time.Duration `yaml:"response-announce-timeout"`
|
||||
ResponseDataTimeout time.Duration `yaml:"response-data-timeout"`
|
||||
PublicDataDirectory string `yaml:"public-data-directory"`
|
||||
Serial Serial `yaml:"serial"`
|
||||
HealthInterval time.Duration `yaml:"health-interval"`
|
||||
HealthStart time.Duration `yaml:"health-start"`
|
||||
FetchCRLStart time.Duration `yaml:"fetch-crl-start"`
|
||||
FetchCRLInterval time.Duration `yaml:"fetch-crl-interval"`
|
||||
ResponseAnnounceTimeout time.Duration `yaml:"response-announce-timeout"`
|
||||
ResponseDataTimeout time.Duration `yaml:"response-data-timeout"`
|
||||
PublicCRLDirectory string `yaml:"public-crl-directory"`
|
||||
PublicCertificateDirectory string `yaml:"public-certificate-directory"`
|
||||
}{}
|
||||
|
||||
err := n.Decode(&data)
|
||||
|
@ -129,11 +131,17 @@ func (c *ClientConfig) UnmarshalYAML(n *yaml.Node) error {
|
|||
|
||||
c.ResponseDataTimeout = data.ResponseDataTimeout
|
||||
|
||||
if data.PublicDataDirectory == "" {
|
||||
data.PublicDataDirectory = defaultFilesDirectory
|
||||
if data.PublicCRLDirectory == "" {
|
||||
data.PublicCRLDirectory = defaultFilesDirectory
|
||||
}
|
||||
|
||||
c.PublicDataDirectory = data.PublicDataDirectory
|
||||
c.PublicCRLDirectory = data.PublicCRLDirectory
|
||||
|
||||
if data.PublicCertificateDirectory == "" {
|
||||
data.PublicCertificateDirectory = defaultFilesDirectory
|
||||
}
|
||||
|
||||
c.PublicCertificateDirectory = data.PublicCRLDirectory
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue