Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: remove remote config files #1877

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 5 additions & 51 deletions cmd/windows_exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@
"config.file",
"YAML configuration file to use. Values set in this file will be overridden by CLI flags.",
).String()
insecureSkipVerify = app.Flag(
"config.file.insecure-skip-verify",
"Skip TLS verification in loading YAML configuration.",
).Default("false").Bool()
webConfig = webflag.AddFlags(app, ":9182")
metricsPath = app.Flag(
"telemetry.path",
Expand Down Expand Up @@ -122,11 +118,9 @@
// Initialize collectors before loading and parsing CLI arguments
collectors := collector.NewWithFlags(app)

// Load values from configuration file(s). Executable flags must first be parsed, in order
// to load the specified file(s).
if _, err := app.Parse(os.Args[1:]); err != nil {
if err := config.Parse(app, os.Args[1:]); err != nil {
//nolint:sloglint // we do not have an logger yet
slog.Error("Failed to parse CLI args",
slog.Error("Failed to load configuration",
slog.Any("err", err),
)

Expand All @@ -145,50 +139,10 @@
return 1
}

if *configFile != "" {
resolver, err := config.NewResolver(ctx, *configFile, logger, *insecureSkipVerify)
if err != nil {
logger.Error("could not load config file",
slog.Any("err", err),
)

return 1
}

if err = resolver.Bind(app, os.Args[1:]); err != nil {
logger.ErrorContext(ctx, "failed to bind configuration",
slog.Any("err", err),
)

return 1
}

// NOTE: This is temporary fix for issue #1092, calling kingpin.Parse
// twice makes slices flags duplicate its value, this clean up
// the first parse before the second call.
*webConfig.WebListenAddresses = (*webConfig.WebListenAddresses)[1:]

// Parse flags once more to include those discovered in configuration file(s).
if _, err = app.Parse(os.Args[1:]); err != nil {
logger.ErrorContext(ctx, "failed to parse CLI args from YAML file",
slog.Any("err", err),
)

return 1
}

logger, err = log.New(logConfig)
if err != nil {
//nolint:sloglint // we do not have an logger yet
slog.Error("failed to create logger",
slog.Any("err", err),
)

return 1
}
}

logger.LogAttrs(ctx, slog.LevelDebug, "logging has Started")
if configFile != nil && *configFile != "" {

Check failure on line 143 in cmd/windows_exporter/main.go

View workflow job for this annotation

GitHub Actions / lint

if statements should only be cuddled with assignments (wsl)
logger.InfoContext(ctx, "using configuration file: "+*configFile)
}

if err = setPriorityWindows(logger, os.Getpid(), *processPriority); err != nil {
logger.Error("failed to set process priority",
Expand Down
5 changes: 2 additions & 3 deletions installer/main.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,9 @@
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />

<Property Id="CONFIG_FILE" Secure="yes" Value="config.yaml" />
<SetProperty Id="ConfigFile_Remote" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND (CONFIG_FILE&lt;&lt;&quot;http://&quot; OR CONFIG_FILE&lt;&lt;&quot;https://&quot;)" />
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE&lt;&gt;&quot;config.yaml&quot; AND NOT (CONFIG_FILE&lt;&lt;&quot;http://&quot; OR CONFIG_FILE&lt;&lt;&quot;https://&quot;)" />
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE&lt;&gt;&quot;config.yaml&quot;" />
<SetProperty Id="ConfigFile_Default" After="InstallFiles" Sequence="execute" Value="[APPLICATIONFOLDER]config.yaml" Condition="CONFIG_FILE=&quot;config.yaml&quot;" />
<SetProperty Id="ConfigFileFlag" After="InstallFiles" Sequence="execute" Value="--config.file=&quot;[ConfigFile_Remote][ConfigFile_NonDefault][ConfigFile_Default]&quot;" Condition="ConfigFile_Remote OR ConfigFile_NonDefault OR ConfigFile_Default" />
<SetProperty Id="ConfigFileFlag" After="InstallFiles" Sequence="execute" Value="--config.file=&quot;[ConfigFile_NonDefault][ConfigFile_Default]&quot;" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />

<Property Id="LISTEN_PORT" Secure="yes" Value="9182" />
<SetProperty Id="ListenFlag" After="InstallFiles" Sequence="execute" Value="--web.listen-address [LISTEN_ADDR]:[LISTEN_PORT]" Condition="LISTEN_ADDR&lt;&gt;&quot;&quot; OR LISTEN_PORT&lt;&gt;9182" />
Expand Down
105 changes: 50 additions & 55 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@
package config

import (
"context"
"crypto/tls"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"strings"

Expand All @@ -38,27 +33,62 @@ type Resolver struct {
flags map[string]string
}

// NewResolver returns a Resolver structure.
func NewResolver(ctx context.Context, file string, logger *slog.Logger, insecureSkipVerify bool) (*Resolver, error) {
// Parse parses the command line arguments and configuration files.
func Parse(app *kingpin.Application, args []string) error {
configFile := ParseConfigFile(args)
if configFile != "" {
resolver, err := NewConfigFileResolver(configFile)
if err != nil {
return fmt.Errorf("failed to load configuration file: %w", err)
}

if err = resolver.Bind(app, args); err != nil {
return fmt.Errorf("failed to bind configuration: %w", err)
}
}

if _, err := app.Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}

return nil
}

// ParseConfigFile manually parses the configuration file from the command line arguments.
func ParseConfigFile(args []string) string {
for i, cliFlag := range args {
if strings.HasPrefix(cliFlag, "--config.file=") {
return strings.TrimPrefix(cliFlag, "--config.file=")
}

if strings.HasPrefix(cliFlag, "-config.file=") {
return strings.TrimPrefix(cliFlag, "-config.file=")
}

if strings.HasSuffix(cliFlag, "-config.file") {
if len(os.Args) <= i+1 {
return ""
}

return os.Args[i+1]
}
}

return ""
}

// NewConfigFileResolver returns a Resolver structure.
func NewConfigFileResolver(file string) (*Resolver, error) {
flags := map[string]string{}

var (
err error
fileBytes []byte
)

if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
logger.WarnContext(ctx, "Loading configuration file from URL is deprecated and will be removed in 0.31.0. Use a local file instead.")

fileBytes, err = readFromURL(ctx, file, logger, insecureSkipVerify)
if err != nil {
return nil, err
}
} else {
fileBytes, err = readFromFile(ctx, file, logger)
if err != nil {
return nil, err
}
fileBytes, err = readFromFile(file)
if err != nil {
return nil, err
}

var rawValues map[string]interface{}
Expand All @@ -79,9 +109,7 @@ func NewResolver(ctx context.Context, file string, logger *slog.Logger, insecure
return &Resolver{flags: flags}, nil
}

func readFromFile(ctx context.Context, file string, logger *slog.Logger) ([]byte, error) {
logger.InfoContext(ctx, "loading configuration file: "+file)

func readFromFile(file string) ([]byte, error) {
if _, err := os.Stat(file); err != nil {
return nil, fmt.Errorf("failed to read configuration file: %w", err)
}
Expand All @@ -94,39 +122,6 @@ func readFromFile(ctx context.Context, file string, logger *slog.Logger) ([]byte
return fileBytes, nil
}

func readFromURL(ctx context.Context, file string, logger *slog.Logger, insecureSkipVerify bool) ([]byte, error) {
logger.InfoContext(ctx, "loading configuration file from URL: "+file)

tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, //nolint:gosec
}

if insecureSkipVerify {
logger.WarnContext(ctx, "Loading configuration file with TLS verification disabled")
}

client := &http.Client{Transport: tr}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, file, nil)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
}

resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to read configuration file from URL: %w", err)
}

defer resp.Body.Close()

fileBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return fileBytes, nil
}

func (c *Resolver) setDefault(v getFlagger) {
for name, value := range c.flags {
f := v.GetFlag(name)
Expand Down
Loading