@@ -2,8 +2,10 @@ package config
22
33import (
44 "bytes"
5+ "context"
56 "fmt"
67 "os"
8+ "path/filepath"
79
810 "github.com/BurntSushi/toml"
911)
@@ -68,6 +70,9 @@ type StaticConfig struct {
6870
6971 // Internal: parsed provider configs (not exposed to TOML package)
7072 parsedClusterProviderConfigs map [string ]ProviderConfig
73+
74+ // Internal: the config.toml directory, to help resolve relative file paths
75+ configDirPath string
7176}
7277
7378type GroupVersionKind struct {
@@ -76,23 +81,48 @@ type GroupVersionKind struct {
7681 Kind string `toml:"kind,omitempty"`
7782}
7883
79- // Read reads the toml file and returns the StaticConfig.
80- func Read (configPath string ) (* StaticConfig , error ) {
84+ type ReadConfigOpt func (cfg * StaticConfig )
85+
86+ func withDirPath (path string ) ReadConfigOpt {
87+ return func (cfg * StaticConfig ) {
88+ cfg .configDirPath = path
89+ }
90+ }
91+
92+ // Read reads the toml file and returns the StaticConfig, with any opts applied.
93+ func Read (configPath string , opts ... ReadConfigOpt ) (* StaticConfig , error ) {
8194 configData , err := os .ReadFile (configPath )
8295 if err != nil {
8396 return nil , err
8497 }
85- return ReadToml (configData )
98+
99+ // get and save the absolute dir path to the config file, so that other config parsers can use it
100+ absPath , err := filepath .Abs (configPath )
101+ if err != nil {
102+ return nil , fmt .Errorf ("failed to resolve absolute path to config file: %w" , err )
103+ }
104+ dirPath := filepath .Dir (absPath )
105+
106+ cfg , err := ReadToml (configData , append (opts , withDirPath (dirPath ))... )
107+ if err != nil {
108+ return nil , err
109+ }
110+
111+ return cfg , nil
86112}
87113
88- // ReadToml reads the toml data and returns the StaticConfig.
89- func ReadToml (configData []byte ) (* StaticConfig , error ) {
114+ // ReadToml reads the toml data and returns the StaticConfig, with any opts applied
115+ func ReadToml (configData []byte , opts ... ReadConfigOpt ) (* StaticConfig , error ) {
90116 config := Default ()
91117 md , err := toml .NewDecoder (bytes .NewReader (configData )).Decode (config )
92118 if err != nil {
93119 return nil , err
94120 }
95121
122+ for _ , opt := range opts {
123+ opt (config )
124+ }
125+
96126 if err := config .parseClusterProviderConfigs (md ); err != nil {
97127 return nil , err
98128 }
@@ -111,13 +141,15 @@ func (c *StaticConfig) parseClusterProviderConfigs(md toml.MetaData) error {
111141 c .parsedClusterProviderConfigs = make (map [string ]ProviderConfig , len (c .ClusterProviderConfigs ))
112142 }
113143
144+ ctx := withConfigDirPath (context .Background (), c .configDirPath )
145+
114146 for strategy , primitive := range c .ClusterProviderConfigs {
115147 parser , ok := getProviderConfigParser (strategy )
116148 if ! ok {
117149 continue
118150 }
119151
120- providerConfig , err := parser (primitive , md )
152+ providerConfig , err := parser (ctx , primitive , md )
121153 if err != nil {
122154 return fmt .Errorf ("failed to parse config for ClusterProvider '%s': %w" , strategy , err )
123155 }
0 commit comments