Merge branch 'master' into bugfix/show_meta_description_in_cms_page

This commit is contained in:
PCoder 2018-08-22 21:42:37 +02:00
commit 9c5363ef55
13 changed files with 145 additions and 26 deletions

View file

@ -1,3 +1,20 @@
Next:
* 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)
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
* bugfix: [blog] Enable content/structure mode in blog page
2.0: 2018-07-07 2.0: 2018-07-07
* #3747: [dcl,hosting] Add multiple cards support (PR #530) * #3747: [dcl,hosting] Add multiple cards support (PR #530)
* #3934: [dcl,hosting] Create HostingOrder outside celery task and add and associate OrderDetail with HostingOrder (PR #624) * #3934: [dcl,hosting] Create HostingOrder outside celery task and add and associate OrderDetail with HostingOrder (PR #624)

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

@ -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

@ -2,16 +2,15 @@
Copyright 2015 ungleich. Copyright 2015 ungleich.
""" """
import json
import logging
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os import os
import json
from django.utils.translation import ugettext_lazy as _
# dotenv # dotenv
import dotenv import dotenv
import logging from django.utils.translation import ugettext_lazy as _
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -56,6 +55,7 @@ PROJECT_DIR = os.path.abspath(
dotenv.read_dotenv("{0}/.env".format(PROJECT_DIR)) dotenv.read_dotenv("{0}/.env".format(PROJECT_DIR))
from multisite import SiteID from multisite import SiteID
SITE_ID = SiteID(default=1) SITE_ID = SiteID(default=1)
APP_ROOT_ENDPOINT = "/" APP_ROOT_ENDPOINT = "/"
@ -179,9 +179,7 @@ ROOT_URLCONF = 'dynamicweb.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(PROJECT_DIR, 'cms_templates/'), 'DIRS': [os.path.join(PROJECT_DIR, 'membership'),
os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
os.path.join(PROJECT_DIR, 'membership'),
os.path.join(PROJECT_DIR, 'hosting/templates/'), os.path.join(PROJECT_DIR, 'hosting/templates/'),
os.path.join(PROJECT_DIR, 'nosystemd/templates/'), os.path.join(PROJECT_DIR, 'nosystemd/templates/'),
os.path.join(PROJECT_DIR, os.path.join(PROJECT_DIR,
@ -192,6 +190,8 @@ TEMPLATES = [
os.path.join(PROJECT_DIR, os.path.join(PROJECT_DIR,
'ungleich_page/templates/ungleich_page'), 'ungleich_page/templates/ungleich_page'),
os.path.join(PROJECT_DIR, 'templates/analytics'), os.path.join(PROJECT_DIR, 'templates/analytics'),
os.path.join(PROJECT_DIR, 'cms_templates/'),
os.path.join(PROJECT_DIR, 'cms_templates/djangocms_blog/'),
], ],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
@ -580,7 +580,6 @@ MULTISITE_FALLBACK_KWARGS = {
FILER_ENABLE_PERMISSIONS = True FILER_ENABLE_PERMISSIONS = True
############################################# #############################################
# configurations for opennebula-integration # # configurations for opennebula-integration #
############################################# #############################################
@ -702,6 +701,12 @@ if ENABLE_LOGGING:
TEST_MANAGE_SSH_KEY_PUBKEY = env('TEST_MANAGE_SSH_KEY_PUBKEY') TEST_MANAGE_SSH_KEY_PUBKEY = env('TEST_MANAGE_SSH_KEY_PUBKEY')
TEST_MANAGE_SSH_KEY_HOST = env('TEST_MANAGE_SSH_KEY_HOST') TEST_MANAGE_SSH_KEY_HOST = env('TEST_MANAGE_SSH_KEY_HOST')
X_FRAME_OPTIONS_ALLOW_FROM_URI = env('X_FRAME_OPTIONS_ALLOW_FROM_URI')
X_FRAME_OPTIONS = ('SAMEORIGIN' if X_FRAME_OPTIONS_ALLOW_FROM_URI is None else
'ALLOW-FROM {}'.format(
X_FRAME_OPTIONS_ALLOW_FROM_URI.strip()
))
DEBUG = bool_env('DEBUG') DEBUG = bool_env('DEBUG')
if DEBUG: if DEBUG:

View file

@ -11,7 +11,6 @@ from hosting.views import (
RailsHostingView, DjangoHostingView, NodeJSHostingView RailsHostingView, DjangoHostingView, NodeJSHostingView
) )
from membership import urls as membership_urls from membership import urls as membership_urls
from ungleich import views as ungleich_views
from ungleich_page.views import LandingView from ungleich_page.views import LandingView
from django.views.generic import RedirectView from django.views.generic import RedirectView
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
@ -57,9 +56,6 @@ urlpatterns += i18n_patterns(
url(r'^blog/$', url(r'^blog/$',
RedirectView.as_view(url=reverse_lazy('ungleich:post-list')), RedirectView.as_view(url=reverse_lazy('ungleich:post-list')),
name='blog_list_view'), name='blog_list_view'),
url(r'^comic/$',
ungleich_views.PostListViewUngleich.as_view(category='comic'),
name='comic_post_list_view'),
url(r'^cms/', include('cms.urls')), url(r'^cms/', include('cms.urls')),
url(r'^blog/', include('djangocms_blog.urls', namespace='djangocms_blog')), url(r'^blog/', include('djangocms_blog.urls', namespace='djangocms_blog')),
url(r'^$', RedirectView.as_view(url='/cms') if REDIRECT_TO_CMS url(r'^$', RedirectView.as_view(url='/cms') if REDIRECT_TO_CMS

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

@ -69,7 +69,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)
@ -212,7 +212,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

@ -315,7 +315,7 @@ class OpenNebulaManager():
return vm_id return vm_id
def delete_vm(self, vm_id): def delete_vm(self, vm_id):
TERMINATE_ACTION = 'terminate' TERMINATE_ACTION = 'terminate-hard'
vm_terminated = False vm_terminated = False
try: try:
self.oneadmin_client.call( self.oneadmin_client.call(

View file

@ -36,7 +36,10 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
return int(obj.template.memory) / 1024 return int(obj.template.memory) / 1024
def get_name(self, obj): 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): class VirtualMachineSerializer(serializers.Serializer):
@ -133,7 +136,10 @@ class VirtualMachineSerializer(serializers.Serializer):
def get_configuration(self, obj): def get_configuration(self, obj):
template_id = obj.template.template_id template_id = obj.template.template_id
template = OpenNebulaManager().get_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): def get_ipv4(self, obj):
""" """
@ -162,7 +168,10 @@ class VirtualMachineSerializer(serializers.Serializer):
return '-' return '-'
def get_name(self, obj): 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): class VMTemplateSerializer(serializers.Serializer):

View file

@ -30,6 +30,14 @@
</span> </span>
</a> </a>
</li> </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> </ul>
<p class="copyright"> <p class="copyright">
Copyright © ungleich GmbH {% now "Y" %} Copyright © ungleich GmbH {% now "Y" %}

View file

@ -55,7 +55,7 @@
<div class="row"> <div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
{% block base_content %} {% block base_content %}
{% placeholder "default" %} {% placeholder "base_ungleich_content" %}
{% endblock %} {% endblock %}
</div> </div>
</div> </div>

View file

@ -1,5 +1,7 @@
{% extends "base_ungleich.html" %} {% extends "base_ungleich.html" %}
{% load cms_tags %}
{% block base_content %} {% block base_content %}
{% placeholder "default" %}
{% block content %} {% block content %}
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}

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):