From 6566d4efd6f14b031c9efbb9ec9210f0c9ede74a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Oct 2019 19:04:45 +0000 Subject: [PATCH] fetch: Add support for providing HTTP headers I plan to use this in ignition-dracut to inject e.g. headers from `/usr/lib/os-release`, so that a server (such as the OpenShift 4 machine-config-operator server) can dispatch on them. --- internal/exec/engine.go | 16 +++++++++++++++- internal/main.go | 14 ++++++++++++++ internal/resource/url.go | 3 +++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/internal/exec/engine.go b/internal/exec/engine.go index 862831a2a..888e37220 100644 --- a/internal/exec/engine.go +++ b/internal/exec/engine.go @@ -20,6 +20,9 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/http" + "strings" + "net/url" "os" "time" @@ -50,6 +53,7 @@ const ( type Engine struct { ConfigCache string FetchTimeout time.Duration + FetchHeaders []string Logger *log.Logger Root string PlatformConfig platform.Config @@ -272,7 +276,17 @@ func (e *Engine) fetchReferencedConfig(cfgRef types.ConfigReference) (types.Conf if err != nil { return types.Config{}, err } - rawCfg, err := e.Fetcher.FetchToBuffer(*u, resource.FetchOptions{}) + headers := make(http.Header) + for _, h := range e.FetchHeaders { + parts := strings.SplitN(h, "=", 2) + k := parts[0] + v := "" + if len(parts) > 1 { + v = parts[1] + } + headers.Add(k, v) + } + rawCfg, err := e.Fetcher.FetchToBuffer(*u, resource.FetchOptions{Headers: headers}) if err != nil { return types.Config{}, err } diff --git a/internal/main.go b/internal/main.go index f630b917b..e9c597a45 100644 --- a/internal/main.go +++ b/internal/main.go @@ -32,11 +32,23 @@ import ( "github.com/coreos/ignition/v2/internal/version" ) +type flagStringArray []string + +func (_ *flagStringArray) String() string { + return "" +} + +func (a *flagStringArray) Set(value string) error { + *a = append(*a, value) + return nil +} + func main() { flags := struct { clearCache bool configCache string fetchTimeout time.Duration + fetchHeaders flagStringArray platform platform.Name root string stage stages.Name @@ -47,6 +59,7 @@ func main() { flag.BoolVar(&flags.clearCache, "clear-cache", false, "clear any cached config") flag.StringVar(&flags.configCache, "config-cache", "/run/ignition.json", "where to cache the config") flag.DurationVar(&flags.fetchTimeout, "fetch-timeout", exec.DefaultFetchTimeout, "initial duration for which to wait for config") + flag.Var(&flags.fetchHeaders, "fetch-header", "Include HTTP header for fetches") flag.Var(&flags.platform, "platform", fmt.Sprintf("current platform. %v", platform.Names())) flag.StringVar(&flags.root, "root", "/", "root of the filesystem") flag.Var(&flags.stage, "stage", fmt.Sprintf("execution stage. %v", stages.Names())) @@ -91,6 +104,7 @@ func main() { engine := exec.Engine{ Root: flags.root, FetchTimeout: flags.fetchTimeout, + FetchHeaders: flags.fetchHeaders, Logger: &logger, ConfigCache: flags.configCache, PlatformConfig: platformConfig, diff --git a/internal/resource/url.go b/internal/resource/url.go index c5b8afed6..e86f01374 100644 --- a/internal/resource/url.go +++ b/internal/resource/url.go @@ -68,6 +68,9 @@ type Fetcher struct { // timeouts Ignition was configured to used will be ignored. client *HttpClient + // headers is additional headers to include + headers []http.Header + // The AWS Session to use when fetching resources from S3. If left nil, the // first S3 object that is fetched will initialize the field. This can be // used to set credentials.