from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib.auth import login, logout from django.contrib.auth.forms import AuthenticationForm from django.contrib import messages from django.http import JsonResponse from .models import RegistryConfig from .forms import RegistryConfigForm from .registry_client import RegistryClient def login_view(request): if request.user.is_authenticated: return redirect('dashboard') if request.method == 'POST': form = AuthenticationForm(request, data=request.POST) if form.is_valid(): user = form.get_user() login(request, user) messages.success(request, f'Bienvenido {user.username}') return redirect('dashboard') else: form = AuthenticationForm() return render(request, 'explorer/login.html', {'form': form}) def logout_view(request): logout(request) messages.info(request, 'Sesión cerrada') return redirect('login') @login_required def dashboard(request): registries = RegistryConfig.objects.all() return render(request, 'explorer/dashboard.html', {'registries': registries}) @login_required def registry_create(request): if request.method == 'POST': form = RegistryConfigForm(request.POST) if form.is_valid(): config = form.save(commit=False) client = RegistryClient( url=config.url, username=config.username, password=config.password, verify_ssl=config.verify_ssl ) ok, msg = client.check_connection() if ok: config.save() messages.success(request, f'Registry "{config.name}" configurado correctamente') return redirect('dashboard') else: messages.error(request, f'No se pudo conectar: {msg}') else: form = RegistryConfigForm() return render(request, 'explorer/registry_form.html', {'form': form, 'title': 'Agregar Registry'}) @login_required def registry_edit(request, pk): config = get_object_or_404(RegistryConfig, pk=pk) if request.method == 'POST': form = RegistryConfigForm(request.POST, instance=config) if form.is_valid(): form.save() messages.success(request, f'Registry "{config.name}" actualizado') return redirect('dashboard') else: form = RegistryConfigForm(instance=config) return render(request, 'explorer/registry_form.html', {'form': form, 'title': 'Editar Registry'}) @login_required def registry_delete(request, pk): config = get_object_or_404(RegistryConfig, pk=pk) if request.method == 'POST': name = config.name config.delete() messages.success(request, f'Registry "{name}" eliminado') return redirect('dashboard') return render(request, 'explorer/registry_confirm_delete.html', {'config': config}) @login_required def registry_repositories(request, pk): config = get_object_or_404(RegistryConfig, pk=pk) client = RegistryClient( url=config.url, username=config.username, password=config.password, verify_ssl=config.verify_ssl ) ok, msg = client.check_connection() if not ok: messages.error(request, f'Error de conexión: {msg}') return redirect('dashboard') try: repositories = client.list_catalog() except Exception as e: messages.error(request, f'Error al listar repositorios: {str(e)}') repositories = [] search = request.GET.get('search', '').strip() if search: repositories = [r for r in repositories if search.lower() in r.lower()] return render(request, 'explorer/repositories.html', { 'config': config, 'repositories': repositories, 'search': search, 'count': len(repositories), }) @login_required def repository_tags(request, pk, repo_name): config = get_object_or_404(RegistryConfig, pk=pk) client = RegistryClient( url=config.url, username=config.username, password=config.password, verify_ssl=config.verify_ssl ) try: tags = client.list_tags(repo_name) except Exception as e: messages.error(request, f'Error al listar tags: {str(e)}') tags = [] search = request.GET.get('search', '').strip() if search: tags = [t for t in tags if search.lower() in t.lower()] return render(request, 'explorer/tags.html', { 'config': config, 'repo_name': repo_name, 'tags': tags, 'search': search, 'count': len(tags), }) @login_required def image_detail(request, pk, repo_name, tag): config = get_object_or_404(RegistryConfig, pk=pk) client = RegistryClient( url=config.url, username=config.username, password=config.password, verify_ssl=config.verify_ssl ) try: detail = client.get_image_detail(repo_name, tag) except Exception as e: messages.error(request, f'Error al obtener detalles: {str(e)}') return redirect('repository_tags', pk=pk, repo_name=repo_name) return render(request, 'explorer/image_detail.html', { 'config': config, 'repo_name': repo_name, 'tag': tag, 'detail': detail, }) @login_required def image_delete(request, pk, repo_name, tag): config = get_object_or_404(RegistryConfig, pk=pk) if request.method != 'POST': return redirect('image_detail', pk=pk, repo_name=repo_name, tag=tag) client = RegistryClient( url=config.url, username=config.username, password=config.password, verify_ssl=config.verify_ssl ) ok, msg = client.delete_manifest(repo_name, tag) if ok: messages.success(request, msg) else: messages.error(request, msg) return redirect('repository_tags', pk=pk, repo_name=repo_name) @login_required def api_check_connection(request): if request.method != 'POST': return JsonResponse({'error': 'Método no permitido'}, status=405) url = request.POST.get('url', '') username = request.POST.get('username', '') password = request.POST.get('password', '') verify_ssl = request.POST.get('verify_ssl', 'on') == 'on' if not url: return JsonResponse({'ok': False, 'message': 'URL requerida'}) client = RegistryClient(url=url, username=username, password=password, verify_ssl=verify_ssl) ok, msg = client.check_connection() return JsonResponse({'ok': ok, 'message': msg})