## Ingress NGINX & Cert-Manager Management
## Глобальный балансировщик с VPN-whitelist и Authentik SSO

# Include common variables and functions
include common/Makefile

# Ingress configuration
INGRESS_NAMESPACE := ingress-nginx
CERT_MANAGER_NAMESPACE := cert-manager
HELMFILE_NGINX := ingress/helmfile-nginx.yaml
HELMFILE_CERT_MANAGER := ingress/helmfile-cert-manager.yaml

.PHONY: ingress-help
ingress-help:
	@echo ""
	@echo "$(COLOR_BOLD)Ingress & Cert-Manager Commands:$(COLOR_RESET)"
	@echo "  make ingress-cleanup-old          - Remove old ingress-nginx installation (if installed via Ansible)"
	@echo "  make ingress-install-all          - Install ingress-nginx and cert-manager"
	@echo "  make ingress-install-nginx         - Install ingress-nginx only"
	@echo "  make ingress-update-nginx         - Update ingress-nginx with new values"
	@echo "  make ingress-uninstall-nginx      - Uninstall ingress-nginx only"
	@echo "  make ingress-install-cert-manager  - Install cert-manager only"
	@echo "  make ingress-update-cert-manager  - Update cert-manager with new values"
	@echo "  make ingress-uninstall-cert-manager - Uninstall cert-manager only"
	@echo "  make ingress-apply                - Apply all ingress manifests"
	@echo "  make ingress-status                - Check ingress and cert-manager status"
	@echo "  make ingress-uninstall             - Uninstall ingress-nginx and cert-manager"
	@echo ""
	@echo "$(COLOR_BOLD)Example Test Application:$(COLOR_RESET)"
	@echo "  make example-apply                 - Deploy test app (example.internal.ai-ops.tech)"
	@echo "  make example-delete                - Delete test app"
	@echo ""

.PHONY: ingress-cleanup-old
ingress-cleanup-old:
	$(call print_warning,Removing old ingress-nginx installation (if exists)...)
	@echo "This will remove ingress-nginx installed via Ansible/kubectl"
	@echo "Press Ctrl+C to cancel, or wait 5 seconds to continue..."
	$(call sleep_seconds,5)
	$(call print_info,Deleting old ingress-nginx resources...)
	-@$(KUBECTL) delete deployment ingress-nginx-controller -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete daemonset ingress-nginx-controller -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete service ingress-nginx-controller -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete serviceaccount ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete serviceaccount ingress-nginx-admission -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete configmap ingress-nginx-controller -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete clusterrole ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete clusterrolebinding ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete role ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete rolebinding ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete role ingress-nginx-admission -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete rolebinding ingress-nginx-admission -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete serviceaccount ingress-nginx-admission -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete job ingress-nginx-admission-create -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete job ingress-nginx-admission-patch -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete validatingwebhookconfiguration ingress-nginx-admission --ignore-not-found=true || true
	-@$(KUBECTL) delete ingressclass nginx --ignore-not-found=true || true
	-@$(KUBECTL) delete all -l app.kubernetes.io/name=ingress-nginx -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	-@$(KUBECTL) delete all -l app.kubernetes.io/component=controller -n $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	$(call print_info,Waiting for resources to be deleted...)
	$(call sleep_seconds,10)
	$(call print_success,Old ingress-nginx resources removed!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) You can now install ingress-nginx via Helm:"
	@echo "  make ingress-install-nginx"

.PHONY: ingress-install-nginx
ingress-install-nginx:
	@echo ""
	@echo "$(COLOR_YELLOW)Checking for existing ingress-nginx installation...$(COLOR_RESET)"
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$ErrorActionPreference = 'SilentlyContinue'; $$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; $$dsExists = kubectl get daemonset -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx 2>$$null; $$deployExists = kubectl get deployment -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx 2>$$null; if (($$LASTEXITCODE -eq 0) -or ($$deployExists -eq 0)) { Write-Host '$(COLOR_GREEN)ingress-nginx already installed via Helm, skipping...$(COLOR_RESET)'; exit 0 }; $$saExists = kubectl get serviceaccount ingress-nginx -n $(INGRESS_NAMESPACE) 2>$$null; $$exitCode = $$LASTEXITCODE; if ($$exitCode -eq 0) { Write-Host '$(COLOR_YELLOW)Old ingress-nginx installation detected (not via Helm)!$(COLOR_RESET)'; Write-Host '$(COLOR_YELLOW)Please run: make ingress-cleanup-old$(COLOR_RESET)'; Write-Host '$(COLOR_YELLOW)Then run this command again.$(COLOR_RESET)'; exit 1 }; exit 0"
else
	@if $(KUBECTL) get daemonset -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx >/dev/null 2>&1 || $(KUBECTL) get deployment -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx >/dev/null 2>&1; then \
		echo "$(COLOR_GREEN)ingress-nginx already installed via Helm, skipping...$(COLOR_RESET)"; \
		exit 0; \
	fi; \
	$(KUBECTL) get serviceaccount ingress-nginx -n $(INGRESS_NAMESPACE) >/dev/null 2>&1 && \
		($(call print_warning,Old ingress-nginx installation detected (not via Helm)!) && \
		 echo "$(COLOR_YELLOW)Please run: make ingress-cleanup-old$(COLOR_RESET)" && \
		 echo "$(COLOR_YELLOW)Then run this command again.$(COLOR_RESET)" && \
		 exit 1) || true
endif
	$(call print_info,Installing ingress-nginx via helmfile...)
	@$(KUBECTL) create namespace $(INGRESS_NAMESPACE) --dry-run=client -o yaml | $(KUBECTL) apply -f -
	$(call run_helmfile,$(HELMFILE_NGINX),sync)
	$(call print_info,Waiting for ingress-nginx pods to be created...)
	$(call sleep_seconds,10)
	$(call print_info,Waiting for ingress-nginx to be ready...)
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/component=controller --timeout=5m 2>/dev/null || \
	 $(KUBECTL) -n $(INGRESS_NAMESPACE) wait --for=jsonpath='{.status.numberReady}'=1 daemonset -l app.kubernetes.io/name=ingress-nginx --timeout=5m || \
	 ($(call print_warning,Some pods may not be ready yet, checking status...) && \
	  $(KUBECTL) -n $(INGRESS_NAMESPACE) get pods -l app.kubernetes.io/name=ingress-nginx && \
	  exit 0)
	$(call print_success,ingress-nginx installed!)
	@echo ""
	@echo "$(COLOR_YELLOW)Service Type: hostNetwork on all master nodes$(COLOR_RESET)"
	@echo "  HTTP: 80"
	@echo "  HTTPS: 443"
	@echo "  Note: Ingress controller (DaemonSet) is bound directly to ports 80/443 on all master nodes"

.PHONY: ingress-update-nginx
ingress-update-nginx:
	$(call print_info,Updating ingress-nginx with new values via helmfile...)
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$ErrorActionPreference = 'SilentlyContinue'; $$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl get daemonset -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx 2>$$null | Out-Null; $$dsExitCode = $$LASTEXITCODE; kubectl get deployment -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx 2>$$null | Out-Null; $$deployExitCode = $$LASTEXITCODE; if (($$dsExitCode -ne 0) -and ($$deployExitCode -ne 0)) { Write-Host '$(COLOR_YELLOW)ingress-nginx not installed. Please run: make ingress-install-nginx$(COLOR_RESET)'; exit 1 }"
else
	@if ! $(KUBECTL) get daemonset -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx >/dev/null 2>&1 && ! $(KUBECTL) get deployment -n $(INGRESS_NAMESPACE) -l app.kubernetes.io/name=ingress-nginx >/dev/null 2>&1; then \
		echo "$(COLOR_YELLOW)ingress-nginx not installed. Please run: make ingress-install-nginx$(COLOR_RESET)"; \
		exit 1; \
	fi
endif
	$(call run_helmfile,$(HELMFILE_NGINX),sync)
	$(call print_info,Waiting for ingress-nginx pods to be created...)
	$(call sleep_seconds,10)
	$(call print_info,Waiting for ingress-nginx to be ready...)
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/component=controller --timeout=5m 2>/dev/null || \
	 $(KUBECTL) -n $(INGRESS_NAMESPACE) wait --for=jsonpath='{.status.numberReady}'=1 daemonset -l app.kubernetes.io/name=ingress-nginx --timeout=5m || \
	 ($(call print_warning,Some pods may not be ready yet, checking status...) && \
	  $(KUBECTL) -n $(INGRESS_NAMESPACE) get pods -l app.kubernetes.io/name=ingress-nginx && \
	  exit 0)
	$(call print_info,Waiting for admission webhook to be ready...)
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/component=admission-webhook --timeout=2m 2>/dev/null || $(call print_warning,Admission webhook pods may not be ready yet)
	$(call print_success,ingress-nginx updated!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Ingress controller will restart with new configuration"

.PHONY: ingress-uninstall-nginx
ingress-uninstall-nginx:
	$(call print_warning,This will uninstall ingress-nginx!)
	@echo "Press Ctrl+C to cancel, or wait 10 seconds to continue..."
	$(call sleep_seconds,10)
	$(call print_info,Uninstalling ingress-nginx...)
	$(call run_helmfile,$(HELMFILE_NGINX),destroy) || true
	-@$(KUBECTL) delete namespace $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	$(call print_success,ingress-nginx uninstalled.)

.PHONY: ingress-install-cert-manager
ingress-install-cert-manager:
	$(call print_info,Installing cert-manager via helmfile...)
	@$(KUBECTL) create namespace $(CERT_MANAGER_NAMESPACE) --dry-run=client -o yaml | $(KUBECTL) apply -f -
	$(call run_helmfile,$(HELMFILE_CERT_MANAGER),sync)
	$(call print_info,Waiting for cert-manager to be ready...)
	$(call sleep_seconds,30)
	@$(KUBECTL) -n $(CERT_MANAGER_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/instance=cert-manager --timeout=5m
	$(call print_info,Creating ClusterIssuer for Let's Encrypt...)
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$manifestPath = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, 'ingress', 'manifests', 'cert-manager', 'cert-manager', 'cluster-issuer.yaml')); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl apply -f \"$$manifestPath\""
else
	@$(KUBECTL) apply -f $(CURDIR)/ingress/manifests/cert-manager/cert-manager/cluster-issuer.yaml
endif
	$(call print_info,Waiting for ClusterIssuer to be ready...)
	$(call sleep_seconds,5)
	@$(KUBECTL) get clusterissuer letsencrypt-http || ($(call print_warning,ClusterIssuer not found, check logs) && exit 1)
	$(call print_success,cert-manager installed!)
	@echo ""
	@echo "$(COLOR_YELLOW)ClusterIssuer created: letsencrypt-http$(COLOR_RESET)"
	@echo "  Challenge: HTTP-01"
	@echo "  Server: Let's Encrypt Production"
	@echo "  Note: Certificates will be automatically created when ingress resources are applied"

.PHONY: ingress-update-cert-manager
ingress-update-cert-manager:
	$(call print_info,Updating cert-manager with new values via helmfile...)
	$(call run_helmfile,$(HELMFILE_CERT_MANAGER),sync)
	$(call print_info,Waiting for cert-manager to be ready...)
	$(call sleep_seconds,30)
	@$(KUBECTL) -n $(CERT_MANAGER_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/instance=cert-manager --timeout=5m
	$(call print_info,Updating ClusterIssuer for Let's Encrypt...)
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$manifestPath = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, 'ingress', 'manifests', 'cert-manager', 'cert-manager', 'cluster-issuer.yaml')); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl apply -f \"$$manifestPath\""
else
	@$(KUBECTL) apply -f $(CURDIR)/ingress/manifests/cert-manager/cert-manager/cluster-issuer.yaml
endif
	$(call print_success,cert-manager updated!)

.PHONY: ingress-uninstall-cert-manager
ingress-uninstall-cert-manager:
	$(call print_warning,This will uninstall cert-manager!)
	@echo "Press Ctrl+C to cancel, or wait 10 seconds to continue..."
	$(call sleep_seconds,10)
	$(call print_info,Uninstalling cert-manager...)
	$(call run_helmfile,$(HELMFILE_CERT_MANAGER),destroy) || true
	-@$(KUBECTL) delete namespace $(CERT_MANAGER_NAMESPACE) --ignore-not-found=true || true
	$(call print_success,cert-manager uninstalled.)

.PHONY: ingress-install-all
ingress-install-all: ingress-install-nginx ingress-install-cert-manager
	$(call print_success,Ingress infrastructure installed!)

.PHONY: ingress-apply
ingress-apply:
	$(call print_info,Applying ingress manifests...)
	@$(KUBECTL) apply -f kafka/manifests/ingress.yaml
	@$(KUBECTL) apply -f redis/manifests/ingress.yaml
	@$(KUBECTL) apply -f vault/manifests/ingress.yaml
	@$(KUBECTL) apply -f minio/manifests/ingress.yaml
	@$(KUBECTL) apply -f nexus/manifests/ingress.yaml
	@$(KUBECTL) apply -f sonarqube/manifests/ingress.yaml
	@$(KUBECTL) apply -f authentik/manifests/ingress.yaml
	@$(KUBECTL) apply -f glitchtip/manifests/ingress.yaml
	@$(KUBECTL) apply -f longhorn/manifests/ingress.yaml
	@$(KUBECTL) apply -f k8s-dashboard/manifests/ingress.yaml
	@$(KUBECTL) apply -f monitoring/manifests/ingress/
	@$(KUBECTL) apply -f docs/ingress/
	$(call print_success,Ingress manifests applied!)

.PHONY: example-apply
example-apply:
	$(call print_info,Applying example test application...)
	@$(KUBECTL) apply -f example/manifests/namespace.yaml
	@$(KUBECTL) apply -f example/manifests/deployment.yaml
	@$(KUBECTL) apply -f example/manifests/service.yaml
	@$(KUBECTL) apply -f example/manifests/ingress.yaml
	$(call print_info,Waiting for example pod to be ready...)
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$ErrorActionPreference = 'SilentlyContinue'; $$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl -n tech-example wait --for=condition=ready pod -l app=hello-world --timeout=2m 2>$$null; exit 0"
else
	@$(KUBECTL) -n tech-example wait --for=condition=ready pod -l app=hello-world --timeout=2m 2>/dev/null || true
endif
	$(call print_success,Example application applied!)
	@echo ""
	@echo "$(COLOR_YELLOW)Test URL:$(COLOR_RESET) https://example.internal.ai-ops.tech"
	@echo "  TLS enabled (cert-manager will issue certificate automatically)"
	@echo "  No Authentik, just TLS for testing certificate issuance"

.PHONY: example-delete
example-delete:
	$(call print_warning,Deleting example test application...)
	@$(KUBECTL) delete -f example/manifests/ingress.yaml --ignore-not-found=true || true
	@$(KUBECTL) delete -f example/manifests/service.yaml --ignore-not-found=true || true
	@$(KUBECTL) delete -f example/manifests/deployment.yaml --ignore-not-found=true || true
	@$(KUBECTL) delete -f example/manifests/namespace.yaml --ignore-not-found=true || true
	$(call print_success,Example application deleted!)

.PHONY: ingress-status
ingress-status:
	@echo ""
	@echo "$(COLOR_BOLD)=== Ingress NGINX Status ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) get pods,svc || echo "ingress-nginx not installed"
	@echo ""
	@echo "$(COLOR_BOLD)=== Cert-Manager Status ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(CERT_MANAGER_NAMESPACE) get pods || echo "cert-manager not installed"
	@echo ""
	@echo "$(COLOR_BOLD)=== ClusterIssuer Status ===$(COLOR_RESET)"
	@$(KUBECTL) get clusterissuer || echo "No ClusterIssuers found"
	@echo ""
	@echo "$(COLOR_BOLD)=== Ingress Resources ===$(COLOR_RESET)"
	@$(KUBECTL) get ingress -A || echo "No Ingress resources found"
	@echo ""
	@echo "$(COLOR_BOLD)=== Certificate Status ===$(COLOR_RESET)"
	@$(KUBECTL) get certificate -A || echo "No Certificates found"
	@echo ""
	@echo "$(COLOR_BOLD)=== Admission Webhook Status ===$(COLOR_RESET)"
	@$(KUBECTL) get validatingwebhookconfiguration ingress-nginx-admission 2>/dev/null || echo "Admission webhook not found"
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) get svc ingress-nginx-controller-admission 2>/dev/null || echo "Admission webhook service not found"
	@$(KUBECTL) -n $(INGRESS_NAMESPACE) get pods -l app.kubernetes.io/component=admission-webhook 2>/dev/null || echo "Admission webhook pods not found"

.PHONY: ingress-uninstall
ingress-uninstall:
	$(call print_warning,This will uninstall ingress-nginx and cert-manager!)
	@echo "Press Ctrl+C to cancel, or wait 10 seconds to continue..."
	$(call sleep_seconds,10)
	$(call print_info,Uninstalling ingress-nginx...)
	$(call run_helmfile,$(HELMFILE_NGINX),destroy) || true
	-@$(KUBECTL) delete namespace $(INGRESS_NAMESPACE) --ignore-not-found=true || true
	$(call print_info,Uninstalling cert-manager...)
	$(call run_helmfile,$(HELMFILE_CERT_MANAGER),destroy) || true
	-@$(KUBECTL) delete namespace $(CERT_MANAGER_NAMESPACE) --ignore-not-found=true || true
	$(call print_success,Ingress infrastructure uninstalled.)
