From b6087afc469519120fb730f7aeced5dc36db3f87 Mon Sep 17 00:00:00 2001 From: George Stykalin Date: Sun, 10 Aug 2025 14:28:32 +0300 Subject: [PATCH] change panic to fatal log --- internal/config/config.go | 2 +- internal/config/{utility.go => utilits.go} | 0 internal/helm_client/chart.go | 2 +- internal/helm_client/repo.go | 3 +- .../kubespray/{utility.go => playbook.go} | 46 +--- internal/kubespray/utilits.go | 54 +++++ internal/python/generate/main.go | 3 +- internal/python/utils.go | 3 +- internal/templates/{utility.go => utilits.go} | 10 +- test-conf/manifests/HA-test.yaml | 197 ++++++++++++++++++ 10 files changed, 265 insertions(+), 55 deletions(-) rename internal/config/{utility.go => utilits.go} (100%) rename internal/kubespray/{utility.go => playbook.go} (65%) create mode 100644 internal/kubespray/utilits.go rename internal/templates/{utility.go => utilits.go} (91%) create mode 100644 test-conf/manifests/HA-test.yaml diff --git a/internal/config/config.go b/internal/config/config.go index 75995a3..83dbd0e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -57,7 +57,7 @@ func createConfig(configFile string, out string, password string, verbose bool) if err := cleanenv.ReadConfig(configFile, instance); err != nil { helper, _ := cleanenv.GetDescription(instance, nil) - panic(fmt.Sprintf("%s\n%s", helper, err)) + logging.Log.Fatal(fmt.Sprintf("%s\n%s", helper, err)) } instance.BaseDir = files.CreateTempDir() diff --git a/internal/config/utility.go b/internal/config/utilits.go similarity index 100% rename from internal/config/utility.go rename to internal/config/utilits.go diff --git a/internal/helm_client/chart.go b/internal/helm_client/chart.go index d240485..a4096b0 100644 --- a/internal/helm_client/chart.go +++ b/internal/helm_client/chart.go @@ -17,7 +17,7 @@ func InstallChart(chartSpec go_helm_client.ChartSpec) { logging.Log.Infof("Upgrading %s", chartSpec.ChartName) } if _, err := helmClient.InstallOrUpgradeChart(context.Background(), &chartSpec, nil); err != nil { - panic(err) + logging.Log.Fatal(err) } } diff --git a/internal/helm_client/repo.go b/internal/helm_client/repo.go index 6056d77..1c93185 100644 --- a/internal/helm_client/repo.go +++ b/internal/helm_client/repo.go @@ -2,6 +2,7 @@ package helm_client import ( "kube-forge/internal/config" + "kube-forge/internal/logging" "helm.sh/helm/v3/pkg/repo" ) @@ -16,7 +17,7 @@ func AddHelmRepo(namespace string, repoSettings config.RepoSettings) { } if err := helmClient.AddOrUpdateChartRepo(chartRepo); err != nil { - panic(err) + logging.Log.Fatal(err) } } diff --git a/internal/kubespray/utility.go b/internal/kubespray/playbook.go similarity index 65% rename from internal/kubespray/utility.go rename to internal/kubespray/playbook.go index 0296433..22df614 100644 --- a/internal/kubespray/utility.go +++ b/internal/kubespray/playbook.go @@ -2,8 +2,6 @@ package kubespray import ( "context" - "fmt" - "io" "kube-forge/internal/config" "kube-forge/internal/logging" "kube-forge/internal/python" @@ -15,48 +13,6 @@ import ( "github.com/apenella/go-ansible/v2/pkg/playbook" ) -func getPlaybookParameters(tags string) playbook.AnsiblePlaybookOptions { - cfg := config.GetConfig() - - ansiblePlaybookOptions := playbook.AnsiblePlaybookOptions{ - Inventory: filepath.Join(cfg.InventoryDir, "hosts"), - Tags: tags, - User: cfg.Credentials.User, - Become: true, - } - - if cfg.Credentials.PrivateKeyFile != "" { - ansiblePlaybookOptions.PrivateKey = cfg.Credentials.PrivateKeyFile - } - - if cfg.Credentials.AskSudoPassword { - ansiblePlaybookOptions.AskBecomePass = true - } - - return ansiblePlaybookOptions -} - -func CopyK8SAdminConfig(outFile string) { - config := config.GetConfig() - var adminDefaultConfigPath = filepath.Join(config.InventoryDir, "artifacts/admin.conf") - source, err := os.Open(adminDefaultConfigPath) - if err != nil { - panic(err) - } - defer source.Close() - - destination, err := os.Create(outFile) - if err != nil { - panic(err) - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - panic(err) - } - logging.Log.Info(fmt.Sprintf("K8s admin config: %s", outFile)) -} - func runPlaybook(playbookPath string, tags string) { config := config.GetConfig() var callbackExecute execute.Executor @@ -111,6 +67,6 @@ func runPlaybook(playbookPath string, tags string) { err := callbackExecute.Execute(context.Background()) if err != nil { - panic(err) + logging.Log.Fatal(err) } } diff --git a/internal/kubespray/utilits.go b/internal/kubespray/utilits.go new file mode 100644 index 0000000..5ce431a --- /dev/null +++ b/internal/kubespray/utilits.go @@ -0,0 +1,54 @@ +package kubespray + +import ( + "fmt" + "io" + "kube-forge/internal/config" + "kube-forge/internal/logging" + "os" + "path/filepath" + + "github.com/apenella/go-ansible/v2/pkg/playbook" +) + +func getPlaybookParameters(tags string) playbook.AnsiblePlaybookOptions { + cfg := config.GetConfig() + + ansiblePlaybookOptions := playbook.AnsiblePlaybookOptions{ + Inventory: filepath.Join(cfg.InventoryDir, "hosts"), + Tags: tags, + User: cfg.Credentials.User, + Become: true, + } + + if cfg.Credentials.PrivateKeyFile != "" { + ansiblePlaybookOptions.PrivateKey = cfg.Credentials.PrivateKeyFile + } + + if cfg.Credentials.AskSudoPassword { + ansiblePlaybookOptions.AskBecomePass = true + } + + return ansiblePlaybookOptions +} + +func CopyK8SAdminConfig(outFile string) { + config := config.GetConfig() + var adminDefaultConfigPath = filepath.Join(config.InventoryDir, "artifacts/admin.conf") + source, err := os.Open(adminDefaultConfigPath) + if err != nil { + logging.Log.Fatal(err) + } + defer source.Close() + + destination, err := os.Create(outFile) + if err != nil { + logging.Log.Fatal(err) + } + defer destination.Close() + _, err = io.Copy(destination, source) + if err != nil { + logging.Log.Fatal(err) + } + logging.Log.Info(fmt.Sprintf("K8s admin config: %s", outFile)) +} diff --git a/internal/python/generate/main.go b/internal/python/generate/main.go index c9a2870..08c5bb1 100644 --- a/internal/python/generate/main.go +++ b/internal/python/generate/main.go @@ -1,6 +1,7 @@ package main import ( + "kube-forge/internal/logging" "runtime" "strings" @@ -22,6 +23,6 @@ func main() { pipPlatform := platforms[strings.Join([]string{os, arch}, "-")] err := pip.CreateEmbeddedPipPackages("requirements.txt", os, arch, pipPlatform, "./data/") if err != nil { - panic(err) + logging.Log.Fatal(err) } } diff --git a/internal/python/utils.go b/internal/python/utils.go index 952f371..1b110f4 100644 --- a/internal/python/utils.go +++ b/internal/python/utils.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "kube-forge/internal/logging" "kube-forge/internal/python/data" "kube-forge/internal/resources" "os" @@ -117,7 +118,7 @@ func NewPythonExec() *PythonExec { pythonLibFs, err := embed_util.NewEmbeddedFilesWithTmpDir(data.Data, pythonLibDir, true) if err != nil { - panic(err) + logging.Log.Fatal(err) } pythonLibFsPath := pythonLibFs.GetExtractedPath() resourcesFs, _ := embed_util.NewEmbeddedFilesWithTmpDir(resources.Kubespray, resourcesDir, true) diff --git a/internal/templates/utility.go b/internal/templates/utilits.go similarity index 91% rename from internal/templates/utility.go rename to internal/templates/utilits.go index 55eb431..16838cd 100644 --- a/internal/templates/utility.go +++ b/internal/templates/utilits.go @@ -15,7 +15,7 @@ func executeTemplateToString(template *template.Template, config *config.Config) templateResult := &bytes.Buffer{} err := template.Execute(templateResult, config) if err != nil { - panic(err) + logging.Log.Fatal(err) } templateResultString := templateResult.String() return templateResultString @@ -24,12 +24,12 @@ func executeTemplateToString(template *template.Template, config *config.Config) func getTemplateFromEmbedFSFolder(embedFS embed.FS, templateFile string) *template.Template { templateData, err := embedFS.ReadFile(templateFile) if err != nil { - panic(err) + logging.Log.Fatal(err) } templateDataString := string(templateData) template, err := template.New("tmpl").Funcs(funcMap()).Parse(templateDataString) if err != nil { - panic(err) + logging.Log.Fatal(err) } return template } @@ -50,12 +50,12 @@ func applyTemplates(templates [][2]string) { file, err := os.Create(outFile) if err != nil { - panic(err) + logging.Log.Fatal(err) } defer file.Close() err = tmpl.Execute(file, config) if err != nil { - panic(err) + logging.Log.Fatal(err) } } } diff --git a/test-conf/manifests/HA-test.yaml b/test-conf/manifests/HA-test.yaml new file mode 100644 index 0000000..eb1c0ab --- /dev/null +++ b/test-conf/manifests/HA-test.yaml @@ -0,0 +1,197 @@ +--- +# Namespace for testing +apiVersion: v1 +kind: Namespace +metadata: + name: ha-test + +--- +# ConfigMap with application configuration +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config + namespace: ha-test +data: + index.html: | + + + + HA Cluster Test + + + +

Kubernetes HA Cluster Test

+
+

Pod Hostname:

+

Timestamp:

+

Node IP:

+
+ + + + +--- +# Deployment with multiple replicas for HA testing +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ha-test-app + namespace: ha-test + labels: + app: ha-test-app +spec: + replicas: 6 # Deploy across multiple nodes + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 1 + selector: + matchLabels: + app: ha-test-app + template: + metadata: + labels: + app: ha-test-app + spec: + # Anti-affinity to spread pods across nodes + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - ha-test-app + topologyKey: kubernetes.io/hostname + containers: + - name: nginx + image: nginx:1.25-alpine + ports: + - containerPort: 80 + name: http + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + volumeMounts: + - name: nginx-config + mountPath: /usr/share/nginx/html + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: nginx-config + configMap: + name: nginx-config + +--- +# Service to expose the deployment +apiVersion: v1 +kind: Service +metadata: + name: ha-test-service + namespace: ha-test + labels: + app: ha-test-app +spec: + selector: + app: ha-test-app + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + type: ClusterIP + +--- +# NodePort Service for external access (alternative to ingress) +apiVersion: v1 +kind: Service +metadata: + name: ha-test-nodeport + namespace: ha-test + labels: + app: ha-test-app +spec: + selector: + app: ha-test-app + ports: + - port: 80 + targetPort: 80 + nodePort: 30080 + protocol: TCP + name: http + type: NodePort + +--- +# HorizontalPodAutoscaler for testing scaling +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: ha-test-hpa + namespace: ha-test +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: ha-test-app + minReplicas: 3 + maxReplicas: 12 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + +--- +# PodDisruptionBudget for HA +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: ha-test-pdb + namespace: ha-test +spec: + minAvailable: 2 + selector: + matchLabels: + app: ha-test-app