|
9 | 9 | "fmt"
|
10 | 10 | "net/url"
|
11 | 11 | "path"
|
| 12 | + "slices" |
12 | 13 | "strings"
|
13 | 14 | "text/template"
|
14 | 15 |
|
@@ -139,21 +140,17 @@ func generateRegistryCACertFiles(
|
139 | 140 |
|
140 | 141 | var files []cabpkv1.File //nolint:prealloc // We don't know the size of the slice yet.
|
141 | 142 |
|
142 |
| - for _, config := range configs { |
143 |
| - if config.CASecretName == "" { |
144 |
| - continue |
145 |
| - } |
146 |
| - |
147 |
| - registryCACertPathOnRemote, err := config.filePathFromURL() |
148 |
| - if err != nil { |
149 |
| - return nil, fmt.Errorf("failed generating CA certificate file path from URL: %w", err) |
150 |
| - } |
| 143 | + filesToGenerate, err := registryCACertFiles(configs) |
| 144 | + if err != nil { |
| 145 | + return nil, err |
| 146 | + } |
| 147 | + for _, file := range filesToGenerate { |
151 | 148 | files = append(files, cabpkv1.File{
|
152 |
| - Path: registryCACertPathOnRemote, |
| 149 | + Path: file.path, |
153 | 150 | Permissions: "0600",
|
154 | 151 | ContentFrom: &cabpkv1.FileSource{
|
155 | 152 | Secret: cabpkv1.SecretFileSource{
|
156 |
| - Name: config.CASecretName, |
| 153 | + Name: file.caSecretName, |
157 | 154 | Key: secretKeyForCACert,
|
158 | 155 | },
|
159 | 156 | },
|
@@ -189,3 +186,52 @@ func formatURLForContainerd(uri string) (string, error) {
|
189 | 186 | // using path.Join on all elements incorrectly drops a "/" from "https://"
|
190 | 187 | return fmt.Sprintf("%s/%s", mirror, mirrorPath), nil
|
191 | 188 | }
|
| 189 | + |
| 190 | +type containerdConfigFile struct { |
| 191 | + path string |
| 192 | + url string |
| 193 | + caSecretName string |
| 194 | + caCert string |
| 195 | +} |
| 196 | + |
| 197 | +// registryCACertFiles returns a list of CA certificate files |
| 198 | +// that should be generated for the given containerd configurations. |
| 199 | +// If any of the provided configurations share the same url.Host only a single file will be generated. |
| 200 | +// An error will be returned, if the CA certificate content for the same URL.Host do not match. |
| 201 | +func registryCACertFiles(configs []containerdConfig) ([]containerdConfigFile, error) { |
| 202 | + filesToGenerate := make([]containerdConfigFile, 0) |
| 203 | + for _, config := range configs { |
| 204 | + // Skip if CA certificate is not provided. |
| 205 | + if config.CASecretName == "" { |
| 206 | + continue |
| 207 | + } |
| 208 | + registryCACertPathOnRemote, err := config.filePathFromURL() |
| 209 | + if err != nil { |
| 210 | + return nil, fmt.Errorf("failed generating CA certificate file path from URL: %w", err) |
| 211 | + } |
| 212 | + |
| 213 | + foundIndex := slices.IndexFunc(filesToGenerate, func(f containerdConfigFile) bool { |
| 214 | + return registryCACertPathOnRemote == f.path |
| 215 | + }) |
| 216 | + // File not already found and needs to be generated. |
| 217 | + if foundIndex == -1 { |
| 218 | + filesToGenerate = append(filesToGenerate, containerdConfigFile{ |
| 219 | + path: registryCACertPathOnRemote, |
| 220 | + url: config.URL, |
| 221 | + caSecretName: config.CASecretName, |
| 222 | + caCert: config.CACert, |
| 223 | + }) |
| 224 | + continue |
| 225 | + } |
| 226 | + // File is already in the list, check if the CA certificate content matches. |
| 227 | + if config.CACert != filesToGenerate[foundIndex].caCert { |
| 228 | + return nil, fmt.Errorf( |
| 229 | + "CA certificate content for %q does not match one for %q", |
| 230 | + config.URL, |
| 231 | + filesToGenerate[foundIndex].url, |
| 232 | + ) |
| 233 | + } |
| 234 | + } |
| 235 | + |
| 236 | + return filesToGenerate, nil |
| 237 | +} |
0 commit comments