Add connection error handling

This commit is contained in:
Modulos 2017-05-14 12:22:10 +02:00
parent d7bd142387
commit 1e2b8b1652
5 changed files with 106 additions and 29 deletions

View file

@ -5,9 +5,19 @@
<div class="container dashboard-container"> <div class="container dashboard-container">
<div class="row"> <div class="row">
<div class="col-md-8 col-md-offset-2"> <div class="col-md-8 col-md-offset-2">
<div class="col-md-12">
<br/>
{% if messages %}
<div class="alert alert-warning">
{% for message in messages %}
<span>{{ message }}</span>
{% endfor %}
</div>
{% endif %}
</div>
{% if not error %}
<h3><i class="fa fa-server" aria-hidden="true"></i> {% trans "New Virtual Machine"%} </h3> <h3><i class="fa fa-server" aria-hidden="true"></i> {% trans "New Virtual Machine"%} </h3>
<hr/> <hr/>
<form method="POST" action=""> <form method="POST" action="">
{% csrf_token %} {% csrf_token %}
<div class="form-group"> <div class="form-group">
@ -34,6 +44,7 @@
<button class="btn btn-success" >{% trans "Start VM"%} </button> <button class="btn btn-success" >{% trans "Start VM"%} </button>
</div> </div>
</form> </form>
{% endif %}
</div> </div>

View file

@ -7,10 +7,6 @@
<div class="col-md-8 col-md-offset-2" style="margin-top: 35px;"> <div class="col-md-8 col-md-offset-2" style="margin-top: 35px;">
<table class="table borderless table-hover"> <table class="table borderless table-hover">
<h3 class="pull-left"><i class="fa fa-server" aria-hidden="true"></i> {% trans "Virtual Machines"%} </h3> <h3 class="pull-left"><i class="fa fa-server" aria-hidden="true"></i> {% trans "Virtual Machines"%} </h3>
<p class="pull-right">
<a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>
</p>
<br/>
<div class="col-md-12"> <div class="col-md-12">
<br/> <br/>
{% if messages %} {% if messages %}
@ -21,6 +17,12 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
{% if not error %}
<p class="pull-right">
<a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>
</p>
<br/>
<thead> <thead>
<tr> <tr>
<th>{% trans "ID"%}</th> <th>{% trans "ID"%}</th>
@ -53,6 +55,7 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endif %}
{% if is_paginated %} {% if is_paginated %}
<div class="pagination"> <div class="pagination">

View file

@ -37,6 +37,8 @@ from opennebula_api.serializers import VirtualMachineSerializer,\
from oca.exceptions import OpenNebulaException from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError from oca.pool import WrongNameError
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
connection error. please try again in a few minutes."
class DjangoHostingView(ProcessVMSelectionMixin, View): class DjangoHostingView(ProcessVMSelectionMixin, View):
template_name = "hosting/django.html" template_name = "hosting/django.html"
@ -528,8 +530,13 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password) password=owner.password)
vm = manager.get_vm(obj.vm_id) try:
context['vm'] = VirtualMachineSerializer(vm).data vm = manager.get_vm(obj.vm_id)
context['vm'] = VirtualMachineSerializer(vm).data
except ConnectionRefusedError:
messages.error( request,
'In order to create a VM, you need to create/upload your SSH KEY first.'
)
return context return context
@ -564,9 +571,28 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
owner = self.request.user owner = self.request.user
manager = OpenNebulaManager(email=owner.email, manager = OpenNebulaManager(email=owner.email,
password=owner.password) password=owner.password)
queryset = manager.get_vms() try:
serializer = VirtualMachineSerializer(queryset, many=True) queryset = manager.get_vms()
return serializer.data serializer = VirtualMachineSerializer(queryset, many=True)
return serializer.data
except ConnectionRefusedError:
messages.error( self.request,
'We could not load your VMs due to a backend connection \
error. Please try again in a few minutes'
)
self.kwargs['error'] = 'connection'
return []
def get_context_data(self, **kwargs):
error = self.kwargs.get('error')
if error is not None:
print(error)
context = { 'error' : 'connection' }
else:
context = super(ListView, self).get_context_data(**kwargs)
return context
class CreateVirtualMachinesView(LoginRequiredMixin, View): class CreateVirtualMachinesView(LoginRequiredMixin, View):
@ -586,14 +612,24 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
) )
return HttpResponseRedirect(reverse('hosting:key_pair')) return HttpResponseRedirect(reverse('hosting:key_pair'))
manager = OpenNebulaManager() try:
templates = manager.get_templates() manager = OpenNebulaManager()
configuration_options = HostingPlan.get_serialized_configs() templates = manager.get_templates()
configuration_options = HostingPlan.get_serialized_configs()
context = {
'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
'configuration_options' : configuration_options,
}
except:
messages.error( request,
'We could not load the VM templates due to a backend connection \
error. Please try again in a few minutes'
)
context = {
'error' : 'connection'
}
context = {
'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
'configuration_options' : configuration_options,
}
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request): def post(self, request):
@ -622,10 +658,16 @@ class VirtualMachineView(LoginRequiredMixin, View):
vm_id = self.kwargs.get('pk') vm_id = self.kwargs.get('pk')
try: try:
vm = manager.get_vm(vm_id) vm = manager.get_vm(vm_id)
return vm
except ConnectionRefusedError:
messages.error( self.request,
'We could not load your VM due to a backend connection \
error. Please try again in a few minutes'
)
return None
except Exception as error: except Exception as error:
print(error) print(error)
raise Http404() raise Http404()
return vm
def get_success_url(self): def get_success_url(self):
final_url = reverse('hosting:virtual_machines') final_url = reverse('hosting:virtual_machines')
@ -633,10 +675,14 @@ class VirtualMachineView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
vm = self.get_object() vm = self.get_object()
serializer = VirtualMachineSerializer(vm) try:
context = { serializer = VirtualMachineSerializer(vm)
'virtual_machine': serializer.data, context = {
} 'virtual_machine': serializer.data,
}
except:
pass
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):

View file

@ -86,6 +86,7 @@ class OpenNebulaManager():
logger.info('Could not connect via client, using oneadmin instead') logger.info('Could not connect via client, using oneadmin instead')
vm_pool = oca.VirtualMachinePool(self.oneadmin_client) vm_pool = oca.VirtualMachinePool(self.oneadmin_client)
vm_pool.info(filter=-2) vm_pool.info(filter=-2)
return vm_pool
except ConnectionRefusedError: except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format( logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
@ -93,13 +94,16 @@ class OpenNebulaManager():
protocol=settings.OPENNEBULA_PROTOCOL) protocol=settings.OPENNEBULA_PROTOCOL)
) )
raise ConnectionRefusedError raise ConnectionRefusedError
return vm_pool # For now we'll just handle all other errors as connection errors
except:
raise ConnectionRefusedError
def get_vms(self): def get_vms(self):
try: try:
return self._get_vm_pool() return self._get_vm_pool()
except ConnectionRefusedError: except ConnectionRefusedError:
return [] raise ConnectionRefusedError
def get_vm(self, vm_id): def get_vm(self, vm_id):
vm_id = int(vm_id) vm_id = int(vm_id)
@ -107,7 +111,7 @@ class OpenNebulaManager():
vm_pool = self._get_vm_pool() vm_pool = self._get_vm_pool()
return vm_pool.get_by_id(vm_id) return vm_pool.get_by_id(vm_id)
except: except:
return None raise ConnectionRefusedError
def create_template(self, name, cores, memory, disk_size, core_price, memory_price, def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
disk_size_price, ssh='' ): disk_size_price, ssh='' ):
@ -233,13 +237,16 @@ class OpenNebulaManager():
try: try:
template_pool = oca.VmTemplatePool(self.oneadmin_client) template_pool = oca.VmTemplatePool(self.oneadmin_client)
template_pool.info() template_pool.info()
return template_pool
except ConnectionRefusedError: except ConnectionRefusedError:
logger.info('Could not connect to host: {host} via protocol {protocol}'.format( logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
host=settings.OPENNEBULA_DOMAIN, host=settings.OPENNEBULA_DOMAIN,
protocol=settings.OPENNEBULA_PROTOCOL) protocol=settings.OPENNEBULA_PROTOCOL)
) )
raise ConnectionRefusedError raise ConnectionRefusedError
return template_pool except:
raise ConnectionRefusedError
def get_templates(self): def get_templates(self):
try: try:
@ -250,6 +257,14 @@ class OpenNebulaManager():
] ]
return public_templates return public_templates
except ConnectionRefusedError: except ConnectionRefusedError:
raise ConnectionRefusedError
except:
raise ConnectionRefusedError
def try_get_templates(self):
try:
return self.get_templates()
except:
return [] return []
def get_template(self, template_id): def get_template(self, template_id):
@ -258,7 +273,7 @@ class OpenNebulaManager():
template_pool = self._get_template_pool() template_pool = self._get_template_pool()
return template_pool.get_by_id(template_id) return template_pool.get_by_id(template_id)
except: except:
return None raise ConnectionRefusedError

View file

@ -92,9 +92,11 @@ class VirtualMachineSerializer(serializers.Serializer):
template_id = serializers.ChoiceField( template_id = serializers.ChoiceField(
choices=[(key.id, key.name) for key in choices=[(key.id, key.name) for key in
OpenNebulaManager().get_templates()], OpenNebulaManager().try_get_templates()
],
source='template.template_id', source='template.template_id',
write_only=True write_only=True,
default=[]
) )
def create(self, validated_data): def create(self, validated_data):