From a2d83da70ef47a1acd7d09d21be76a76ee45ad84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20El=20Fartas?= Date: Tue, 7 Jan 2025 22:05:46 +0100 Subject: [PATCH 1/2] Create namespace with labels & annotations in a single request --- internal/app/kube_helpers.go | 47 +++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/internal/app/kube_helpers.go b/internal/app/kube_helpers.go index 0d5e81a3..89f69e2a 100644 --- a/internal/app/kube_helpers.go +++ b/internal/app/kube_helpers.go @@ -24,7 +24,7 @@ func addNamespaces(s *State) { wg.Add(1) go func(name string, cfg *Namespace, wg *sync.WaitGroup) { defer wg.Done() - createNamespace(name) + createNamespace(name, cfg.Labels, cfg.Annotations) labelNamespace(name, cfg.Labels, s.Settings.NamespaceLabelsAuthoritative) annotateNamespace(name, cfg.Annotations) if !flags.dryRun { @@ -46,20 +46,59 @@ func kubectl(args []string, desc string) Command { } // createNamespace creates a namespace in the k8s cluster -func createNamespace(ns string) { +func createNamespace(ns string, labels map[string]string, annotations map[string]string) { checkCmd := kubectl([]string{"get", "namespace", ns}, "Looking for namespace [ "+ns+" ]") if _, err := checkCmd.Exec(); err == nil { log.Verbose("Namespace [ " + ns + " ] exists") return } - cmd := kubectl([]string{"create", "namespace", ns, flags.getKubeDryRunFlag("create")}, "Creating namespace [ "+ns+" ]") - if _, err := cmd.RetryExec(3); err != nil { + targetFile, err := tempBuildNamespaceDefinition(ns, labels, annotations) + if err != nil { + log.Fatal(err.Error()) + } + defer os.Remove(targetFile.Name()) + + cmd := kubectl([]string{"apply", "-f", targetFile.Name(), flags.getKubeDryRunFlag("apply")}, + "Creating namespace [ "+ns+" ]") + + if _, err := cmd.Exec(); err != nil { log.Fatalf("Failed creating namespace [ "+ns+" ] with error: %v", err) } log.Info("Namespace [ " + ns + " ] created") } +// tempBuildNamespaceDefinition creates temporary file with Namespace object definition +func tempBuildNamespaceDefinition(ns string, labels map[string]string, annotations map[string]string) (f *os.File, err error) { + definition := ` +--- +apiVersion: v1 +kind: Namespace +metadata: +` + definition += fmt.Sprintf(" name: \"%s\"\n", ns) + + metadata := make(map[string]map[string]string) + metadata["labels"] = labels + metadata["annotations"] = annotations + d, err := yaml.Marshal(&metadata) + if err != nil { + return nil, err + } + definition += Indent(string(d), strings.Repeat(" ", 2)) + + targetFile, err := ioutil.TempFile(tempFilesDir, "namespace-*.yaml") + if err != nil { + return nil, err + } + + if _, err = targetFile.Write([]byte(definition)); err != nil { + return nil, err + } + + return targetFile, nil +} + // labelNamespace labels a namespace with provided labels func labelNamespace(ns string, labels map[string]string, authoritative bool) { var nsLabels map[string]string From 955f94aa476424e3d287bfae2a143298d4b5dc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20El=20Fartas?= Date: Tue, 7 Jan 2025 22:40:43 +0100 Subject: [PATCH 2/2] Fix createNamespace "not enough arguments" error --- internal/app/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/app/main.go b/internal/app/main.go index 92ef8f2b..7052ac9b 100644 --- a/internal/app/main.go +++ b/internal/app/main.go @@ -84,7 +84,7 @@ func Main() int { if flags.nsOverride == "" { addNamespaces(&s) } else { - createNamespace(flags.nsOverride) + createNamespace(flags.nsOverride, nil, nil) s.overrideAppsNamespace(flags.nsOverride) } }