Merge branch 'master' into bugfix/send_email_on_dg_subscription

This commit is contained in:
PCoder 2018-08-24 08:42:25 +02:00
commit 83a6e53fae
10 changed files with 113 additions and 18 deletions

View file

@ -1,3 +1,9 @@
Next:
* #5458: [admin] Make hostingorder more readable (PR #657)
* bugfix: [CMS templates] Set description meta field of ungleich template (was missing before) and set ungleich glarus ag uniformly as author of various CMS pages (PR #653)
* #5473: Ping a VM before saving ssh key of the user (PR #655)
2.1: 2018-08-21
* Bugfix: Increase CC brand name fields from 10 to 128 characters (PR #654)
2.0.5: 2018-08-08 2.0.5: 2018-08-08
* Fix IPv6 VM name in the billing invoice * Fix IPv6 VM name in the billing invoice
2.0.4: 2018-08-07 2.0.4: 2018-08-07

View file

@ -8,13 +8,16 @@ from django.core.mail import EmailMessage
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils import translation from django.utils import translation
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from time import sleep
from dynamicweb.celery import app from dynamicweb.celery import app
from hosting.models import HostingOrder from hosting.models import HostingOrder
from membership.models import CustomUser from membership.models import CustomUser
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineSerializer from opennebula_api.serializers import VirtualMachineSerializer
from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail from utils.hosting_utils import (
get_all_public_keys, get_or_create_vm_detail, ping_ok
)
from utils.mailer import BaseEmail from utils.mailer import BaseEmail
from utils.stripe_utils import StripeUtils from utils.stripe_utils import StripeUtils
from .models import VMPricing from .models import VMPricing
@ -203,12 +206,45 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
host=vm_ipv6, num_keys=len(keys) host=vm_ipv6, num_keys=len(keys)
) )
) )
# Let's delay the task by 75 seconds to be sure # Let's wait until the IP responds to ping before we
# that we run the cdist configure after the host # run the cdist configure on the host
# is up did_manage_public_key = False
manager.manage_public_key( for i in range(0, 15):
keys, hosts=[vm_ipv6], countdown=75 if ping_ok(vm_ipv6):
logger.debug(
"{} is pingable. Doing a "
"manage_public_key".format(vm_ipv6)
) )
sleep(10)
manager.manage_public_key(
keys, hosts=[vm_ipv6]
)
did_manage_public_key = True
break
else:
logger.debug(
"Can't ping {}. Wait 5 secs".format(
vm_ipv6
)
)
sleep(5)
if not did_manage_public_key:
emsg = ("Waited for over 75 seconds for {} to be "
"pingable. But the VM was not reachable. "
"So, gave up manage_public_key. Please do "
"this manually".format(vm_ipv6))
logger.error(emsg)
email_data = {
'subject': '{} CELERY TASK INCOMPLETE: {} not '
'pingable for 75 seconds'.format(
settings.DCL_TEXT, vm_ipv6
),
'from_email': current_task.request.hostname,
'to': settings.DCL_ERROR_EMAILS_TO_LIST,
'body': emsg
}
email = EmailMessage(**email_data)
email.send()
except Exception as e: except Exception as e:
logger.error(str(e)) logger.error(str(e))
try: try:

View file

@ -8,8 +8,8 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{% page_attribute 'meta_description' %}">
<meta name="author" content="ungleich glarus ag"> <meta name="author" content="ungleich glarus ag">
<meta name="description" content="{% page_attribute 'meta_description' %}">
<title>{% page_attribute "page_title" %}</title> <title>{% page_attribute "page_title" %}</title>
<!-- Vendor CSS --> <!-- Vendor CSS -->

View file

@ -1,3 +1,4 @@
import logging
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from datacenterlight.tasks import create_vm_task from datacenterlight.tasks import create_vm_task
@ -8,6 +9,8 @@ from utils.models import BillingAddress
from .cms_models import CMSIntegration from .cms_models import CMSIntegration
from .models import VMPricing, VMTemplate from .models import VMPricing, VMTemplate
logger = logging.getLogger(__name__)
def get_cms_integration(name): def get_cms_integration(name):
current_site = Site.objects.get_current() current_site = Site.objects.get_current()

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-08-21 12:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hosting', '0046_usercarddetail'),
]
operations = [
migrations.AlterField(
model_name='hostingorder',
name='cc_brand',
field=models.CharField(max_length=128),
),
migrations.AlterField(
model_name='usercarddetail',
name='brand',
field=models.CharField(max_length=128),
),
]

View file

@ -53,10 +53,12 @@ class OrderDetail(AssignPermissionsMixin, models.Model):
ssd_size = models.IntegerField(default=0) ssd_size = models.IntegerField(default=0)
def __str__(self): def __str__(self):
return "%s - %s, %s cores, %s GB RAM, %s GB SSD" % ( return "Not available" if self.vm_template is None else (
"%s - %s, %s cores, %s GB RAM, %s GB SSD" % (
self.vm_template.name, self.vm_template.vm_type, self.cores, self.vm_template.name, self.vm_template.vm_type, self.cores,
self.memory, self.ssd_size self.memory, self.ssd_size
) )
)
class HostingOrder(AssignPermissionsMixin, models.Model): class HostingOrder(AssignPermissionsMixin, models.Model):
@ -69,7 +71,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False) approved = models.BooleanField(default=False)
last4 = models.CharField(max_length=4) last4 = models.CharField(max_length=4)
cc_brand = models.CharField(max_length=10) cc_brand = models.CharField(max_length=128)
stripe_charge_id = models.CharField(max_length=100, null=True) stripe_charge_id = models.CharField(max_length=100, null=True)
price = models.FloatField() price = models.FloatField()
subscription_id = models.CharField(max_length=100, null=True) subscription_id = models.CharField(max_length=100, null=True)
@ -87,7 +89,11 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
) )
def __str__(self): def __str__(self):
return "%s" % (self.id) return ("Order Nr: #{} - VM_ID: {} - {} - {} - "
"Specs: {} - Price: {}").format(
self.id, self.vm_id, self.customer.user.email, self.created_at,
self.order_detail, self.price
)
@cached_property @cached_property
def status(self): def status(self):
@ -212,7 +218,7 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
permissions = ('view_usercarddetail',) permissions = ('view_usercarddetail',)
stripe_customer = models.ForeignKey(StripeCustomer) stripe_customer = models.ForeignKey(StripeCustomer)
last4 = models.CharField(max_length=4) last4 = models.CharField(max_length=4)
brand = models.CharField(max_length=10) brand = models.CharField(max_length=128)
card_id = models.CharField(max_length=100, blank=True, default='') card_id = models.CharField(max_length=100, blank=True, default='')
fingerprint = models.CharField(max_length=100) fingerprint = models.CharField(max_length=100)
exp_month = models.IntegerField(null=False) exp_month = models.IntegerField(null=False)

View file

@ -9,7 +9,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""> <meta name="description" content="">
<meta name="author" content=""> <meta name="author" content="ungleich glarus ag">
<title>{{ domain }} - {{ hosting }} hosting as easy as possible</title> <title>{{ domain }} - {{ hosting }} hosting as easy as possible</title>

View file

@ -7,7 +7,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="ungleich GmbH"> <meta name="author" content="ungleich glarus ag">
<meta name="description" content="{% page_attribute 'meta_description' %}"> <meta name="description" content="{% page_attribute 'meta_description' %}">
<title>{% page_attribute "page_title" %}</title> <title>{% page_attribute "page_title" %}</title>

View file

@ -7,8 +7,9 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""> <meta name="author" content="ungleich glarus ag">
<meta name="author" content=""> <meta name="description" content="{% page_attribute 'meta_description' %}">
<title>{% page_attribute "page_title" %}</title> <title>{% page_attribute "page_title" %}</title>

View file

@ -1,5 +1,6 @@
import decimal import decimal
import logging import logging
import subprocess
from oca.pool import WrongIdError from oca.pool import WrongIdError
from datacenterlight.models import VMPricing from datacenterlight.models import VMPricing
@ -130,6 +131,23 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0,
return float(price), float(vat), float(vat_percent), discount return float(price), float(vat), float(vat_percent), discount
def ping_ok(host_ipv6):
"""
A utility method to check if a host responds to ping requests. Note: the
function relies on `ping6` utility of debian to check.
:param host_ipv6 str type parameter that represets the ipv6 of the host to
checked
:return True if the host responds to ping else returns False
"""
try:
subprocess.check_output("ping6 -c 1 " + host_ipv6, shell=True)
except Exception as ex:
logger.debug(host_ipv6 + " not reachable via ping. Error = " + str(ex))
return False
return True
class HostingUtils: class HostingUtils:
@staticmethod @staticmethod
def clear_items_from_list(from_list, items_list): def clear_items_from_list(from_list, items_list):