Merge branch 'master' into bugfix/show_meta_description_in_cms_page
This commit is contained in:
		
				commit
				
					
						9c5363ef55
					
				
			
		
					 13 changed files with 145 additions and 26 deletions
				
			
		
							
								
								
									
										17
									
								
								Changelog
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								Changelog
									
										
									
									
									
								
							|  | @ -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 | ||||
|     * #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) | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -2,16 +2,15 @@ | |||
| Copyright 2015 ungleich. | ||||
| """ | ||||
| 
 | ||||
| import json | ||||
| import logging | ||||
| # -*- coding: utf-8 -*- | ||||
| # Build paths inside the project like this: os.path.join(BASE_DIR, ...) | ||||
| import os | ||||
| import json | ||||
| 
 | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| 
 | ||||
| # dotenv | ||||
| import dotenv | ||||
| import logging | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -56,6 +55,7 @@ PROJECT_DIR = os.path.abspath( | |||
| dotenv.read_dotenv("{0}/.env".format(PROJECT_DIR)) | ||||
| 
 | ||||
| from multisite import SiteID | ||||
| 
 | ||||
| SITE_ID = SiteID(default=1) | ||||
| 
 | ||||
| APP_ROOT_ENDPOINT = "/" | ||||
|  | @ -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/'), | ||||
|                  ], | ||||
|         'APP_DIRS': True, | ||||
|         'OPTIONS': { | ||||
|  | @ -580,7 +580,6 @@ MULTISITE_FALLBACK_KWARGS = { | |||
| 
 | ||||
| FILER_ENABLE_PERMISSIONS = True | ||||
| 
 | ||||
| 
 | ||||
| ############################################# | ||||
| # 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_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') | ||||
| 
 | ||||
| if DEBUG: | ||||
|  |  | |||
|  | @ -11,7 +11,6 @@ from hosting.views import ( | |||
|     RailsHostingView, DjangoHostingView, NodeJSHostingView | ||||
| ) | ||||
| from membership import urls as membership_urls | ||||
| from ungleich import views as ungleich_views | ||||
| from ungleich_page.views import LandingView | ||||
| from django.views.generic import RedirectView | ||||
| from django.core.urlresolvers import reverse_lazy | ||||
|  | @ -57,9 +56,6 @@ urlpatterns += i18n_patterns( | |||
|     url(r'^blog/$', | ||||
|         RedirectView.as_view(url=reverse_lazy('ungleich:post-list')), | ||||
|         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'^blog/', include('djangocms_blog.urls', namespace='djangocms_blog')), | ||||
|     url(r'^$', RedirectView.as_view(url='/cms') if REDIRECT_TO_CMS | ||||
|  |  | |||
							
								
								
									
										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) | ||||
|  |  | |||
|  | @ -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): | ||||
|         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) | ||||
|         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): | ||||
|         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" %} | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ | |||
|       <div class="row"> | ||||
| 	<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> | ||||
| 	  {% block base_content %} | ||||
| 	  {% placeholder "default" %} | ||||
|         {% placeholder "base_ungleich_content" %} | ||||
| 	  {% endblock %} | ||||
| 	</div> | ||||
|       </div> | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| {% extends "base_ungleich.html" %} | ||||
| {% load cms_tags %} | ||||
| {% block base_content %} | ||||
| {% placeholder "default" %} | ||||
| {% block content %} | ||||
| {% endblock %} | ||||
| {% endblock %} | ||||
|  |  | |||
|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue