From 00dcce1ca60e2abe3ba09ca8dcbab71506f30b54 Mon Sep 17 00:00:00 2001 From: aantoni Date: Thu, 12 Feb 2026 17:22:03 +0100 Subject: [PATCH 1/2] sort the stack files based on resource kind priority --- internal/constants/constants.go | 38 +++++++++++++++++++++++++++++++++ internal/k8s/actions/apply.go | 32 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 82de9f4..b7924a0 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -215,3 +215,41 @@ var MigrationStatsFields = []string{ "fully_migrated_positions", "status", } + +// getKindPriority returns the installation priority for a resource kind +// Lower number = applied first (follows Helm 2.10 install order) +func GetKindPriority(kind string) int { + priorities := map[string]int{ + "Namespace": 0, + "ResourceQuota": 1, + "LimitRange": 2, + "PodSecurityPolicy": 3, + "Secret": 4, + "ConfigMap": 5, + "StorageClass": 6, + "PersistentVolume": 7, + "PersistentVolumeClaim": 8, + "ServiceAccount": 9, + "CustomResourceDefinition": 10, + "ClusterRole": 11, + "ClusterRoleBinding": 12, + "Role": 13, + "RoleBinding": 14, + "Service": 15, + "DaemonSet": 16, + "Pod": 17, + "ReplicationController": 18, + "ReplicaSet": 19, + "Deployment": 20, + "StatefulSet": 21, + "Job": 22, + "CronJob": 23, + "Ingress": 24, + "APIService": 25, + } + + if priority, exists := priorities[kind]; exists { + return priority + } + return 100 // Unknown kinds applied last +} diff --git a/internal/k8s/actions/apply.go b/internal/k8s/actions/apply.go index e277529..eaa6d7e 100644 --- a/internal/k8s/actions/apply.go +++ b/internal/k8s/actions/apply.go @@ -5,7 +5,9 @@ import ( "fmt" "os" "path/filepath" + "sort" + "github.com/OpenSlides/openslides-cli/internal/constants" "github.com/OpenSlides/openslides-cli/internal/k8s/client" "github.com/OpenSlides/openslides-cli/internal/logger" "github.com/OpenSlides/openslides-cli/internal/utils" @@ -108,6 +110,8 @@ func applyDirectory(ctx context.Context, k8sClient *client.Client, dirPath strin return fmt.Errorf("reading directory: %w", err) } + // Filter YAML files + var yamlFiles []os.DirEntry for _, file := range files { if file.IsDir() { continue @@ -117,7 +121,18 @@ func applyDirectory(ctx context.Context, k8sClient *client.Client, dirPath strin logger.Debug("Skipping non-YAML file: %s", file.Name()) continue } + yamlFiles = append(yamlFiles, file) + } + + // Sort by resource kind priority + sort.Slice(yamlFiles, func(i, j int) bool { + kindI := getKindFromFile(filepath.Join(dirPath, yamlFiles[i].Name())) + kindJ := getKindFromFile(filepath.Join(dirPath, yamlFiles[j].Name())) + return constants.GetKindPriority(kindI) < constants.GetKindPriority(kindJ) + }) + // Apply in sorted order + for _, file := range yamlFiles { manifestPath := filepath.Join(dirPath, file.Name()) if _, err := applyManifest(ctx, k8sClient, manifestPath); err != nil { logger.Warn("Failed to apply %s: %v", file.Name(), err) @@ -127,3 +142,20 @@ func applyDirectory(ctx context.Context, k8sClient *client.Client, dirPath strin return nil } + +// getKindFromFile reads the Kind field from a YAML file +func getKindFromFile(path string) string { + data, err := os.ReadFile(path) + if err != nil { + return "" + } + + var obj struct { + Kind string `yaml:"kind"` + } + if err := yaml.Unmarshal(data, &obj); err != nil { + return "" + } + + return obj.Kind +} From f74b104d0dab1d93c498774e05381394792bf963 Mon Sep 17 00:00:00 2001 From: aantoni Date: Thu, 12 Feb 2026 17:29:44 +0100 Subject: [PATCH 2/2] use typesafe unstructured obj --- internal/constants/constants.go | 2 +- internal/k8s/actions/apply.go | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/internal/constants/constants.go b/internal/constants/constants.go index b7924a0..5472d61 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -251,5 +251,5 @@ func GetKindPriority(kind string) int { if priority, exists := priorities[kind]; exists { return priority } - return 100 // Unknown kinds applied last + return 100 } diff --git a/internal/k8s/actions/apply.go b/internal/k8s/actions/apply.go index eaa6d7e..30c3d40 100644 --- a/internal/k8s/actions/apply.go +++ b/internal/k8s/actions/apply.go @@ -110,7 +110,6 @@ func applyDirectory(ctx context.Context, k8sClient *client.Client, dirPath strin return fmt.Errorf("reading directory: %w", err) } - // Filter YAML files var yamlFiles []os.DirEntry for _, file := range files { if file.IsDir() { @@ -124,14 +123,12 @@ func applyDirectory(ctx context.Context, k8sClient *client.Client, dirPath strin yamlFiles = append(yamlFiles, file) } - // Sort by resource kind priority sort.Slice(yamlFiles, func(i, j int) bool { kindI := getKindFromFile(filepath.Join(dirPath, yamlFiles[i].Name())) kindJ := getKindFromFile(filepath.Join(dirPath, yamlFiles[j].Name())) return constants.GetKindPriority(kindI) < constants.GetKindPriority(kindJ) }) - // Apply in sorted order for _, file := range yamlFiles { manifestPath := filepath.Join(dirPath, file.Name()) if _, err := applyManifest(ctx, k8sClient, manifestPath); err != nil { @@ -150,12 +147,10 @@ func getKindFromFile(path string) string { return "" } - var obj struct { - Kind string `yaml:"kind"` - } + var obj unstructured.Unstructured if err := yaml.Unmarshal(data, &obj); err != nil { return "" } - return obj.Kind + return obj.GetKind() }