Merge pull request #511 from pcoder/task/3774/update_stripe_subscription_on_vm_delete
Task/3774/update stripe subscription on vm delete
This commit is contained in:
		
				commit
				
					
						bbd02687c9
					
				
			
		
					 2 changed files with 77 additions and 14 deletions
				
			
		| 
						 | 
					@ -41,6 +41,7 @@ from utils.forms import (
 | 
				
			||||||
from utils.hosting_utils import get_vm_price
 | 
					from utils.hosting_utils import get_vm_price
 | 
				
			||||||
from utils.mailer import BaseEmail
 | 
					from utils.mailer import BaseEmail
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
 | 
					from utils.tasks import send_plain_email_task
 | 
				
			||||||
from utils.views import (
 | 
					from utils.views import (
 | 
				
			||||||
    PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,
 | 
					    PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,
 | 
				
			||||||
    ResendActivationLinkViewMixin
 | 
					    ResendActivationLinkViewMixin
 | 
				
			||||||
| 
						 | 
					@ -1034,7 +1035,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
                           )
 | 
					                           )
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        except Exception as error:
 | 
					        except Exception as error:
 | 
				
			||||||
            print(error)
 | 
					            logger.error(str(error))
 | 
				
			||||||
            raise Http404()
 | 
					            raise Http404()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_success_url(self):
 | 
					    def get_success_url(self):
 | 
				
			||||||
| 
						 | 
					@ -1077,49 +1078,88 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, request, *args, **kwargs):
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
        response = {'status': False}
 | 
					        response = {'status': False}
 | 
				
			||||||
 | 
					        admin_email_body = {}
 | 
				
			||||||
        owner = self.request.user
 | 
					        owner = self.request.user
 | 
				
			||||||
        vm = self.get_object()
 | 
					        vm = self.get_object()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        opennebula_vm_id = self.kwargs.get('pk')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        manager = OpenNebulaManager(
 | 
					        manager = OpenNebulaManager(
 | 
				
			||||||
            email=owner.email,
 | 
					            email=owner.email,
 | 
				
			||||||
            password=owner.password
 | 
					            password=owner.password
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data
 | 
					            vm_data = VirtualMachineSerializer(manager.get_vm(vm.id)).data
 | 
				
			||||||
            vm_name = vm_data.get('name')
 | 
					            vm_name = vm_data.get('name')
 | 
				
			||||||
        except WrongIdError:
 | 
					        except WrongIdError as wrong_id_err:
 | 
				
			||||||
 | 
					            logger.error(str(wrong_id_err))
 | 
				
			||||||
            return redirect(reverse('hosting:virtual_machines'))
 | 
					            return redirect(reverse('hosting:virtual_machines'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Cancel Stripe subscription
 | 
				
			||||||
 | 
					        stripe_utils = StripeUtils()
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            hosting_order = HostingOrder.objects.get(
 | 
				
			||||||
 | 
					                vm_id=vm.id
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            result = stripe_utils.unsubscribe_customer(
 | 
				
			||||||
 | 
					                subscription_id=hosting_order.subscription_id
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            stripe_subscription_obj = result.get('response_object')
 | 
				
			||||||
 | 
					            # Check if the subscription was canceled
 | 
				
			||||||
 | 
					            if (stripe_subscription_obj is None or
 | 
				
			||||||
 | 
					                    stripe_subscription_obj.status != 'canceled'):
 | 
				
			||||||
 | 
					                error_msg = result.get('error')
 | 
				
			||||||
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Error canceling subscription for {user} and vm id '
 | 
				
			||||||
 | 
					                    '{vm_id}'.format(user=owner.email, vm_id=vm.id)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                logger.error(error_msg)
 | 
				
			||||||
 | 
					                admin_email_body['stripe_error_msg'] = error_msg
 | 
				
			||||||
 | 
					        except HostingOrder.DoesNotExist:
 | 
				
			||||||
 | 
					            error_msg = (
 | 
				
			||||||
 | 
					                "HostingOrder corresponding to vm_id={vm_id} does"
 | 
				
			||||||
 | 
					                "not exist. Hence, can not find subscription to "
 | 
				
			||||||
 | 
					                "cancel ".format(vm_id=vm.id)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            logger.error(error_msg)
 | 
				
			||||||
 | 
					            admin_email_body['stripe_error_msg'] = error_msg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        terminated = manager.delete_vm(vm.id)
 | 
					        terminated = manager.delete_vm(vm.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not terminated:
 | 
					        if not terminated:
 | 
				
			||||||
            response['text'] = ugettext(
 | 
					            logger.debug(
 | 
				
			||||||
                'Error terminating VM') + opennebula_vm_id
 | 
					                "manager.delete_vm returned False. Hence, error making "
 | 
				
			||||||
 | 
					                "xml-rpc call to delete vm failed."
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            response['text'] = ugettext('Error terminating VM') + vm.id
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            for t in range(15):
 | 
					            for t in range(15):
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    manager.get_vm(opennebula_vm_id)
 | 
					                    manager.get_vm(vm.id)
 | 
				
			||||||
                except WrongIdError:
 | 
					                except WrongIdError:
 | 
				
			||||||
                    response['status'] = True
 | 
					                    response['status'] = True
 | 
				
			||||||
                    response['text'] = ugettext('Terminated')
 | 
					                    response['text'] = ugettext('Terminated')
 | 
				
			||||||
                    vm_detail_obj = VMDetail.objects.filter(
 | 
					                    vm_detail_obj = VMDetail.objects.filter(
 | 
				
			||||||
                        vm_id=opennebula_vm_id).first()
 | 
					                        vm_id=vm.id
 | 
				
			||||||
 | 
					                    ).first()
 | 
				
			||||||
                    vm_detail_obj.terminated_at = datetime.utcnow()
 | 
					                    vm_detail_obj.terminated_at = datetime.utcnow()
 | 
				
			||||||
                    vm_detail_obj.save()
 | 
					                    vm_detail_obj.save()
 | 
				
			||||||
                    break
 | 
					                except BaseException as base_exception:
 | 
				
			||||||
                except BaseException:
 | 
					                    logger.error(
 | 
				
			||||||
 | 
					                        "manager.get_vm({vm_id}) returned exception: "
 | 
				
			||||||
 | 
					                        "{details}.".format(
 | 
				
			||||||
 | 
					                            details=str(base_exception), vm_id=vm.id
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
                    break
 | 
					                    break
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    sleep(2)
 | 
					                    sleep(2)
 | 
				
			||||||
            context = {
 | 
					            context = {
 | 
				
			||||||
                'vm_name': vm_name,
 | 
					                'vm_name': vm_name,
 | 
				
			||||||
                'base_url': "{0}://{1}".format(self.request.scheme,
 | 
					                'base_url': "{0}://{1}".format(
 | 
				
			||||||
                                               self.request.get_host()),
 | 
					                    self.request.scheme, self.request.get_host()
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
                'page_header': _('Virtual Machine %(vm_name)s Cancelled') % {
 | 
					                'page_header': _('Virtual Machine %(vm_name)s Cancelled') % {
 | 
				
			||||||
                    'vm_name': vm_name}
 | 
					                    'vm_name': vm_name
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            email_data = {
 | 
					            email_data = {
 | 
				
			||||||
                'subject': context['page_header'],
 | 
					                'subject': context['page_header'],
 | 
				
			||||||
| 
						 | 
					@ -1131,6 +1171,18 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            email = BaseEmail(**email_data)
 | 
					            email = BaseEmail(**email_data)
 | 
				
			||||||
            email.send()
 | 
					            email.send()
 | 
				
			||||||
 | 
					        admin_email_body.update(response)
 | 
				
			||||||
 | 
					        email_to_admin_data = {
 | 
				
			||||||
 | 
					            'subject': "Deleted VM and Subscription for VM {vm_id} and "
 | 
				
			||||||
 | 
					                       "user: {user}".format(
 | 
				
			||||||
 | 
					                            vm_id=vm.id, user=owner.email
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					            'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
 | 
				
			||||||
 | 
					            'to': ['info@ungleich.ch'],
 | 
				
			||||||
 | 
					            'body': "\n".join(
 | 
				
			||||||
 | 
					                ["%s=%s" % (k, v) for (k, v) in admin_email_body.items()]),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        send_plain_email_task.delay(email_to_admin_data)
 | 
				
			||||||
        return HttpResponse(
 | 
					        return HttpResponse(
 | 
				
			||||||
            json.dumps(response),
 | 
					            json.dumps(response),
 | 
				
			||||||
            content_type="application/json"
 | 
					            content_type="application/json"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -232,6 +232,17 @@ class StripeUtils(object):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        return subscription_result
 | 
					        return subscription_result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @handleStripeError
 | 
				
			||||||
 | 
					    def unsubscribe_customer(self, subscription_id):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Cancels a given subscription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param subscription_id: The Stripe subscription id string
 | 
				
			||||||
 | 
					        :return:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        sub = stripe.Subscription.retrieve(subscription_id)
 | 
				
			||||||
 | 
					        return sub.delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @handleStripeError
 | 
					    @handleStripeError
 | 
				
			||||||
    def make_payment(self, customer, amount, token):
 | 
					    def make_payment(self, customer, amount, token):
 | 
				
			||||||
        charge = self.stripe.Charge.create(
 | 
					        charge = self.stripe.Charge.create(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue