Merge branch 'master' into task/3601/reduce_min_ram_to_1G
This commit is contained in:
commit
3a558c86a6
3 changed files with 79 additions and 14 deletions
|
@ -2,6 +2,8 @@ Next:
|
||||||
* #3911: [dcl] Integrate resend activation link into dcl landing payment page
|
* #3911: [dcl] Integrate resend activation link into dcl landing payment page
|
||||||
* #3972: [hosting] Add ungleich company info to invoice footer
|
* #3972: [hosting] Add ungleich company info to invoice footer
|
||||||
* #3974: [hosting] Improve invoice number: Show 404 for invoice resources that do not belong to the user
|
* #3974: [hosting] Improve invoice number: Show 404 for invoice resources that do not belong to the user
|
||||||
|
* [ungleich] Add video cover to the header on ungleich.ch landing page and add corresponding cms plugin
|
||||||
|
* #3774: [hosting] |Update Stripe subscription on vm delete
|
||||||
1.2.13: 2017-12-09
|
1.2.13: 2017-12-09
|
||||||
* [cms] Introduce UngleichHeaderBackgroundImageAndTextSliderPlugin that allows to have scrolling images and texts
|
* [cms] Introduce UngleichHeaderBackgroundImageAndTextSliderPlugin that allows to have scrolling images and texts
|
||||||
* [cms] Remove <p> tag for ungleich cms customer item template
|
* [cms] Remove <p> tag for ungleich cms customer item template
|
||||||
|
|
|
@ -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…
Reference in a new issue