1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "context"
19 "flag"
20 "fmt"
21 "io/ioutil"
22 "log"
23 "os"
24 "path"
25 "regexp"
26 "strings"
27
28 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/loaders"
29
30 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/k8s"
31 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/test/util/paths"
32 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/scripts/utils"
33 )
34
35 const (
36 dirMode = os.FileMode(0755)
37 fileMode = os.FileMode(0644)
38 gcsPathTmpl = "gs://cnrm/%v/release-bundle.tar.gz"
39 baseDir = "scripts/update-kcc-manifest"
40 channelDir = "channels/packages/configconnector"
41 managerPatch = "manager_sidecar_patch.yaml"
42 recorderPatch = "recorder_sidecar_patch.yaml"
43 finalizerPatch = "finalizer_patch.yaml"
44
45 autopilotChannelDir = "autopilot-channels/packages/configconnector"
46 autopilotRecorderPatch = "recorder_remove_hostport_patch.yaml"
47 )
48
49 var (
50 version string
51 )
52
53
54
55
56
57
58
59 func main() {
60 ctx := context.TODO()
61
62 flag.StringVar(&version, "version", "latest", "Version of the KCC core to download.")
63 flag.Parse()
64
65
66 operatorSrcRoot := paths.GetOperatorSrcRootOrLogFatal()
67 log.Printf("Operator source root is set to %s.\r\n", operatorSrcRoot)
68 outputDir := path.Join(operatorSrcRoot, baseDir, "kcc")
69 if err := os.Mkdir(outputDir, dirMode); err != nil && !os.IsExist(err) {
70 log.Fatalf("error creating dir %v: %v", outputDir, err)
71 }
72 if version == "local" {
73 tarballPath := path.Join("..", "release-bundle.tar.gz")
74 log.Printf("Extracting bundle resource from local %s to %s.\r\n", tarballPath, outputDir)
75 if err := utils.ExtractTarball(tarballPath, outputDir); err != nil {
76 log.Fatalf("error extracting tarball: %v", err)
77 }
78 } else {
79 gcsPath := fmt.Sprintf(gcsPathTmpl, version)
80 log.Printf("GCS Path is set to %s.\r\n", gcsPath)
81 if err := utils.DownloadAndExtractTarballAt(gcsPath, outputDir); err != nil {
82 log.Fatalf("error downloading and extracting the tarball %v: %v", gcsPath, err)
83 }
84 }
85
86 kustomizeBuild(operatorSrcRoot)
87
88
89 wiSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-workload-identity", "0-cnrm-system.yaml")
90 gcpSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-gcp-identity", "0-cnrm-system.yaml")
91 namespacedSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-namespaced", "0-cnrm-system.yaml")
92
93 autopilotWiSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-workload-identity", "0-cnrm-system.yaml")
94 autopilotGcpSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-gcp-identity", "0-cnrm-system.yaml")
95 autopilotNamespacedSystemManifest := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-namespaced", "0-cnrm-system.yaml")
96
97 pnc := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-namespaced", "per-namespace-components.yaml")
98 manifests := []string{wiSystemManifest, gcpSystemManifest, namespacedSystemManifest, pnc}
99 for _, manifest := range manifests {
100 if err := swapContainerRegistry(manifest); err != nil {
101 log.Fatalf("error swapping container registry: %v", err)
102 }
103 }
104 autopilotPnc := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-namespaced", "per-namespace-components.yaml")
105 manifests = []string{autopilotWiSystemManifest, autopilotGcpSystemManifest, autopilotNamespacedSystemManifest, autopilotPnc}
106 for _, manifest := range manifests {
107 if err := swapContainerRegistry(manifest); err != nil {
108 log.Fatalf("error swapping container registry: %v", err)
109 }
110 }
111
112
113 manifestFile := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-namespaced", "0-cnrm-system.yaml")
114 version, err := extractVersionFromManifest(manifestFile)
115 if err != nil {
116 log.Fatalf("error extracting version from manifest %v: %v", manifestFile, err)
117 }
118 manifestDir := path.Join(operatorSrcRoot, channelDir, version)
119 if err := os.Mkdir(manifestDir, dirMode); err != nil && !os.IsExist(err) {
120 log.Fatalf("error creating dir %v: %v", manifestDir, err)
121 }
122 autopilotManifestDir := path.Join(operatorSrcRoot, autopilotChannelDir, version)
123 if err := os.Mkdir(autopilotManifestDir, dirMode); err != nil && !os.IsExist(err) {
124 log.Fatalf("error creating dir %v: %v", autopilotManifestDir, err)
125 }
126
127
128 crds := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-namespaced", "crds.yaml")
129 destCRDs := path.Join(manifestDir, "crds.yaml")
130 if err := utils.Copy(crds, destCRDs); err != nil {
131 log.Fatalf("error copying %v to %v: %v", crds, destCRDs, err)
132 }
133 destCRDs = path.Join(autopilotManifestDir, "crds.yaml")
134 if err := utils.Copy(crds, destCRDs); err != nil {
135 log.Fatalf("error copying %v to %v: %v", crds, destCRDs, err)
136 }
137
138
139 if err := os.Mkdir(path.Join(manifestDir, "cluster"), dirMode); err != nil && !os.IsExist(err) {
140 log.Fatalf("error creating dir: %v", err)
141 }
142 if err := os.Mkdir(path.Join(autopilotManifestDir, "cluster"), dirMode); err != nil && !os.IsExist(err) {
143 log.Fatalf("error creating dir: %v", err)
144 }
145
146
147 if err := os.Mkdir(path.Join(manifestDir, "cluster", "workload-identity"), dirMode); err != nil && !os.IsExist(err) {
148 log.Fatalf("error creating dir: %v", err)
149 }
150 destWiSystemManifest := path.Join(manifestDir, "cluster", "workload-identity", "0-cnrm-system.yaml")
151 if err := utils.Copy(wiSystemManifest, destWiSystemManifest); err != nil {
152 log.Fatalf("error copying %v to %v: %v", wiSystemManifest, destWiSystemManifest, err)
153 }
154 if err := os.Mkdir(path.Join(autopilotManifestDir, "cluster", "workload-identity"), dirMode); err != nil && !os.IsExist(err) {
155 log.Fatalf("error creating dir: %v", err)
156 }
157 destWiSystemManifest = path.Join(autopilotManifestDir, "cluster", "workload-identity", "0-cnrm-system.yaml")
158 if err := utils.Copy(autopilotWiSystemManifest, destWiSystemManifest); err != nil {
159 log.Fatalf("error copying %v to %v: %v", wiSystemManifest, destWiSystemManifest, err)
160 }
161
162
163 if err := os.Mkdir(path.Join(manifestDir, "cluster", "gcp-identity"), dirMode); err != nil && !os.IsExist(err) {
164 log.Fatalf("error creating dir: %v", err)
165 }
166 destGcpSystemManifest := path.Join(manifestDir, "cluster", "gcp-identity", "0-cnrm-system.yaml")
167 if err := utils.Copy(gcpSystemManifest, destGcpSystemManifest); err != nil {
168 log.Fatalf("error copying %v to %v: %v", wiSystemManifest, destWiSystemManifest, err)
169 }
170 if err := os.Mkdir(path.Join(autopilotManifestDir, "cluster", "gcp-identity"), dirMode); err != nil && !os.IsExist(err) {
171 log.Fatalf("error creating dir: %v", err)
172 }
173 destGcpSystemManifest = path.Join(autopilotManifestDir, "cluster", "gcp-identity", "0-cnrm-system.yaml")
174 if err := utils.Copy(autopilotGcpSystemManifest, destGcpSystemManifest); err != nil {
175 log.Fatalf("error copying %v to %v: %v", wiSystemManifest, destWiSystemManifest, err)
176 }
177
178
179 namespacedDir := path.Join(manifestDir, "namespaced")
180 if err := os.Mkdir(namespacedDir, dirMode); err != nil && !os.IsExist(err) {
181 log.Fatalf("error creating dir %v: %v", namespacedDir, err)
182 }
183 destNamespacedSystemManifest := path.Join(manifestDir, "namespaced", "0-cnrm-system.yaml")
184 if err := utils.Copy(namespacedSystemManifest, destNamespacedSystemManifest); err != nil {
185 log.Fatalf("error copying %v to %v: %v", namespacedSystemManifest, destNamespacedSystemManifest, err)
186 }
187 destPnc := path.Join(manifestDir, "namespaced", "per-namespace-components.yaml")
188 if err := utils.Copy(pnc, destPnc); err != nil {
189 log.Fatalf("error copying %v to %v: %v", pnc, destPnc, err)
190 }
191 namespacedDir = path.Join(autopilotManifestDir, "namespaced")
192 if err := os.Mkdir(namespacedDir, dirMode); err != nil && !os.IsExist(err) {
193 log.Fatalf("error creating dir %v: %v", namespacedDir, err)
194 }
195 destNamespacedSystemManifest = path.Join(autopilotManifestDir, "namespaced", "0-cnrm-system.yaml")
196 if err := utils.Copy(autopilotNamespacedSystemManifest, destNamespacedSystemManifest); err != nil {
197 log.Fatalf("error copying %v to %v: %v", autopilotNamespacedSystemManifest, destNamespacedSystemManifest, err)
198 }
199 destPnc = path.Join(autopilotManifestDir, "namespaced", "per-namespace-components.yaml")
200 if err := utils.Copy(autopilotPnc, destPnc); err != nil {
201 log.Fatalf("error copying %v to %v: %v", autopilotPnc, destPnc, err)
202 }
203
204 if err := os.RemoveAll(outputDir); err != nil {
205 log.Fatalf("error deleting dir %v: %v", outputDir, err)
206 }
207
208
209 kustomizationFilePath := path.Join(operatorSrcRoot, "config", "default", "kustomization.yaml")
210 b, err := ioutil.ReadFile(kustomizationFilePath)
211 if err != nil {
212 log.Fatalf("error reading %v: %v", kustomizationFilePath, err)
213 }
214 kustomization := string(b)
215 m := regexp.MustCompile("cnrm.cloud.google.com/operator-version: (\".*\")")
216 kustomization = m.ReplaceAllString(kustomization, fmt.Sprintf("cnrm.cloud.google.com/operator-version: \"%v\"", version))
217 if err := ioutil.WriteFile(kustomizationFilePath, []byte(kustomization), fileMode); err != nil {
218 log.Fatalf("error updating file %v", kustomizationFilePath)
219 }
220 log.Printf("successfully updated the version annotation in %v for default kustomization\n", kustomizationFilePath)
221
222
223 kustomizationFilePath = path.Join(operatorSrcRoot, "config", "autopilot", "kustomization.yaml")
224 b, err = ioutil.ReadFile(kustomizationFilePath)
225 if err != nil {
226 log.Fatalf("error reading %v: %v", kustomizationFilePath, err)
227 }
228 kustomization = string(b)
229 m = regexp.MustCompile("cnrm.cloud.google.com/operator-version: (\".*\")")
230 kustomization = m.ReplaceAllString(kustomization, fmt.Sprintf("cnrm.cloud.google.com/operator-version: \"%v\"", version))
231 if err := ioutil.WriteFile(kustomizationFilePath, []byte(kustomization), fileMode); err != nil {
232 log.Fatalf("error updating file %v", kustomizationFilePath)
233 }
234 log.Printf("successfully updated the version annotation in %v for autopilot kustomization\n", kustomizationFilePath)
235
236
237 r := loaders.NewFSRepository(path.Join(operatorSrcRoot, loaders.FlagChannel))
238 channel, err := r.LoadChannel(ctx, k8s.StableChannel)
239 if err != nil {
240 log.Fatalf("error loading %v channel: %v", k8s.StableChannel, err)
241 }
242 currentVersion, err := channel.Latest(ctx, "configconnector")
243 if err != nil {
244 log.Fatalf("error resolving the current version: %v", err)
245 }
246 if currentVersion.Version == version {
247 log.Printf("the current KCC version is the same as the latest version %v\n", version)
248 return
249 }
250 stableFilePath := path.Join(operatorSrcRoot, "channels", "stable")
251 b, err = ioutil.ReadFile(stableFilePath)
252 if err != nil {
253 log.Fatalf("error reading %v: %v", stableFilePath, err)
254 }
255 stable := string(b)
256 stable = strings.ReplaceAll(stable, fmt.Sprintf("- version: %v", currentVersion.Version), fmt.Sprintf("- version: %v", version))
257 if err := ioutil.WriteFile(stableFilePath, []byte(stable), fileMode); err != nil {
258 log.Fatalf("error updating file %v", stableFilePath)
259 }
260 stableFilePath = path.Join(operatorSrcRoot, "autopilot-channels", "stable")
261 b, err = ioutil.ReadFile(stableFilePath)
262 if err != nil {
263 log.Fatalf("error reading %v: %v", stableFilePath, err)
264 }
265 stable = string(b)
266 stable = strings.ReplaceAll(stable, fmt.Sprintf("- version: %v", currentVersion.Version), fmt.Sprintf("- version: %v", version))
267 if err := ioutil.WriteFile(stableFilePath, []byte(stable), fileMode); err != nil {
268 log.Fatalf("error updating file %v", stableFilePath)
269 }
270
271 staleManifestDir := path.Join(operatorSrcRoot, "channels", "packages", "configconnector", currentVersion.Version)
272 log.Printf("removing stale manifest %v", staleManifestDir)
273 if err := os.RemoveAll(staleManifestDir); err != nil {
274 log.Fatalf("error deleting dir %v: %v", staleManifestDir, err)
275 }
276 staleManifestDir = path.Join(operatorSrcRoot, "autopilot-channels", "packages", "configconnector", currentVersion.Version)
277 log.Printf("removing stale manifest %v", staleManifestDir)
278 if err := os.RemoveAll(staleManifestDir); err != nil {
279 log.Fatalf("error deleting dir %v: %v", staleManifestDir, err)
280 }
281 }
282
283 func kustomizeBuild(operatorSrcRoot string) {
284
285 buildPath := path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-workload-identity")
286 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_workload-identity.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
287 log.Fatalf("error copying kustomization: %v", err)
288 }
289 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, managerPatch), path.Join(buildPath, managerPatch)); err != nil {
290 log.Fatalf("error copying %v: %v", managerPatch, err)
291 }
292 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, recorderPatch), path.Join(buildPath, recorderPatch)); err != nil {
293 log.Fatalf("error copying %v: %v", recorderPatch, err)
294 }
295 output := path.Join(buildPath, "0-cnrm-system.yaml")
296 if err := utils.KustomizeBuild(buildPath, output); err != nil {
297 log.Fatalf("error running kustomize build: %v", err)
298 }
299
300
301 buildPath = path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-workload-identity")
302 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_autopilot_workload-identity.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
303 log.Fatalf("error copying kustomization: %v", err)
304 }
305 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, autopilotRecorderPatch), path.Join(buildPath, autopilotRecorderPatch)); err != nil {
306 log.Fatalf("error copying %v: %v", autopilotRecorderPatch, err)
307 }
308 output = path.Join(buildPath, "0-cnrm-system.yaml")
309 if err := utils.KustomizeBuild(buildPath, output); err != nil {
310 log.Fatalf("error running kustomize build: %v", err)
311 }
312
313
314 buildPath = path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-gcp-identity")
315 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_autopilot_gcp-identity.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
316 log.Fatalf("error copying kustomization: %v", err)
317 }
318 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, autopilotRecorderPatch), path.Join(buildPath, autopilotRecorderPatch)); err != nil {
319 log.Fatalf("error copying %v: %v", autopilotRecorderPatch, err)
320 }
321 output = path.Join(buildPath, "0-cnrm-system.yaml")
322 if err := utils.KustomizeBuild(buildPath, output); err != nil {
323 log.Fatalf("error running kustomize build: %v", err)
324 }
325
326
327 buildPath = path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-namespaced")
328 buildNamespacedMode(operatorSrcRoot, buildPath, output, false)
329
330
331 buildPath = path.Join(operatorSrcRoot, baseDir, "kcc", "install-bundle-autopilot-namespaced")
332 buildNamespacedMode(operatorSrcRoot, buildPath, output, true)
333 }
334
335 func buildNamespacedMode(operatorSrcRoot, buildPath, output string, autopilot bool) {
336 if !autopilot {
337 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, managerPatch), path.Join(buildPath, managerPatch)); err != nil {
338 log.Fatalf("error copying %v: %v", managerPatch, err)
339 }
340 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, recorderPatch), path.Join(buildPath, recorderPatch)); err != nil {
341 log.Fatalf("error copying %v: %v", recorderPatch, err)
342 }
343 } else {
344 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, autopilotRecorderPatch), path.Join(buildPath, autopilotRecorderPatch)); err != nil {
345 log.Fatalf("error copying %v: %v", autopilotRecorderPatch, err)
346 }
347 }
348 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, finalizerPatch), path.Join(buildPath, finalizerPatch)); err != nil {
349 log.Fatalf("error copying %v: %v", finalizerPatch, err)
350 }
351 if autopilot {
352 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_autopilot_namespaced_0-cnrm-system.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
353 log.Fatalf("error copying kustomization: %v", err)
354 }
355 } else {
356 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_namespaced_0-cnrm-system.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
357 log.Fatalf("error copying kustomization: %v", err)
358 }
359 }
360 output = path.Join(buildPath, "0-cnrm-system.yaml")
361 if err := utils.KustomizeBuild(buildPath, output); err != nil {
362 log.Fatalf("error running kustomize build: %v", err)
363 }
364 if autopilot {
365 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_autopilot_namespaced_per-namespace-components.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
366 log.Fatalf("error copying kustomization: %v", err)
367 }
368 } else {
369 if err := utils.Copy(path.Join(operatorSrcRoot, baseDir, "kustomizations", "kustomization_namespaced_per-namespace-components.yaml"), path.Join(buildPath, "kustomization.yaml")); err != nil {
370 log.Fatalf("error copying kustomization: %v", err)
371 }
372 }
373 output = path.Join(buildPath, "per-namespace-components.yaml")
374 if err := utils.KustomizeBuild(buildPath, output); err != nil {
375 log.Fatalf("error running kustomize build: %v", err)
376 }
377 }
378
379
380 func swapContainerRegistry(manifestPath string) error {
381 content, err := ioutil.ReadFile(manifestPath)
382 if err != nil {
383 return fmt.Errorf("error reading manifestPath: %v", err)
384 }
385 manifest := string(content)
386 updatedManifest := strings.ReplaceAll(manifest, "gcr.io/cnrm-eap/", "gcr.io/gke-release/cnrm/")
387 fileMode := os.FileMode(0644)
388 return ioutil.WriteFile(manifestPath, []byte(updatedManifest), fileMode)
389 }
390
391 func extractVersionFromManifest(filePath string) (string, error) {
392 objs, err := utils.ReadFileToUnstructs(filePath)
393 if err != nil {
394 return "", fmt.Errorf("error reading file %v and converting to unstructs: %v", filePath, err)
395 }
396 for _, obj := range objs {
397 if obj.GetKind() == "Namespace" && obj.GetName() == k8s.CNRMSystemNamespace {
398 for key, val := range obj.GetAnnotations() {
399 if key == k8s.VersionAnnotation {
400 return val, nil
401 }
402 }
403 }
404 }
405 return "", fmt.Errorf("couldn't extract the version from the manifest %v", filePath)
406 }
407
View as plain text