Load starts by running the MigrationRules and then takes the loading rules and returns a Config object based on following rules. if the ExplicitPath, return the unmerged explicit file Otherwise, return a merged config based on the Precedence slice A missing ExplicitPath file produces an error. Empty
()
| 167 | // Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder |
| 168 | // and only absolute file paths are returned. |
| 169 | func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) { |
| 170 | if err := rules.Migrate(); err != nil { |
| 171 | return nil, err |
| 172 | } |
| 173 | |
| 174 | errlist := []error{} |
| 175 | |
| 176 | kubeConfigFiles := []string{} |
| 177 | |
| 178 | // Make sure a file we were explicitly told to use exists |
| 179 | if len(rules.ExplicitPath) > 0 { |
| 180 | if _, err := os.Stat(rules.ExplicitPath); os.IsNotExist(err) { |
| 181 | return nil, err |
| 182 | } |
| 183 | kubeConfigFiles = append(kubeConfigFiles, rules.ExplicitPath) |
| 184 | |
| 185 | } else { |
| 186 | kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...) |
| 187 | } |
| 188 | |
| 189 | kubeconfigs := []*clientcmdapi.Config{} |
| 190 | // read and cache the config files so that we only look at them once |
| 191 | for _, filename := range kubeConfigFiles { |
| 192 | if len(filename) == 0 { |
| 193 | // no work to do |
| 194 | continue |
| 195 | } |
| 196 | |
| 197 | config, err := LoadFromFile(filename) |
| 198 | if os.IsNotExist(err) { |
| 199 | // skip missing files |
| 200 | continue |
| 201 | } |
| 202 | if err != nil { |
| 203 | errlist = append(errlist, fmt.Errorf("Error loading config file \"%s\": %v", filename, err)) |
| 204 | continue |
| 205 | } |
| 206 | |
| 207 | kubeconfigs = append(kubeconfigs, config) |
| 208 | } |
| 209 | |
| 210 | // first merge all of our maps |
| 211 | mapConfig := clientcmdapi.NewConfig() |
| 212 | |
| 213 | for _, kubeconfig := range kubeconfigs { |
| 214 | mergo.MergeWithOverwrite(mapConfig, kubeconfig) |
| 215 | } |
| 216 | |
| 217 | // merge all of the struct values in the reverse order so that priority is given correctly |
| 218 | // errors are not added to the list the second time |
| 219 | nonMapConfig := clientcmdapi.NewConfig() |
| 220 | for i := len(kubeconfigs) - 1; i >= 0; i-- { |
| 221 | kubeconfig := kubeconfigs[i] |
| 222 | mergo.MergeWithOverwrite(nonMapConfig, kubeconfig) |
| 223 | } |
| 224 | |
| 225 | // since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and |
| 226 | // get the values we expect. |