## Authentik Management
## Authentik через официальный Helm chart

# Include common variables and functions
include common/Makefile

# Authentik configuration
# Using common namespace variables from common/Makefile

.PHONY: authentik-help
authentik-help:
	@echo ""
	@echo "$(COLOR_BOLD)Authentik Commands:$(COLOR_RESET)"
	@echo "  make authentik-install         - Install Authentik"
	@echo "  make authentik-update          - Update Authentik with new values"
	@echo "  make authentik-uninstall        - Uninstall Authentik"
	@echo "  make authentik-create-secret   - Create secrets (SECRET_KEY, PostgreSQL password)"
	@echo "  make authentik-update-secret   - Update secrets (SECRET_KEY, PostgreSQL password)"
	@echo "  make authentik-delete-secret   - Delete secrets"
	@echo "  make authentik-get-secret      - Get secret info"
	@echo "  make authentik-create-db       - Create PostgreSQL database and user for authentik"
	@echo "  make authentik-create-token    - Create API token for programmatic access (CI/CD, automation)"
	@echo "  make authentik-status          - Check Authentik status"
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Before installing:"
	@echo "  1. PostgreSQL cluster pg-public must be running"
	@echo "  2. Create secrets: make authentik-create-secret"
	@echo "  3. Create database: make authentik-create-db"
	@echo "  4. Prepare nodes: cd ../.. && make k8s-prepare-nodes"

.PHONY: authentik-check-postgres
authentik-check-postgres:
	$(call check_postgres_cluster)

.PHONY: authentik-create-secret
authentik-create-secret:
	$(call print_info,Creating namespace $(AUTHENTIK_NAMESPACE) if not exists...)
	@$(KUBECTL) apply -f authentik/manifests/namespace.yaml
	@echo ""
	@echo "$(COLOR_YELLOW)Creating Authentik secrets...$(COLOR_RESET)"
	@echo "$(COLOR_YELLOW)You will be prompted for:$(COLOR_RESET)"
	@echo "  1. SECRET_KEY (Django secret key - REQUIRED for security)"
	@echo "     Used for: session signing, CSRF tokens, password hashing, user IDs"
	@echo "     Generate with: openssl rand -hex 32"
	@echo "     IMPORTANT: Never change this after first install!"
	@echo "  2. PostgreSQL password for authentik user"
	@echo "     Note: Password can be obtained from Crunchy secret:"
	@echo "       kubectl -n tech-postgres-databases get secret pg-public-pguser-authentik -o jsonpath='{.data.password}' | base64 -d"
	@echo ""
	@echo "$(COLOR_YELLOW)Enter SECRET_KEY (random string, e.g., use: openssl rand -hex 32):$(COLOR_RESET)"
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$secretKey = Read-Host -Prompt '> '; Write-Host ''; Write-Host '$(COLOR_YELLOW)Enter PostgreSQL password for authentik user:$(COLOR_RESET)'; $$pgPassSecure = Read-Host -AsSecureString -Prompt '> '; $$pgPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($$pgPassSecure)); $$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl -n $(AUTHENTIK_NAMESPACE) delete secret authentik-secrets --ignore-not-found=true 2>$$null; kubectl -n $(AUTHENTIK_NAMESPACE) create secret generic authentik-secrets --from-literal=secret-key=$$secretKey --from-literal=postgresql-password=$$pgPass"
else
	@read -s -p "> " secretKey && echo "" && \
		echo "$(COLOR_YELLOW)Enter PostgreSQL password for authentik user:$(COLOR_RESET)" && \
		read -s -p "> " pgPass && echo "" && \
		$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) delete secret authentik-secrets --ignore-not-found=true 2>/dev/null || true && \
		$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) create secret generic authentik-secrets --from-literal=secret-key=$$secretKey --from-literal=postgresql-password=$$pgPass
endif
	$(call print_success,Secret created!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Make sure the PostgreSQL user 'authentik' exists in pg-public cluster"
	@echo "  Run: make authentik-create-db"

.PHONY: authentik-update-secret
authentik-update-secret:
	$(call print_info,Updating Authentik secrets...)
	@echo ""
	@echo "$(COLOR_YELLOW)You will be prompted for:$(COLOR_RESET)"
	@echo "  1. SECRET_KEY (Django secret key - REQUIRED for security)"
	@echo "     IMPORTANT: Never change this after first install!"
	@echo "  2. PostgreSQL password for authentik user"
	@echo ""
	@echo "$(COLOR_YELLOW)Enter SECRET_KEY (random string, e.g., use: openssl rand -hex 32):$(COLOR_RESET)"
ifeq ($(DETECTED_OS),Windows)
	@powershell -NoProfile -Command "$$secretKey = Read-Host -Prompt '> '; Write-Host ''; Write-Host '$(COLOR_YELLOW)Enter PostgreSQL password for authentik user:$(COLOR_RESET)'; $$pgPassSecure = Read-Host -AsSecureString -Prompt '> '; $$pgPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($$pgPassSecure)); $$curDir = [System.IO.Directory]::GetCurrentDirectory(); $$kubeconfig = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($$curDir, '$(KUBECONFIG_REL)')); $$env:KUBECONFIG = $$kubeconfig; kubectl -n $(AUTHENTIK_NAMESPACE) delete secret authentik-secrets --ignore-not-found=true 2>$$null; kubectl -n $(AUTHENTIK_NAMESPACE) create secret generic authentik-secrets --from-literal=secret-key=$$secretKey --from-literal=postgresql-password=$$pgPass"
else
	@read -s -p "> " secretKey && echo "" && \
		echo "$(COLOR_YELLOW)Enter PostgreSQL password for authentik user:$(COLOR_RESET)" && \
		read -s -p "> " pgPass && echo "" && \
		$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) delete secret authentik-secrets --ignore-not-found=true 2>/dev/null || true && \
		$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) create secret generic authentik-secrets --from-literal=secret-key=$$secretKey --from-literal=postgresql-password=$$pgPass
endif
	$(call print_success,Secret updated!)

.PHONY: authentik-delete-secret
authentik-delete-secret:
	$(call print_warning,This will delete the authentik-secrets secret!)
	@echo "Press Ctrl+C to cancel, or wait 5 seconds to continue..."
	$(call sleep_seconds,5)
	$(call print_info,Deleting secret authentik-secrets...)
	-@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) delete secret authentik-secrets || true
	$(call print_success,Secret deleted!)

.PHONY: authentik-get-secret
authentik-get-secret:
	@echo ""
	@echo "$(COLOR_BOLD)=== Authentik Secret Info ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) get secret authentik-secrets >/dev/null 2>&1 && \
		($(call print_success,Secret authentik-secrets exists) && \
		 echo "$(COLOR_YELLOW)Secret keys:$(COLOR_RESET)" && \
		 echo "$(COLOR_YELLOW)Secret keys:$(COLOR_RESET)" && \
		 $(call get_secret_keys,$(AUTHENTIK_NAMESPACE),authentik-secrets)) || \
		($(call print_warning,Secret authentik-secrets not found))
	@echo ""

.PHONY: authentik-create-db
authentik-create-db:
	@echo ""
	@echo "$(COLOR_BOLD)=== Creating PostgreSQL database and user for Authentik ===$(COLOR_RESET)"
	@echo ""
	@echo "$(COLOR_YELLOW)This will create:$(COLOR_RESET)"
	@echo "  - User: authentik"
	@echo "  - Database: authentik"
	@echo ""
	@echo "$(COLOR_YELLOW)You will be prompted for the PostgreSQL password for the 'authentik' user.$(COLOR_RESET)"
	@echo ""
	@echo "$(COLOR_YELLOW)Enter PostgreSQL password for authentik user:$(COLOR_RESET)"
	@read -s -p "> " pgPass && echo "" && \
		podName=$$($(KUBECTL) -n tech-postgres-databases get pod -l cluster-name=pg-public,spilo-role=master -o jsonpath='{.items[0].metadata.name}' 2>/dev/null) && \
		if [ -z "$$podName" ]; then \
			$(call print_warning,Failed to get PostgreSQL master pod) && exit 1; \
		fi && \
		pgPassEscaped=$$(echo "$$pgPass" | sed "s/'/''/g") && \
		$(KUBECTL) -n tech-postgres-databases exec $$podName -- psql -U postgres -c "CREATE USER authentik WITH PASSWORD '$$pgPassEscaped';" 2>/dev/null || echo "User may already exist, continuing..." && \
		$(KUBECTL) -n tech-postgres-databases exec $$podName -- psql -U postgres -c "CREATE DATABASE authentik OWNER authentik;" 2>/dev/null || echo "Database may already exist, continuing..." && \
		$(KUBECTL) -n tech-postgres-databases exec $$podName -- psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE authentik TO authentik;" 2>/dev/null && \
		echo "$(COLOR_GREEN)Database and user created successfully!$(COLOR_RESET)"
	$(call print_success,PostgreSQL database and user created!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Make sure the password matches the one in authentik-secrets secret"

.PHONY: authentik-create-token
authentik-create-token:
	@echo ""
	@echo "$(COLOR_BOLD)=== Creating Authentik API Token ===$(COLOR_RESET)"
	@echo ""
	@echo "$(COLOR_YELLOW)Purpose:$(COLOR_RESET) Create an API token for programmatic access to Authentik API"
	@echo "$(COLOR_YELLOW)Use cases:$(COLOR_RESET)"
	@echo "  - Automation and scripting (CI/CD pipelines)"
	@echo "  - Integration with external systems"
	@echo "  - Management via API instead of web UI"
	@echo "  - Terraform/Ansible automation"
	@echo ""
	@echo "$(COLOR_YELLOW)You will be prompted for:$(COLOR_RESET)"
	@echo "  - Token identifier (name/description for identification)"
	@echo "  - Token expiration (optional, format: YYYY-MM-DD or leave empty for no expiration)"
	@echo ""
	@bash authentik/scripts/create-token.sh $(AUTHENTIK_NAMESPACE) $(KUBECONFIG) || \
		($(call print_warning,Error creating token. Check Authentik pods and logs.) && exit 1)

.PHONY: authentik-install
authentik-install: install-namespaces authentik-check-postgres
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Make sure secrets are created:"
	@echo "  make authentik-create-secret"
	@echo ""
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) get secret authentik-secrets || \
		($(call print_warning,Authentik secrets not found!) && \
		 echo "$(COLOR_YELLOW)Please create secrets first:$(COLOR_RESET)" && \
		 echo "  make authentik-create-secret" && \
		 exit 1)
	$(call print_info,Applying Authentik resource policies...)
	@$(KUBECTL) apply -f authentik/manifests/limitrange.yaml
	@$(KUBECTL) apply -f authentik/manifests/resourcequota.yaml
	$(call print_info,Installing Authentik via helmfile...)
	$(call run_helmfile,authentik/helmfile.yaml,sync)
	$(call print_info,Waiting for Authentik to be ready...)
	$(call sleep_seconds,30)
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/name=authentik,app.kubernetes.io/component=server --timeout=10m
	$(call print_success,Authentik installed!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Authentik may take 2-5 minutes to fully start"
	@echo "Monitor with: make authentik-status"

.PHONY: authentik-update
authentik-update:
	$(call print_info,Updating Authentik resource policies...)
	@$(KUBECTL) apply -f authentik/manifests/limitrange.yaml
	@$(KUBECTL) apply -f authentik/manifests/resourcequota.yaml
	$(call print_info,Updating Authentik with new values via helmfile...)
	$(call run_helmfile,authentik/helmfile.yaml,sync)
	$(call print_info,Waiting for Authentik to be ready...)
	$(call sleep_seconds,30)
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) wait --for=condition=ready pod -l app.kubernetes.io/name=authentik,app.kubernetes.io/component=server --timeout=10m
	$(call print_success,Authentik updated!)
	@echo ""
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Authentik pods will restart with new configuration"

.PHONY: authentik-uninstall
authentik-uninstall:
	$(call print_warning,This will uninstall Authentik!)
	@echo "$(COLOR_YELLOW)Note:$(COLOR_RESET) Data in PostgreSQL will NOT be deleted."
	@echo "Press Ctrl+C to cancel, or wait 10 seconds to continue..."
	$(call sleep_seconds,10)
	$(call print_info,Uninstalling Authentik...)
	$(call run_helmfile,authentik/helmfile.yaml,destroy) || true
	$(call print_success,Authentik uninstalled. PostgreSQL data is preserved.)

.PHONY: authentik-status
authentik-status:
	@echo ""
	@echo "$(COLOR_BOLD)=== Authentik Status ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) get pods -o wide
	@echo ""
	@echo "$(COLOR_BOLD)=== Authentik Services ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) get svc
	@echo ""
	@echo "$(COLOR_BOLD)=== Authentik Pod Logs (last 20 lines) ===$(COLOR_RESET)"
	@$(KUBECTL) -n $(AUTHENTIK_NAMESPACE) logs -l app.kubernetes.io/name=authentik,app.kubernetes.io/component=server --tail=20 2>&1 || \
		echo "No logs available"
	@echo ""
