Initial Django project setup for Postgres cluster management - Created Django project structure with postgres_handholder main app - Added clusters, backups, and monitoring apps - Implemented comprehensive models for PostgresCluster, PostgresInstance, ClusterUser, ClusterDatabase - Added forms and views for cluster management - Created Bootstrap 5 templates with modern UI - Added Docker and Docker Compose configuration - Included Celery for background tasks - Added comprehensive requirements.txt with all dependencies - Updated README with installation and usage instructions - Added environment configuration example - Set up proper URL routing and app structure

This commit is contained in:
2025-06-18 06:24:56 +02:00
parent b1d9ec8ec0
commit a856fb73f7
26 changed files with 1577 additions and 1 deletions

261
clusters/views.py Normal file
View File

@ -0,0 +1,261 @@
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.core.paginator import Paginator
from .models import PostgresCluster, PostgresInstance, ClusterUser, ClusterDatabase
from .forms import PostgresClusterForm, ClusterUserForm, ClusterDatabaseForm
@login_required
def cluster_list(request):
"""Display list of all clusters."""
clusters = PostgresCluster.objects.filter(created_by=request.user)
# Filtering
status_filter = request.GET.get('status')
if status_filter:
clusters = clusters.filter(status=status_filter)
# Pagination
paginator = Paginator(clusters, 10)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
context = {
'page_obj': page_obj,
'status_choices': PostgresCluster._meta.get_field('status').choices,
}
return render(request, 'clusters/cluster_list.html', context)
@login_required
def cluster_create(request):
"""Create a new Postgres cluster."""
if request.method == 'POST':
form = PostgresClusterForm(request.POST)
if form.is_valid():
cluster = form.save(commit=False)
cluster.created_by = request.user
cluster.save()
messages.success(request, f'Cluster "{cluster.name}" created successfully.')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
else:
form = PostgresClusterForm()
context = {
'form': form,
'title': 'Create New Cluster',
}
return render(request, 'clusters/cluster_form.html', context)
@login_required
def cluster_detail(request, cluster_id):
"""Display detailed information about a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
context = {
'cluster': cluster,
'instances': cluster.instances.all(),
'users': cluster.users.all(),
'databases': cluster.databases.all(),
}
return render(request, 'clusters/cluster_detail.html', context)
@login_required
def cluster_edit(request, cluster_id):
"""Edit an existing cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
if request.method == 'POST':
form = PostgresClusterForm(request.POST, instance=cluster)
if form.is_valid():
form.save()
messages.success(request, f'Cluster "{cluster.name}" updated successfully.')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
else:
form = PostgresClusterForm(instance=cluster)
context = {
'form': form,
'cluster': cluster,
'title': f'Edit Cluster: {cluster.name}',
}
return render(request, 'clusters/cluster_form.html', context)
@login_required
def cluster_delete(request, cluster_id):
"""Delete a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
if request.method == 'POST':
cluster_name = cluster.name
cluster.delete()
messages.success(request, f'Cluster "{cluster_name}" deleted successfully.')
return redirect('clusters:cluster_list')
context = {
'cluster': cluster,
}
return render(request, 'clusters/cluster_confirm_delete.html', context)
@login_required
@require_http_methods(["POST"])
def cluster_start(request, cluster_id):
"""Start a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
try:
# TODO: Implement actual cluster start logic
cluster.status = 'starting'
cluster.save()
messages.success(request, f'Starting cluster "{cluster.name}"...')
except Exception as e:
messages.error(request, f'Failed to start cluster: {str(e)}')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
@login_required
@require_http_methods(["POST"])
def cluster_stop(request, cluster_id):
"""Stop a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
try:
# TODO: Implement actual cluster stop logic
cluster.status = 'stopping'
cluster.save()
messages.success(request, f'Stopping cluster "{cluster.name}"...')
except Exception as e:
messages.error(request, f'Failed to stop cluster: {str(e)}')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
@login_required
@require_http_methods(["POST"])
def cluster_restart(request, cluster_id):
"""Restart a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
try:
# TODO: Implement actual cluster restart logic
cluster.status = 'starting'
cluster.save()
messages.success(request, f'Restarting cluster "{cluster.name}"...')
except Exception as e:
messages.error(request, f'Failed to restart cluster: {str(e)}')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
@login_required
@require_http_methods(["POST"])
def cluster_update(request, cluster_id):
"""Update a cluster (rolling update)."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
try:
# TODO: Implement actual rolling update logic
cluster.status = 'updating'
cluster.save()
messages.success(request, f'Updating cluster "{cluster.name}"...')
except Exception as e:
messages.error(request, f'Failed to update cluster: {str(e)}')
return redirect('clusters:cluster_detail', cluster_id=cluster.id)
@login_required
def cluster_users(request, cluster_id):
"""Manage users for a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
if request.method == 'POST':
form = ClusterUserForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.cluster = cluster
user.created_by = request.user
user.save()
messages.success(request, f'User "{user.username}" created successfully.')
return redirect('clusters:cluster_users', cluster_id=cluster.id)
else:
form = ClusterUserForm()
context = {
'cluster': cluster,
'form': form,
'users': cluster.users.all(),
}
return render(request, 'clusters/cluster_users.html', context)
@login_required
def cluster_databases(request, cluster_id):
"""Manage databases for a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
if request.method == 'POST':
form = ClusterDatabaseForm(request.POST)
if form.is_valid():
database = form.save(commit=False)
database.cluster = cluster
database.save()
messages.success(request, f'Database "{database.name}" created successfully.')
return redirect('clusters:cluster_databases', cluster_id=cluster.id)
else:
form = ClusterDatabaseForm()
context = {
'cluster': cluster,
'form': form,
'databases': cluster.databases.all(),
}
return render(request, 'clusters/cluster_databases.html', context)
@login_required
def cluster_instances(request, cluster_id):
"""View instances for a cluster."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
context = {
'cluster': cluster,
'instances': cluster.instances.all(),
}
return render(request, 'clusters/cluster_instances.html', context)
@login_required
def cluster_status_api(request, cluster_id):
"""API endpoint to get cluster status."""
cluster = get_object_or_404(PostgresCluster, id=cluster_id, created_by=request.user)
data = {
'id': cluster.id,
'name': cluster.name,
'status': cluster.status,
'instances': [
{
'id': instance.id,
'name': instance.name,
'type': instance.instance_type,
'status': instance.status,
'host': instance.host,
'port': instance.port,
'cpu_usage': instance.cpu_usage,
'memory_usage': instance.memory_usage,
'disk_usage': instance.disk_usage,
}
for instance in cluster.instances.all()
]
}
return JsonResponse(data)