first mvp
This commit is contained in:
parent
9b5bda5042
commit
523485f307
13 changed files with 289 additions and 72 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -27,3 +27,5 @@ examples/testing/
|
||||||
|
|
||||||
*.toml
|
*.toml
|
||||||
!examples/*.toml
|
!examples/*.toml
|
||||||
|
|
||||||
|
test/
|
||||||
|
|
|
@ -6,15 +6,13 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/cli"
|
"code.lila.network/adoralaura/certwarden-deploy/internal/cli"
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/config"
|
"code.lila.network/adoralaura/certwarden-deploy/internal/configuration"
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/logger"
|
"github.com/getsentry/sentry-go"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cfgFile string
|
|
||||||
|
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
func Execute() {
|
func Execute() {
|
||||||
|
@ -22,14 +20,14 @@ func Execute() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
defer sentry.Flush(2 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(config.InitializeConfig, logger.InitializeLogger)
|
|
||||||
|
|
||||||
cli.RootCmd.PersistentFlags().BoolVarP(&config.VerboseLogging, "verbose", "v", false, "Enable verbose logging")
|
cli.RootCmd.PersistentFlags().BoolVarP(&configuration.VerboseLogging, "verbose", "v", false, "Enable verbose logging")
|
||||||
cli.RootCmd.PersistentFlags().BoolVarP(&config.DryRun, "dry-run", "d", false, "Just show the would-be changes without changing the file system")
|
cli.RootCmd.PersistentFlags().BoolVarP(&configuration.DryRun, "dry-run", "d", false, "Just show the would-be changes without changing the file system (turns on verbose logging)")
|
||||||
cli.RootCmd.PersistentFlags().BoolVarP(&config.QuietLogging, "quiet", "q", false, "Disable any logging (if both -q and -v are set, quiet wins)")
|
cli.RootCmd.PersistentFlags().BoolVarP(&configuration.QuietLogging, "quiet", "q", false, "Disable any logging (if both -q and -v are set, quiet wins)")
|
||||||
cli.RootCmd.PersistentFlags().StringVarP(&config.ConfigFile, "config", "c", "/etc/certwarden-deploy/config.yaml", "Path to config file (default is /etc/certwarden-deploy/config.yaml)")
|
cli.RootCmd.PersistentFlags().StringVarP(&configuration.ConfigFile, "config", "c", "/etc/certwarden-deploy/config.yaml", "Path to config file (default is /etc/certwarden-deploy/config.yaml)")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -8,8 +8,11 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/getsentry/sentry-go v0.28.1 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
)
|
)
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -1,5 +1,7 @@
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k=
|
||||||
|
github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
@ -14,6 +16,10 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
161
internal/certificates/certificates.go
Normal file
161
internal/certificates/certificates.go
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
package certificates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/configuration"
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/constants"
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleCertificates(logger *slog.Logger, config *configuration.ConfigFileData) {
|
||||||
|
for _, cert := range config.Certificates {
|
||||||
|
certBytes, err := getCertFromServer(
|
||||||
|
logger,
|
||||||
|
cert.Name,
|
||||||
|
cert.ApiKey,
|
||||||
|
config.BaseURL,
|
||||||
|
config.DisableCertificateValidation,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to get certificate from server", "cert-id", cert.Name, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
certIsDifferent, err := checkCertIsDifferent(logger, cert.FilePath, certBytes)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to handle certificate", "cert-id", cert.Name, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if certIsDifferent {
|
||||||
|
err = updateCertOnFS(logger, cert.FilePath, certBytes)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to handle certificate", "cert-id", cert.Name, "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Certificate updated successfully", "cert-id", cert.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCertIsDifferent(logger *slog.Logger, path string, data []byte) (bool, error) {
|
||||||
|
filebytes, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return true, nil
|
||||||
|
} else {
|
||||||
|
return false, fmt.Errorf("failed to read certificate file on disk: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existingSha256 := sha256.Sum256(filebytes)
|
||||||
|
newSha256 := sha256.Sum256(data)
|
||||||
|
|
||||||
|
sumsAreDifferent := existingSha256 != newSha256
|
||||||
|
if sumsAreDifferent {
|
||||||
|
logger.Debug("Certificate on file differs from the certificate on the server", "cert-path", path)
|
||||||
|
} else {
|
||||||
|
logger.Debug("Certificate on file is identical to the certificate on the server", "cert-path", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sumsAreDifferent, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCertOnFS(logger *slog.Logger, path string, data []byte) error {
|
||||||
|
if configuration.DryRun {
|
||||||
|
logger.Debug("DRY-RUN: writing certificate data to file", "cert-path", path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open certificate for writing: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func(l *slog.Logger) {
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
l.Error("failed to close file", "file-path", path, "error", err)
|
||||||
|
}
|
||||||
|
}(logger)
|
||||||
|
|
||||||
|
w := bufio.NewWriter(file)
|
||||||
|
|
||||||
|
if _, err := w.Write(data); err != nil {
|
||||||
|
return fmt.Errorf("failed to write certificate data to file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = w.Flush(); err != nil {
|
||||||
|
return fmt.Errorf("failed to flush certificate data to file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug("wrote certificate to file", "file-path", path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCertFromServer(logger *slog.Logger, certName string, certKey string, baseUrl string, skipInsecure bool) ([]byte, error) {
|
||||||
|
url := baseUrl + constants.CertificateApiPath + certName
|
||||||
|
logger.Debug("Certificate request URL: " + url)
|
||||||
|
var transport http.RoundTripper
|
||||||
|
|
||||||
|
if skipInsecure {
|
||||||
|
logger.Debug("TLS Certificate Validation is disabled")
|
||||||
|
transport = &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.Debug("TLS Certificate Validation is enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 10 * time.Second,
|
||||||
|
Transport: transport,
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, fmt.Errorf("failed to prepare to request certificate from server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("User-Agent", constants.UserAgent)
|
||||||
|
req.Header.Add(constants.ApiKeyHeaderName, certKey)
|
||||||
|
|
||||||
|
res, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
e := fmt.Errorf("failed to request certificate from server: %w", err)
|
||||||
|
sentry.CaptureException(e)
|
||||||
|
return []byte{}, e
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func(l *slog.Logger) {
|
||||||
|
if err := res.Body.Close(); err != nil {
|
||||||
|
l.Error("failed to close http response body", "error", err)
|
||||||
|
}
|
||||||
|
}(logger)
|
||||||
|
|
||||||
|
if res.StatusCode == http.StatusUnauthorized {
|
||||||
|
logger.Error("API-Key for Certificate is invalid, skipping certificate!", "cert-id", certName)
|
||||||
|
return []byte{}, errors.New("API-Key invalid")
|
||||||
|
} else if res.StatusCode != http.StatusOK {
|
||||||
|
logger.Error("failed to get certificate from server", "cert-id", certName, "http-response", res.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
e := fmt.Errorf("failed to read certificate response from server: %w", err)
|
||||||
|
sentry.CaptureException(e)
|
||||||
|
return []byte{}, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
|
@ -1,17 +1,41 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import "github.com/spf13/cobra"
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/certificates"
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/configuration"
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/constants"
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/errlog"
|
||||||
|
"code.lila.network/adoralaura/certwarden-deploy/internal/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
var RootCmd = &cobra.Command{
|
var RootCmd = &cobra.Command{
|
||||||
Use: "certwarden-deploy",
|
Use: "certwarden-deploy",
|
||||||
Short: "A brief description of your application",
|
Short: "Deploy Certificates from CertWarden in a breeze",
|
||||||
Long: `A longer description that spans multiple lines and likely contains
|
Long: `certwarden-deploy is a CLI utility to deploy certificates managed by CertWarden.
|
||||||
examples and usage of using your application. For example:
|
Configuration is handled by a single YAML file, so you can get started quickly.
|
||||||
|
|
||||||
Cobra is a CLI library for Go that empowers applications.
|
For more information on how to configure this tool, visit the docs at https://certwarden-deploy.adora.codes`,
|
||||||
This application is a tool to generate the needed files
|
Version: constants.Version,
|
||||||
to quickly create a Cobra application.`,
|
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
|
||||||
// Uncomment the following line if your bare application
|
Args: cobra.ExactArgs(0),
|
||||||
// has an action associated with it:
|
Run: handleRootCmd,
|
||||||
// Run: func(cmd *cobra.Command, args []string) { },
|
}
|
||||||
|
|
||||||
|
func handleRootCmd(cmd *cobra.Command, args []string) {
|
||||||
|
config, err := configuration.InitializeConfig()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to initialize config", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log := logger.InitializeLogger()
|
||||||
|
err = errlog.SetupSentry(log, config.Sentry.DSN)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to initialize sentry", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certificates.HandleCertificates(log, config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitializeConfig() {
|
|
||||||
if *ConfigFile != "" {
|
|
||||||
*ConfigFile = "/etc/certwarden-deploy/config.yaml"
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := os.ReadFile(*ConfigFile)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to read config file", "file", *ConfigFile, "error", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = yaml.Unmarshal([]byte(data), &Config)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to unmarshal config file", "file", *ConfigFile, "error", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
27
internal/configuration/config.go
Normal file
27
internal/configuration/config.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package configuration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitializeConfig() (*ConfigFileData, error) {
|
||||||
|
var cfg ConfigFileData
|
||||||
|
if ConfigFile == "" {
|
||||||
|
ConfigFile = "/etc/certwarden-deploy/config.yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(ConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return &ConfigFileData{}, fmt.Errorf("failed to read config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(data, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
return &ConfigFileData{}, fmt.Errorf("failed to unmarshal config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &cfg, nil
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package config
|
package configuration
|
||||||
|
|
||||||
import "log/slog"
|
import "log/slog"
|
||||||
|
|
||||||
var Config *ConfigFileData
|
var Config *ConfigFileData
|
||||||
var ConfigFile *string
|
var ConfigFile string
|
||||||
var Logger *slog.Logger
|
var Logger *slog.Logger
|
||||||
var DryRun bool
|
var DryRun bool
|
||||||
var QuietLogging bool
|
var QuietLogging bool
|
||||||
|
@ -12,6 +12,7 @@ var VerboseLogging bool
|
||||||
type ConfigFileData struct {
|
type ConfigFileData struct {
|
||||||
BaseURL string `yaml:"base_url"`
|
BaseURL string `yaml:"base_url"`
|
||||||
DisableCertificateValidation bool `yaml:"disable_certificate_validation"`
|
DisableCertificateValidation bool `yaml:"disable_certificate_validation"`
|
||||||
|
Sentry SentryData `yaml:"sentry,omitempty"`
|
||||||
Certificates []CertificateData `yaml:"certificates"`
|
Certificates []CertificateData `yaml:"certificates"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,3 +22,7 @@ type CertificateData struct {
|
||||||
Action string `yaml:"action"`
|
Action string `yaml:"action"`
|
||||||
FilePath string `yaml:"file_path"`
|
FilePath string `yaml:"file_path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SentryData struct {
|
||||||
|
DSN string `yaml:"dsn"`
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package constants
|
package constants
|
||||||
|
|
||||||
const Version = "0.0.1"
|
const Version = "0.0.1"
|
||||||
const ChainApiPath = "/certwarden/api/v1/download/certrootchains/"
|
|
||||||
const CertificateApiPath = "/certwarden/api/v1/download/certificates/"
|
const CertificateApiPath = "/certwarden/api/v1/download/certificates/"
|
||||||
const ApiKeyHeaderName = "X-API-Key"
|
const ApiKeyHeaderName = "X-API-Key"
|
||||||
const UserAgent = "certwarden-deploy/" + Version + " +code.lila.network/adoralaura/certwarden-deploy"
|
const UserAgent = "certwarden-deploy/" + Version + " +code.lila.network/adoralaura/certwarden-deploy"
|
||||||
|
|
27
internal/errlog/sentry.go
Normal file
27
internal/errlog/sentry.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package errlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupSentry(logger *slog.Logger, dsn string) error {
|
||||||
|
if dsn == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: dsn,
|
||||||
|
// Set TracesSampleRate to 1.0 to capture 100%
|
||||||
|
// of transactions for performance monitoring.
|
||||||
|
// We recommend adjusting this value in production,
|
||||||
|
TracesSampleRate: 1.0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to set up sentry")
|
||||||
|
}
|
||||||
|
// Flush buffered events before the program terminates.
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/cli"
|
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/config"
|
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/logger"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitializeApp() {
|
|
||||||
cobra.OnInitialize(config.InitializeConfig, logger.InitializeLogger)
|
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
|
||||||
// Cobra supports persistent flags, which, if defined here,
|
|
||||||
// will be global for your application.
|
|
||||||
|
|
||||||
cli.RootCmd.PersistentFlags().StringVar(config.ConfigFile, "config", "", "config file (default is /etc/certwarden-deploy/config.yaml)")
|
|
||||||
}
|
|
|
@ -3,25 +3,34 @@ package logger
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"code.lila.network/adoralaura/certwarden-deploy/internal/config"
|
"code.lila.network/adoralaura/certwarden-deploy/internal/configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeLogger() {
|
func InitializeLogger() *slog.Logger {
|
||||||
logLevel := slog.LevelInfo
|
logLevel := slog.LevelInfo
|
||||||
|
|
||||||
if config.VerboseLogging {
|
if configuration.VerboseLogging {
|
||||||
logLevel = slog.LevelDebug
|
logLevel = slog.LevelDebug
|
||||||
}
|
}
|
||||||
if config.QuietLogging {
|
if configuration.QuietLogging {
|
||||||
logLevel = slog.LevelError
|
logLevel = slog.LevelError
|
||||||
}
|
}
|
||||||
|
if configuration.DryRun {
|
||||||
|
logLevel = slog.LevelDebug
|
||||||
|
}
|
||||||
|
|
||||||
opts := &slog.HandlerOptions{
|
opts := &slog.HandlerOptions{
|
||||||
Level: logLevel,
|
Level: logLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := slog.NewTextHandler(os.Stdout, opts)
|
handler := slog.NewTextHandler(os.Stdout, opts)
|
||||||
|
log := slog.New(handler)
|
||||||
|
|
||||||
slog.SetDefault(slog.New(handler))
|
log.Debug("configuration.VerboseLogging is " + strconv.FormatBool(configuration.VerboseLogging))
|
||||||
|
log.Debug("configuration.QuietLogging is " + strconv.FormatBool(configuration.QuietLogging))
|
||||||
|
log.Debug("configuration.DryRun is " + strconv.FormatBool(configuration.DryRun))
|
||||||
|
|
||||||
|
return log
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue