diff --git a/helm/chart/templates/deployment.yaml b/helm/chart/templates/deployment.yaml index 20cebec..03b19c0 100644 --- a/helm/chart/templates/deployment.yaml +++ b/helm/chart/templates/deployment.yaml @@ -2,18 +2,24 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Release.Name }} - namespace: {{ .Values.namespace }} + labels: + app: {{ .Release.Name }} + spec: replicas: 1 + selector: matchLabels: app: {{ .Release.Name }} + template: metadata: labels: app: {{ .Release.Name }} + spec: containers: - name: app - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + image: nginx:latest + ports: + - containerPort: 80 diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index c08910c..d4fc39c 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -9,14 +9,22 @@ func Run(envName string, dryRun bool) error { return err } - //////////////////////////////////////////////////// - // PREFLIGHT FIRST - //////////////////////////////////////////////////// + //////////////////////////////////// + // PREFLIGHT + //////////////////////////////////// if err := Preflight(environment); err != nil { return err } + //////////////////////////////////// + // ENSURE NAMESPACE + //////////////////////////////////// + + if err := EnsureNamespace(environment); err != nil { + return err + } + command, _, err := BuildCommand(environment) if err != nil { return err @@ -28,5 +36,21 @@ func Run(envName string, dryRun bool) error { fmt.Println("Starting deployment...") - return executor.Run(command.Name, command.Args...) + if err := executor.Run(command.Name, command.Args...); err != nil { + return err + } + + //////////////////////////////////// + // SKIP ROLLOUT FOR DRY RUN + //////////////////////////////////// + + if dryRun { + return nil + } + + //////////////////////////////////// + // MONITOR ROLLOUT + //////////////////////////////////// + + return MonitorRollout(environment) } diff --git a/pkg/deploy/namespace.go b/pkg/deploy/namespace.go new file mode 100644 index 0000000..9f93ca0 --- /dev/null +++ b/pkg/deploy/namespace.go @@ -0,0 +1,65 @@ +package deploy + +import ( + "fmt" + "os/exec" + + "github.com/aryansharma9917/codewise-cli/pkg/env" +) + +func namespaceExists(namespace string, context string) bool { + + args := []string{"get", "ns", namespace} + + if context != "" { + args = append(args, "--context", context) + } + + cmd := exec.Command("kubectl", args...) + + if err := cmd.Run(); err != nil { + return false + } + + return true +} + +func createNamespace(namespace string, context string) error { + + args := []string{"create", "ns", namespace} + + if context != "" { + args = append(args, "--context", context) + } + + cmd := exec.Command("kubectl", args...) + + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to create namespace: %s", string(output)) + } + + return nil +} + +func EnsureNamespace(environment *env.Env) error { + + ns := environment.K8s.Namespace + ctx := environment.K8s.Context + + fmt.Printf("Checking namespace \"%s\"...\n", ns) + + if namespaceExists(ns, ctx) { + fmt.Println("Namespace exists") + return nil + } + + fmt.Println("Namespace not found. Creating namespace...") + + if err := createNamespace(ns, ctx); err != nil { + return err + } + + fmt.Println("Namespace created") + return nil +} diff --git a/pkg/deploy/rollout.go b/pkg/deploy/rollout.go new file mode 100644 index 0000000..0c3b3bf --- /dev/null +++ b/pkg/deploy/rollout.go @@ -0,0 +1,96 @@ +package deploy + +import ( + "fmt" + "os/exec" + "strings" + "time" + + "github.com/aryansharma9917/codewise-cli/pkg/env" +) + +func getDeployments(namespace string, context string) ([]string, error) { + + args := []string{ + "get", + "deployments", + "-n", + namespace, + "-o", + "name", + } + + if context != "" { + args = append(args, "--context", context) + } + + cmd := exec.Command("kubectl", args...) + out, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("failed to list deployments") + } + + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + + var deployments []string + for _, line := range lines { + if strings.TrimSpace(line) != "" { + deployments = append(deployments, line) + } + } + + return deployments, nil +} + +func waitForDeployment(deployment string, namespace string, context string) error { + + args := []string{ + "rollout", + "status", + deployment, + "-n", + namespace, + "--timeout=120s", + } + + if context != "" { + args = append(args, "--context", context) + } + + cmd := exec.Command("kubectl", args...) + cmd.Stdout = nil + cmd.Stderr = nil + + return cmd.Run() +} + +func MonitorRollout(environment *env.Env) error { + + ns := environment.K8s.Namespace + ctx := environment.K8s.Context + + fmt.Println("Waiting for deployment rollout...") + + deployments, err := getDeployments(ns, ctx) + if err != nil { + return err + } + + if len(deployments) == 0 { + fmt.Println("No deployments found. Skipping rollout monitoring.") + return nil + } + + for _, deploy := range deployments { + fmt.Printf("Monitoring %s...\n", deploy) + + if err := waitForDeployment(deploy, ns, ctx); err != nil { + return fmt.Errorf("deployment %s failed to roll out", deploy) + } + + time.Sleep(500 * time.Millisecond) + } + + fmt.Println("All deployments successfully rolled out.") + return nil +}