#!/bin/bash # ============================================================================= # Setup da Aula 10 - GitLab via Helm (Hetzner Cloud) # ============================================================================= # # Este script instala e configura: # 1. cert-manager (opcional, para Let's Encrypt) # 2. GitLab com todos os componentes # # Pré-requisitos: # - Kubernetes cluster Talos na Hetzner (aula-08) com: # - Hetzner CSI Driver (StorageClass: hcloud-volumes) # - NGINX Ingress Controller com LoadBalancer # - kubectl configurado (KUBECONFIG=../aula-08/kubeconfig) # - Helm 3.x instalado # # Uso: # export KUBECONFIG=$(pwd)/../aula-08/kubeconfig # chmod +x setup.sh # ./setup.sh # # ============================================================================= set -e # Cores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERRO]${NC} $1"; } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Variáveis de configuração GITLAB_HOST="" REGISTRY_HOST="" # Derivado automaticamente DOMAIN="" # Extraído automaticamente do GITLAB_HOST USE_CLOUDFLARE="" USE_LETSENCRYPT="" LETSENCRYPT_EMAIL="" # Hetzner Object Storage S3_ENDPOINT="" S3_ACCESS_KEY="" S3_SECRET_KEY="" S3_BUCKET="" S3_REGION="" # ============================================================================= # FUNÇÕES DE CONFIGURAÇÃO # ============================================================================= save_config() { cat > "$SCRIPT_DIR/.env" </dev/null || true helm repo update jetstack if helm status cert-manager -n cert-manager &> /dev/null; then log_success "cert-manager já está instalado" else helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.16.2 \ --set crds.enabled=true \ --wait \ --timeout 5m log_success "cert-manager instalado" fi } create_cluster_issuer() { log_info "Criando ClusterIssuer para Let's Encrypt..." cat </dev/null || echo "") # Extrair nome do host (ex: git.kube.quest → git) GITLAB_NAME=$(echo "$GITLAB_HOST" | cut -d. -f1) REGISTRY_NAME=$(echo "$REGISTRY_HOST" | sed "s/\.${DOMAIN}$//" ) echo "" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" echo -e "${CYAN} Configure o DNS${NC}" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" if [[ "$USE_CLOUDFLARE" == "true" ]]; then echo "" echo "No painel do CloudFlare (https://dash.cloudflare.com):" echo "" echo -e " ${YELLOW}Tipo:${NC} A" echo -e " ${YELLOW}Nome:${NC} ${GITLAB_NAME}" echo -e " ${YELLOW}Conteúdo:${NC} ${GREEN}${LB_IP}${NC}" echo -e " ${YELLOW}Proxy:${NC} ✓ (ícone laranja)" echo "" echo -e " ${YELLOW}Tipo:${NC} A" echo -e " ${YELLOW}Nome:${NC} ${REGISTRY_NAME}" echo -e " ${YELLOW}Conteúdo:${NC} ${GREEN}${LB_IP}${NC}" echo -e " ${YELLOW}Proxy:${NC} ✓ (ícone laranja)" echo "" echo -e "${GREEN}O CloudFlare cuida do TLS automaticamente!${NC}" else echo "" echo "No seu provedor DNS:" echo "" echo -e " ${YELLOW}Tipo:${NC} A" echo -e " ${YELLOW}Nome:${NC} ${GITLAB_NAME}" echo -e " ${YELLOW}Valor:${NC} ${GREEN}${LB_IP}${NC}" echo "" echo -e " ${YELLOW}Tipo:${NC} A" echo -e " ${YELLOW}Nome:${NC} ${REGISTRY_NAME}" echo -e " ${YELLOW}Valor:${NC} ${GREEN}${LB_IP}${NC}" if [[ "$USE_LETSENCRYPT" == "true" ]]; then echo "" echo -e "${GREEN}Let's Encrypt irá emitir certificados automaticamente!${NC}" echo -e "Aguarde ~2 minutos após configurar o DNS." fi fi # Determinar protocolo PROTOCOL="https" if [[ "$USE_CLOUDFLARE" == "false" && "$USE_LETSENCRYPT" == "false" ]]; then PROTOCOL="http" fi echo "" echo -e "Acesse: ${GREEN}${PROTOCOL}://${GITLAB_HOST}${NC}" } # ============================================================================= # VERIFICAÇÕES INICIAIS # ============================================================================= log_info "Verificando pré-requisitos..." if ! command -v kubectl &> /dev/null; then log_error "kubectl não encontrado" exit 1 fi log_success "kubectl encontrado" if ! command -v helm &> /dev/null; then log_error "Helm não encontrado" exit 1 fi log_success "Helm $(helm version --short) encontrado" if ! kubectl cluster-info &> /dev/null; then log_error "Não foi possível conectar ao cluster" exit 1 fi log_success "Conectado ao cluster Kubernetes" # ============================================================================= # 1. VERIFICAR PRÉ-REQUISITOS DA AULA-08 # ============================================================================= log_info "=== Verificando infraestrutura (aula-08) ===" # Verificar Hetzner CSI Driver if ! kubectl get storageclass hcloud-volumes &> /dev/null; then log_error "StorageClass hcloud-volumes não encontrado!" log_error "Execute primeiro o setup.sh da aula-08 para instalar o CSI Driver." exit 1 fi log_success "Hetzner CSI Driver instalado (hcloud-volumes)" # Verificar NGINX Ingress if ! kubectl get ingressclass nginx &> /dev/null; then log_error "NGINX Ingress não encontrado!" log_error "Execute primeiro o setup.sh da aula-08 para instalar o Ingress Controller." exit 1 fi log_success "NGINX Ingress Controller instalado" echo "" # ============================================================================= # 2. COLETAR INPUT DO USUÁRIO # ============================================================================= collect_user_input echo "" # ============================================================================= # 3. MOSTRAR DNS E AGUARDAR CONFIGURAÇÃO (ANTES DO GITLAB!) # ============================================================================= # IMPORTANTE: Para Let's Encrypt funcionar, o DNS precisa estar configurado # ANTES da instalação do GitLab. O HTTP-01 challenge requer que: # 1. O DNS aponte para o LoadBalancer # 2. O cert-manager crie o pod acme-http-solver # 3. Let's Encrypt acesse http://dominio/.well-known/acme-challenge/token log_info "=== Configuração de DNS ===" show_dns_instructions echo "" echo -e "${YELLOW}════════════════════════════════════════════════════════════════${NC}" echo -e "${YELLOW} IMPORTANTE: Configure o DNS AGORA antes de continuar!${NC}" echo -e "${YELLOW}════════════════════════════════════════════════════════════════${NC}" echo "" if [[ "$USE_LETSENCRYPT" == "true" ]]; then echo -e "O Let's Encrypt precisa que o DNS já esteja configurado para" echo -e "validar o domínio via HTTP-01 challenge." echo "" fi echo -n "Pressione ENTER após configurar o DNS (ou 's' para pular): " read -r dns_confirm if [[ "$dns_confirm" == "s" || "$dns_confirm" == "S" ]]; then log_warn "DNS não configurado - certificados podem falhar!" else log_success "DNS confirmado pelo usuário" fi echo "" # ============================================================================= # 4. INSTALAR CERT-MANAGER (se Let's Encrypt) # ============================================================================= if [[ "$USE_LETSENCRYPT" == "true" ]]; then log_info "=== Configurando cert-manager ===" install_cert_manager create_cluster_issuer echo "" fi # ============================================================================= # 5. ADICIONAR REPOSITÓRIO HELM # ============================================================================= log_info "=== Preparando instalação do GitLab ===" log_info "Adicionando repositório Helm do GitLab..." helm repo add gitlab https://charts.gitlab.io/ 2>/dev/null || true helm repo update # ============================================================================= # 6. CRIAR NAMESPACE # ============================================================================= log_info "Criando namespace gitlab..." kubectl create namespace gitlab --dry-run=client -o yaml | kubectl apply -f - echo "" # ============================================================================= # 7. CRIAR SECRETS DO OBJECT STORAGE # ============================================================================= create_object_storage_secrets echo "" # ============================================================================= # 8. INSTALAR GITLAB VIA HELM # ============================================================================= log_info "=== Instalando GitLab (isso pode levar 10-15 minutos) ===" # Construir argumentos do Helm dinamicamente HELM_ARGS="" # Detectar cert-manager já instalado (ex: aula-09) # Se existe, desabilitar o bundled para evitar conflito de CRDs if kubectl get crd certificates.cert-manager.io &> /dev/null; then log_info "cert-manager detectado - usando instalação existente" HELM_ARGS="$HELM_ARGS --set installCertmanager=false" fi # Configurar hosts HELM_ARGS="$HELM_ARGS --set global.hosts.domain=${DOMAIN}" HELM_ARGS="$HELM_ARGS --set global.hosts.gitlab.name=${GITLAB_HOST}" HELM_ARGS="$HELM_ARGS --set global.hosts.registry.name=${REGISTRY_HOST}" # MinIO desabilitado - usando Hetzner Object Storage # Configurar TLS if [[ "$USE_LETSENCRYPT" == "true" ]]; then # Let's Encrypt: TLS gerenciado pelo cert-manager HELM_ARGS="$HELM_ARGS --set global.ingress.configureCertmanager=true" HELM_ARGS="$HELM_ARGS --set global.ingress.tls.enabled=true" HELM_ARGS="$HELM_ARGS --set global.hosts.https=true" HELM_ARGS="$HELM_ARGS --set certmanager-issuer.email=${LETSENCRYPT_EMAIL}" # Adicionar annotation do ClusterIssuer HELM_ARGS="$HELM_ARGS --set global.ingress.annotations.cert-manager\\.io/cluster-issuer=letsencrypt-prod" elif [[ "$USE_CLOUDFLARE" == "true" ]]; then # CloudFlare: TLS na edge, backend HTTP # Workhorse precisa confiar nos IPs do CloudFlare para X-Forwarded-For HELM_ARGS="$HELM_ARGS --set global.ingress.configureCertmanager=false" HELM_ARGS="$HELM_ARGS --set certmanager-issuer.install=false" HELM_ARGS="$HELM_ARGS --set global.ingress.tls.enabled=false" HELM_ARGS="$HELM_ARGS --set global.hosts.https=true" # CloudFlare IPv4 CIDRs (https://www.cloudflare.com/ips-v4) CLOUDFLARE_CIDRS='["173.245.48.0/20","103.21.244.0/22","103.22.200.0/22","103.31.4.0/22","141.101.64.0/18","108.162.192.0/18","190.93.240.0/20","188.114.96.0/20","197.234.240.0/22","198.41.128.0/17","162.158.0.0/15","104.16.0.0/13","104.24.0.0/14","172.64.0.0/13","131.0.72.0/22"]' HELM_ARGS="$HELM_ARGS --set-json gitlab.webservice.workhorse.trustedCIDRsForXForwardedFor='${CLOUDFLARE_CIDRS}'" else # Apenas HTTP HELM_ARGS="$HELM_ARGS --set global.ingress.configureCertmanager=false" HELM_ARGS="$HELM_ARGS --set certmanager-issuer.install=false" HELM_ARGS="$HELM_ARGS --set global.ingress.tls.enabled=false" HELM_ARGS="$HELM_ARGS --set global.hosts.https=false" fi # Verificar se já está instalado if helm status gitlab -n gitlab &> /dev/null; then log_warn "GitLab já está instalado. Atualizando..." eval helm upgrade gitlab gitlab/gitlab \ --namespace gitlab \ -f "$SCRIPT_DIR/gitlab-values.yaml" \ $HELM_ARGS \ --timeout 15m \ --wait log_success "GitLab atualizado com sucesso!" else log_info "Instalando GitLab..." eval helm install gitlab gitlab/gitlab \ --namespace gitlab \ -f "$SCRIPT_DIR/gitlab-values.yaml" \ $HELM_ARGS \ --timeout 15m \ --wait log_success "GitLab instalado com sucesso!" fi echo "" # ============================================================================= # 9. CONFIGURAR TCP PASSTHROUGH PARA SSH # ============================================================================= log_info "=== Configurando TCP passthrough para SSH ===" # Verificar se ConfigMap existe if kubectl get configmap tcp-services -n ingress-nginx &> /dev/null; then kubectl patch configmap tcp-services \ -n ingress-nginx \ --type merge \ -p '{"data":{"22":"gitlab/gitlab-gitlab-shell:22"}}' else kubectl create configmap tcp-services \ -n ingress-nginx \ --from-literal="22=gitlab/gitlab-gitlab-shell:22" fi # Reiniciar NGINX para aplicar kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx log_success "TCP passthrough configurado (porta 22 → GitLab Shell)" echo "" # ============================================================================= # 10. OBTER SENHA INICIAL # ============================================================================= log_info "Obtendo senha inicial do root..." # Aguardar secret ser criado e obter senha (até 2 min) ROOT_PASSWORD="" for i in {1..60}; do ROOT_PASSWORD=$(kubectl get secret gitlab-gitlab-initial-root-password \ -n gitlab \ -o jsonpath='{.data.password}' 2>/dev/null | base64 -d 2>/dev/null) if [[ -n "$ROOT_PASSWORD" ]]; then log_success "Senha obtida" break fi sleep 2 done # ============================================================================= # RESUMO FINAL # ============================================================================= # Determinar protocolo PROTOCOL="https" if [[ "$USE_CLOUDFLARE" == "false" && "$USE_LETSENCRYPT" == "false" ]]; then PROTOCOL="http" fi echo "" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" echo -e "${GREEN} GitLab Instalado com Sucesso!${NC}" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" echo "" echo "Componentes instalados:" if [[ "$USE_LETSENCRYPT" == "true" ]]; then echo " - cert-manager (ClusterIssuer: letsencrypt)" fi echo " - GitLab (namespace: gitlab)" echo " - Webservice (UI + API)" echo " - Sidekiq (background jobs)" echo " - Gitaly (Git storage)" echo " - GitLab Shell (SSH)" echo " - PostgreSQL" echo " - Redis" echo " - Hetzner Object Storage (S3)" echo " - Container Registry" echo "" # Determinar tipo de TLS para exibição if [[ "$USE_LETSENCRYPT" == "true" ]]; then TLS_TYPE="Let's Encrypt" elif [[ "$USE_CLOUDFLARE" == "true" ]]; then TLS_TYPE="CloudFlare" else TLS_TYPE="Sem TLS (HTTP)" fi echo "Configuração:" echo " GitLab: ${GITLAB_HOST}" echo " Registry: ${REGISTRY_HOST}" echo " Domínio: ${DOMAIN}" echo " TLS: ${TLS_TYPE}" echo "" echo "URLs:" echo " Web: ${PROTOCOL}://${GITLAB_HOST}" echo " Registry: ${PROTOCOL}://${REGISTRY_HOST}" echo " SSH: git@${GITLAB_HOST} (porta 22)" echo "" echo "Credenciais:" echo " Usuário: root" if [ -n "$ROOT_PASSWORD" ]; then echo " Senha: $ROOT_PASSWORD" else echo " Senha: (execute o comando abaixo)" echo "" echo " kubectl get secret gitlab-gitlab-initial-root-password -n gitlab \\" echo " -o jsonpath='{.data.password}' | base64 -d; echo" fi # Lembrete de DNS (referência) echo "" echo -e "${CYAN}Lembrete DNS:${NC}" echo " ${GITLAB_HOST} → LoadBalancer IP" echo " ${REGISTRY_HOST} → LoadBalancer IP" echo "" echo "Comandos úteis:" echo " # Ver pods" echo " kubectl get pods -n gitlab" echo "" echo " # Ver logs" echo " kubectl logs -n gitlab -l app=webservice -f" echo "" echo " # Reiniciar componente" echo " kubectl rollout restart deployment -n gitlab gitlab-webservice-default" echo "" if [[ "$USE_LETSENCRYPT" == "true" ]]; then echo " # Ver status dos certificados" echo " kubectl get certificate -n gitlab" echo "" fi echo " # Desinstalar" echo " ./cleanup.sh" echo "" echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" echo "" # Mostrar status dos pods log_info "Status dos pods:" kubectl get pods -n gitlab