Merge master into 5151/gdpr_modal
This commit is contained in:
commit
e230f2ac8c
14 changed files with 133 additions and 22 deletions
13
Changelog
13
Changelog
|
@ -1,6 +1,17 @@
|
|||
Next:
|
||||
* 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
|
||||
* Fix IPv6 VM name in the billing invoice
|
||||
2.0.4: 2018-08-07
|
||||
* Add RSS feed link to the footer of the blog template (PR #651)
|
||||
* #5308: [ipv6only] Fix - when creating a VM, the name begins with v6only (PR #649)
|
||||
* #5293: Use `terminate-hard` action instead of `terminate` in the opennebula call to terminate a vm (PR #650)
|
||||
2.0.3: 2018-07-18
|
||||
* Remove unused /comic url (PR #644)
|
||||
* 5126: Allow dynamicweb sites to be iframed on other by setting `X_FRAME_OPTIONS_ALLOW_FROM_URI` (PR #645)
|
||||
* #5126: Allow dynamicweb sites to be iframed on other by setting `X_FRAME_OPTIONS_ALLOW_FROM_URI` (PR #645)
|
||||
2.0.2: 2018-07-14
|
||||
* bugfix: [blog] Add missing content block in the blog_ungleich.html template file
|
||||
2.0.1: 2018-07-14
|
||||
|
|
|
@ -8,13 +8,16 @@ from django.core.mail import EmailMessage
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.utils import translation
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from time import sleep
|
||||
|
||||
from dynamicweb.celery import app
|
||||
from hosting.models import HostingOrder
|
||||
from membership.models import CustomUser
|
||||
from opennebula_api.models import OpenNebulaManager
|
||||
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.stripe_utils import StripeUtils
|
||||
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)
|
||||
)
|
||||
)
|
||||
# Let's delay the task by 75 seconds to be sure
|
||||
# that we run the cdist configure after the host
|
||||
# is up
|
||||
manager.manage_public_key(
|
||||
keys, hosts=[vm_ipv6], countdown=75
|
||||
)
|
||||
# Let's wait until the IP responds to ping before we
|
||||
# run the cdist configure on the host
|
||||
did_manage_public_key = False
|
||||
for i in range(0, 15):
|
||||
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:
|
||||
logger.error(str(e))
|
||||
try:
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<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="description" content="{% page_attribute 'meta_description' %}">
|
||||
<title>{% page_attribute "page_title" %}</title>
|
||||
|
||||
<!-- Vendor CSS -->
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
from datacenterlight.tasks import create_vm_task
|
||||
|
@ -8,6 +9,8 @@ from utils.models import BillingAddress
|
|||
from .cms_models import CMSIntegration
|
||||
from .models import VMPricing, VMTemplate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_cms_integration(name):
|
||||
current_site = Site.objects.get_current()
|
||||
|
|
|
@ -179,9 +179,7 @@ ROOT_URLCONF = 'dynamicweb.urls'
|
|||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(PROJECT_DIR, 'cms_templates/'),
|
||||
os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
|
||||
os.path.join(PROJECT_DIR, 'membership'),
|
||||
'DIRS': [os.path.join(PROJECT_DIR, 'membership'),
|
||||
os.path.join(PROJECT_DIR, 'hosting/templates/'),
|
||||
os.path.join(PROJECT_DIR, 'nosystemd/templates/'),
|
||||
os.path.join(PROJECT_DIR,
|
||||
|
@ -192,6 +190,8 @@ TEMPLATES = [
|
|||
os.path.join(PROJECT_DIR,
|
||||
'ungleich_page/templates/ungleich_page'),
|
||||
os.path.join(PROJECT_DIR, 'templates/analytics'),
|
||||
os.path.join(PROJECT_DIR, 'cms_templates/'),
|
||||
os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
|
||||
os.path.join(PROJECT_DIR, 'templates/gdpr'),
|
||||
],
|
||||
'APP_DIRS': True,
|
||||
|
|
25
hosting/migrations/0047_auto_20180821_1240.py
Normal file
25
hosting/migrations/0047_auto_20180821_1240.py
Normal 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),
|
||||
),
|
||||
]
|
|
@ -69,7 +69,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
|
|||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
approved = models.BooleanField(default=False)
|
||||
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)
|
||||
price = models.FloatField()
|
||||
subscription_id = models.CharField(max_length=100, null=True)
|
||||
|
@ -212,7 +212,7 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
|
|||
permissions = ('view_usercarddetail',)
|
||||
stripe_customer = models.ForeignKey(StripeCustomer)
|
||||
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='')
|
||||
fingerprint = models.CharField(max_length=100)
|
||||
exp_month = models.IntegerField(null=False)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<meta name="author" content="ungleich glarus ag">
|
||||
|
||||
<title>{{ domain }} - {{ hosting }} hosting as easy as possible</title>
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ class OpenNebulaManager():
|
|||
return vm_id
|
||||
|
||||
def delete_vm(self, vm_id):
|
||||
TERMINATE_ACTION = 'terminate'
|
||||
TERMINATE_ACTION = 'terminate-hard'
|
||||
vm_terminated = False
|
||||
try:
|
||||
self.oneadmin_client.call(
|
||||
|
|
|
@ -36,7 +36,10 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
|
|||
return int(obj.template.memory) / 1024
|
||||
|
||||
def get_name(self, obj):
|
||||
return obj.name.lstrip('public-')
|
||||
if obj.name.startswith('public-'):
|
||||
return obj.name.lstrip('public-')
|
||||
else:
|
||||
return obj.name
|
||||
|
||||
|
||||
class VirtualMachineSerializer(serializers.Serializer):
|
||||
|
@ -133,7 +136,10 @@ class VirtualMachineSerializer(serializers.Serializer):
|
|||
def get_configuration(self, obj):
|
||||
template_id = obj.template.template_id
|
||||
template = OpenNebulaManager().get_template(template_id)
|
||||
return template.name.lstrip('public-')
|
||||
if template.name.startswith('public-'):
|
||||
return template.name.lstrip('public-')
|
||||
else:
|
||||
return template.name
|
||||
|
||||
def get_ipv4(self, obj):
|
||||
"""
|
||||
|
@ -162,7 +168,10 @@ class VirtualMachineSerializer(serializers.Serializer):
|
|||
return '-'
|
||||
|
||||
def get_name(self, obj):
|
||||
return obj.name.lstrip('public-')
|
||||
if obj.name.startswith('public-'):
|
||||
return obj.name.lstrip('public-')
|
||||
else:
|
||||
return obj.name
|
||||
|
||||
|
||||
class VMTemplateSerializer(serializers.Serializer):
|
||||
|
|
|
@ -30,6 +30,14 @@
|
|||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'djangocms_blog:posts-latest-feed' %}">
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-circle fa-stack-2x"></i>
|
||||
<i class="fa fa-rss fa-stack-1x fa-inverse"></i>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="copyright">
|
||||
Copyright © ungleich GmbH {% now "Y" %}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<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' %}">
|
||||
<title>{% page_attribute "page_title" %}</title>
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<meta name="author" content="ungleich glarus ag">
|
||||
<meta name="description" content="{% page_attribute 'meta_description' %}">
|
||||
|
||||
|
||||
<title>{% page_attribute "page_title" %}</title>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import decimal
|
||||
import logging
|
||||
import subprocess
|
||||
from oca.pool import WrongIdError
|
||||
|
||||
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
|
||||
|
||||
|
||||
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:
|
||||
@staticmethod
|
||||
def clear_items_from_list(from_list, items_list):
|
||||
|
|
Loading…
Reference in a new issue