Merge upsteam/master
This commit is contained in:
Siarhei Puhach 2017-06-30 10:03:44 +03:00
commit 1f0bb9f72a
66 changed files with 389 additions and 435 deletions

View file

@ -8,4 +8,6 @@ env:
- DJANGO_SECRET_KEY=0
# install dependencies
install: "pip install -r requirements.txt"
script: python manage.py test
script:
- flake8
- python manage.py test

View file

@ -1,3 +1,3 @@
from django.contrib import admin
# from django.contrib import admin
# Register your models here.

View file

@ -1,3 +1,3 @@
from django.db import models
# from django.db import models
# Create your models here.

View file

@ -1,3 +1,3 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.

View file

@ -4,11 +4,11 @@ from django.utils.translation import get_language, get_language_info
from django.utils.translation import ugettext_lazy as _
from django.views.generic.edit import FormView
from django.contrib import messages
from django.core.urlresolvers import reverse_lazy, reverse
from django.shortcuts import render
from utils.forms import ContactUsForm
class IndexView(TemplateView):
template_name = "alplora/index.html"
@ -18,6 +18,7 @@ class IndexView(TemplateView):
context.update(languages)
return context
class ContactView(FormView):
template_name = 'alplora/contact.html'
form_class = ContactUsForm
@ -35,6 +36,7 @@ class ContactView(FormView):
messages.add_message(self.request, messages.SUCCESS, self.success_message)
return render(self.request, 'alplora/contact_success.html', {})
class LoginView(TemplateView):
template_name = "alplora/login.html"

View file

@ -1,6 +1,6 @@
from django import forms
from .models import BetaAccess, BetaAccessVM
from .models import BetaAccess
class BetaAccessForm(forms.ModelForm):

View file

@ -5,7 +5,6 @@ from django.utils.translation import activate, get_language
register = template.Library()
@register.simple_tag(takes_context=True)
def change_lang(context, lang=None, *args, **kwargs):
@ -20,5 +19,4 @@ def change_lang(context, lang=None, *args, **kwargs):
finally:
activate(cur_language)
return "%s" % url

View file

@ -1,3 +1,3 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.

View file

@ -1,6 +1,7 @@
from django.conf.urls import url
from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, PaymentOrderView, OrderConfirmationView
from .views import IndexView, BetaProgramView, LandingProgramView, \
BetaAccessView, PricingView, SuccessView, PaymentOrderView, OrderConfirmationView
urlpatterns = [

View file

@ -3,7 +3,7 @@ from django.http import HttpResponseRedirect
from .forms import BetaAccessForm
from .models import BetaAccess, BetaAccessVMType, BetaAccessVM
from django.contrib import messages
from django.core.urlresolvers import reverse_lazy, reverse
from django.core.urlresolvers import reverse
from django.core.mail import EmailMessage
from utils.mailer import BaseEmail
from django.shortcuts import render
@ -13,18 +13,19 @@ from django.core.exceptions import ValidationError
from django.views.decorators.cache import cache_control
from django.conf import settings
from utils.forms import BillingAddressForm, UserBillingAddressForm
from membership.models import StripeCustomer
from hosting.models import HostingOrder, HostingBill
from hosting.models import HostingOrder
from utils.stripe_utils import StripeUtils
from datetime import datetime
from membership.models import CustomUser, StripeCustomer
from oca.pool import WrongIdError
from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer
class LandingProgramView(TemplateView):
template_name = "datacenterlight/landing.html"
class SuccessView(TemplateView):
template_name = "datacenterlight/success.html"
@ -36,6 +37,7 @@ class SuccessView(TemplateView):
del request.session['user']
return render(request, self.template_name)
class PricingView(TemplateView):
template_name = "datacenterlight/pricing.html"
@ -58,7 +60,6 @@ class PricingView(TemplateView):
return render(request, self.template_name, context)
def post(self, request):
cores = request.POST.get('cpu')
@ -92,7 +93,6 @@ class BetaAccessView(FormView):
success_message = "Thank you, we will contact you as soon as possible"
def form_valid(self, form):
context = {
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
}
@ -127,6 +127,7 @@ class BetaAccessView(FormView):
messages.add_message(self.request, messages.SUCCESS, self.success_message)
return render(self.request, 'datacenterlight/beta_success.html', {})
class BetaProgramView(CreateView):
template_name = "datacenterlight/beta.html"
model = BetaAccessVM
@ -330,7 +331,7 @@ class PaymentOrderView(FormView):
final_price = specs.get('price')
token = form.cleaned_data.get('token')
try:
custom_user = CustomUser.objects.get(email=user.get('email'))
CustomUser.objects.get(email=user.get('email'))
except CustomUser.DoesNotExist:
password = CustomUser.get_random_password()
# Register the user, and do not send emails
@ -340,7 +341,6 @@ class PaymentOrderView(FormView):
app='dcl',
base_url=None, send_email=False)
# Get or create stripe customer
customer = StripeCustomer.get_or_create(email=user.get('email'),
token=token)
@ -390,8 +390,9 @@ class PaymentOrderView(FormView):
)
# Create a Hosting Bill
bill = HostingBill.create(
customer=customer, billing_address=billing_address)
# not used
# bill = HostingBill.create(
# customer=customer, billing_address=billing_address)
# Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count():
@ -436,10 +437,12 @@ class PaymentOrderView(FormView):
else:
return self.form_invalid(form)
class OrderConfirmationView(DetailView):
template_name = "datacenterlight/order_detail.html"
context_object_name = "order"
model = HostingOrder
def get_context_data(self, **kwargs):
# Get context
context = super(DetailView, self).get_context_data(**kwargs)

View file

@ -1,5 +1,5 @@
from django.contrib import admin
from .models import Supporter, DGGallery, DGPicture, Booking, BookingPrice,\
from .models import DGGallery, DGPicture, Booking, BookingPrice,\
MembershipOrder, Membership, MembershipType, BookingOrder, BookingCancellation
from django.core.urlresolvers import reverse

View file

@ -1,9 +1,9 @@
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from cms.wizards import wizard_base
from .models import DGGalleryPlugin, DGSupportersPlugin, Supporter
from django.utils.translation import ugettext as _
#
class CMSGalleryPlugin(CMSPluginBase):
model = DGGalleryPlugin
name = _("Digital Glarus Gallery")
@ -17,6 +17,7 @@ class CMSGalleryPlugin(CMSPluginBase):
})
return context
class CMSSupportersPlugin(CMSPluginBase):
name = _("Digital Glarus Supporters")
model = DGSupportersPlugin
@ -29,8 +30,7 @@ class CMSSupportersPlugin(CMSPluginBase):
'placeholder': placeholder
})
return context
#
#
#
plugin_pool.register_plugin(CMSGalleryPlugin)
plugin_pool.register_plugin(CMSSupportersPlugin)

View file

@ -1,7 +1,6 @@
from django import forms
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from datetime import datetime
from utils.models import BillingAddress

View file

@ -3,6 +3,7 @@ from django.conf import settings
import stripe
stripe.api_key = settings.STRIPE_API_PRIVATE_KEY
class Command(BaseCommand):
help = "Record payment plans for Digital Glarus on stripe"
@ -10,5 +11,3 @@ class Command(BaseCommand):
print("Available plans:")
for plan in stripe.Plan.all():
print(plan)

View file

@ -26,8 +26,6 @@ class Command(BaseCommand):
def handle(self, *args, **options):
for payment_plan, data in PAYMENT_PLANS:
try:
res = stripe.Plan.create(**data)
stripe.Plan.create(**data)
except stripe.InvalidRequestError as e:
print(e)

View file

@ -316,7 +316,8 @@ class DGGallery(models.Model):
class Meta:
verbose_name_plural = 'dgGallery'
#
class DGPicture(models.Model):
gallery = models.ForeignKey(DGGallery)
image = FilerImageField(related_name='dg_gallery')
@ -325,8 +326,10 @@ class DGPicture(models.Model):
def __str__(self):
return "%s" % (self.image.name)
class DGGalleryPlugin(CMSPlugin):
dgGallery = models.ForeignKey(DGGallery)
class DGSupportersPlugin(CMSPlugin):
pass

View file

@ -1,4 +1,3 @@
import json
from model_mommy import mommy
from unittest import mock

View file

@ -720,7 +720,9 @@ class ContactView(FormView):
messages.add_message(self.request, messages.SUCCESS, self.success_message)
return super(ContactView, self).form_valid(form)
############## OLD VIEWS
# OLD VIEWS
def blog(request):
tags = ["digitalglarus"]
@ -751,6 +753,3 @@ def supporters(request):
'supporters': Supporter.objects.order_by('name')
}
return render(request, 'supporters.html', context)

View file

@ -9,12 +9,15 @@ from django.utils.translation import ugettext_lazy as _
# dotenv
import dotenv
gettext = lambda s: s
def gettext(s):
return s
def env(env_name):
return os.environ.get(env_name)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.abspath(

View file

@ -1 +1 @@
from .base import *
# from .base import *

View file

@ -11,7 +11,9 @@ from django.utils.translation import ugettext_lazy as _
# dotenv
import dotenv
gettext = lambda s: s
def gettext(s):
return s
def env(env_name):
@ -186,7 +188,11 @@ CMS_TEMPLATES = (
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'app'
'NAME': 'app',
'HOST': 'localhost',
'USER': 'ubuntu',
'PASSWORD': 'Qwerty123',
}
}
@ -462,17 +468,20 @@ STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services"
# EMAIL MESSAGES
REGISTRATION_MESSAGE = {'subject': "Validation mail",
'message': 'Thank You for registering for account on Digital Glarus.\nPlease verify Your account under following link http://{host}/en-us/digitalglarus/login/validate/{slug}',
'message': 'Thank You for registering for account on Digital Glarus.\n'
'Please verify Your account under following link '
'http://{host}/en-us/digitalglarus/login/validate/{slug}',
}
STRIPE_API_PRIVATE_KEY = env('STRIPE_API_PRIVATE_KEY')
STRIPE_API_PUBLIC_KEY = env('STRIPE_API_PUBLIC_KEY')
DEBUG = True
if DEBUG:
from .local import *
else:
from .prod import *
# not used
# if DEBUG:
# from .local import *
# # else:
# # from .prod import *
ANONYMOUS_USER_NAME = 'anonymous@ungleich.ch'

View file

@ -1,5 +1,7 @@
from .base import *
REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='dynamicweb-development.ungleich.ch',slug='{slug}')
from .base import * # flake8: noqa
REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='dynamicweb-development.ungleich.ch',
slug='{slug}')
ALLOWED_HOSTS = [
"*"
]

View file

@ -1,4 +1,4 @@
from .base import *
from .base import * # flake8: noqa
# List of people that get admin messages
ADMINS = ((x, x + "@ungleich.ch") for x in ["web-team"])
@ -9,7 +9,8 @@ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# MANAGERS = ADMINS
REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='digitalglarus.ungleich.ch',slug='{slug}')
REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='digitalglarus.ungleich.ch',
slug='{slug}') # flake8: noqa
ALLOWED_HOSTS = [
".ungleich.ch",

View file

@ -30,7 +30,8 @@ urlpatterns += i18n_patterns('',
url(r'^/?$', LandingView.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^datacenterlight', include('datacenterlight.urls', namespace="datacenterlight")),
url(r'^hosting/', RedirectView.as_view(url=reverse_lazy('hosting:login')), name='redirect_hosting_login'),
url(r'^hosting/', RedirectView.as_view(
url=reverse_lazy('hosting:login')), name='redirect_hosting_login'),
url(r'^alplora', include('alplora.urls', namespace="alplora")),
url(r'^membership/', include(membership_urls)),
url(r'^digitalglarus/', include('digitalglarus.urls',

View file

@ -7,13 +7,13 @@ For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""
import os,sys
import os
import sys
from django.core.wsgi import get_wsgi_application
# sys.path.append(os.path.dirname(__file__))
sys.path.append('/home/app/pyvenv/lib/python3.4/site-packages/')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dynamicweb.settings.prod")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

View file

@ -1,8 +1,4 @@
from django.contrib import admin
from django.utils.html import format_html
from django.core.urlresolvers import reverse
from utils.mailer import BaseEmail
from .models import HostingOrder, HostingBill, HostingPlan

View file

@ -1,14 +1,11 @@
import random
import string
from django import forms
from membership.models import CustomUser
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _
from utils.stripe_utils import StripeUtils
from .models import UserHostingKey
from .models import HostingOrder, UserHostingKey
class HostingUserLoginForm(forms.Form):

View file

@ -1,4 +1,4 @@
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from hosting.models import VirtualMachineType
@ -55,15 +55,15 @@ class Command(BaseCommand):
},
]
hetzner = {
'base_price': 10,
'core_price': 5,
'memory_price': 2,
'disk_size_price': 0.6,
'description': 'VM auf einzelner HW, Raid1, kein HA',
'location': 'DE'
}
# not used
# hetzner = {
# 'base_price': 10,
# 'core_price': 5,
# 'memory_price': 2,
# 'disk_size_price': 0.6,
# 'description': 'VM auf einzelner HW, Raid1, kein HA',
# 'location': 'DE'
# }
# return {
# # 'hetzner_nug': {

View file

@ -1,22 +1,16 @@
import os
import socket
import logging
import oca
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.functional import cached_property
from django.conf import settings
from Crypto.PublicKey import RSA
from stored_messages.settings import stored_messages_settings
from membership.models import StripeCustomer, CustomUser
from utils.models import BillingAddress
from utils.mixins import AssignPermissionsMixin
from .managers import VMPlansManager
logger = logging.getLogger(__name__)
@ -46,6 +40,7 @@ class HostingPlan(models.Model):
price += self.memory * 2
return price
class HostingOrder(AssignPermissionsMixin, models.Model):
ORDER_APPROVED_STATUS = 'Approved'
@ -128,6 +123,7 @@ class UserHostingKey(models.Model):
# self.save(update_fields=['public_key'])
return private_key, public_key
class HostingBill(AssignPermissionsMixin, models.Model):
customer = models.ForeignKey(StripeCustomer)
billing_address = models.ForeignKey(BillingAddress)
@ -147,4 +143,3 @@ class HostingBill(AssignPermissionsMixin, models.Model):
def create(cls, customer=None, billing_address=None):
instance = cls.objects.create(customer=customer, billing_address=billing_address)
return instance

View file

@ -4,7 +4,7 @@ from django.test import TestCase
from django.core.urlresolvers import reverse
from django.core.urlresolvers import resolve
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes

View file

@ -1,7 +1,7 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.
test_user_can_add_ssh_key()
test_user_can_delete_ssh_ke()
# test_user_can_add_ssh_key()
#
# test_user_can_delete_ssh_ke()

View file

@ -1,5 +1,4 @@
from collections import namedtuple
from oca.pool import WrongNameError, WrongIdError
from django.shortcuts import render
from django.http import Http404
from django.core.urlresolvers import reverse_lazy, reverse
@ -7,7 +6,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import View, CreateView, FormView, ListView, DetailView, \
DeleteView, TemplateView, UpdateView
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.contrib import messages
from django.conf import settings
from django.shortcuts import redirect
@ -35,9 +33,6 @@ from opennebula_api.serializers import VirtualMachineSerializer,\
from django.utils.translation import ugettext_lazy as _
from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError, WrongIdError
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
connection error. please try again in a few minutes."
@ -142,7 +137,6 @@ class HostingPricingView(ProcessVMSelectionMixin, View):
'templates': templates,
'configuration_options': configuration_options,
}
return context
@ -173,7 +167,6 @@ class IndexView(View):
return context
def get(self, request, *args, **kwargs):
context = self.get_context_data()
return render(request, self.template_name, context)
@ -205,6 +198,7 @@ class SignupView(CreateView):
return HttpResponseRedirect(reverse_lazy('hosting:signup-validate'))
class SignupValidateView(TemplateView):
template_name = "hosting/signup_validate.html"
@ -214,7 +208,9 @@ class SignupValidateView(TemplateView):
home_url = '<a href="' + reverse('datacenterlight:index') + '">Data Center Light</a>'
message = '{signup_success_message} {lurl}</a> \
<br />{go_back} {hurl}.'.format(
signup_success_message = _('Thank you for signing up. We have sent an email to you. Please follow the instructions in it to activate your account. Once activated, you can login using'),
signup_success_message=_(
'Thank you for signing up. We have sent an email to you. '
'Please follow the instructions in it to activate your account. Once activated, you can login using'),
go_back=_('Go back to'),
lurl=login_url,
hurl=home_url
@ -223,6 +219,7 @@ class SignupValidateView(TemplateView):
context['section_title'] = _('Sign up')
return context
class SignupValidatedView(SignupValidateView):
template_name = "hosting/signup_validate.html"
@ -351,6 +348,7 @@ class SSHKeyDeleteView(LoginRequiredMixin, DeleteView):
return super(SSHKeyDeleteView, self).delete(request, *args, **kwargs)
class SSHKeyListView(LoginRequiredMixin, ListView):
template_name = "hosting/user_keys.html"
login_url = reverse_lazy('hosting:login')
@ -359,7 +357,6 @@ class SSHKeyListView(LoginRequiredMixin, ListView):
paginate_by = 10
ordering = '-id'
def get_queryset(self):
user = self.request.user
self.queryset = UserHostingKey.objects.filter(user=user)
@ -379,7 +376,6 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
context_object_name = "virtual_machine"
success_url = reverse_lazy('hosting:ssh_keys')
def get_form_kwargs(self):
kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
kwargs.update({'request': self.request})
@ -565,8 +561,9 @@ class PaymentVMView(LoginRequiredMixin, FormView):
)
# Create a Hosting Bill
bill = HostingBill.create(
customer=customer, billing_address=billing_address)
# variable bill is not used
# bill = HostingBill.create(
# customer=customer, billing_address=billing_address)
# Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count():

View file

@ -1,7 +1,7 @@
__author__ = 'tomislav'
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth import authenticate,login
from django.contrib.auth import authenticate
from .models import CreditCards
@ -36,6 +36,7 @@ class RegisterForm(SignupFormMixin):
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class PaymentForm(forms.ModelForm):
class Meta:
model = CreditCards
@ -58,7 +59,7 @@ class PaymentForm(forms.ModelForm):
# if CreditCards.objects.filter(card_number=data.get("card_number")):
# raise forms.ValidationError({'card_number': _('Credit card is used before.')})
return self.cleaned_data
return data
def save(self, user_id):
self.instance.user_id = user_id

View file

@ -1,10 +1,9 @@
from datetime import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager, AbstractUser, PermissionsMixin
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.contrib.auth.hashers import make_password
from django.core.validators import RegexValidator
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.conf import settings
from django.utils.crypto import get_random_string
@ -15,11 +14,12 @@ from django.core.urlresolvers import reverse
from utils.mailer import BaseEmail
REGISTRATION_MESSAGE = {'subject': "Validation mail",
'message': 'Please validate Your account under this link http://localhost:8000/en-us/digitalglarus/login/validate/{}',
'message': 'Please validate Your account under this link '
'http://localhost:8000/en-us/digitalglarus/login/validate/{}',
'from': 'test@test.com'}
def get_anonymous_user_instance(User):
def get_anonymous_user_instance():
return CustomUser(name='Anonymous', email='anonymous@ungleich.ch',
validation_slug=make_password(None))
@ -85,15 +85,18 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):
dg.send_mail(to=user.email)
elif app == 'dcl':
dcl_text = settings.DCL_TEXT
dcl_from_address = settings.DCL_SUPPORT_FROM_ADDRESS
# not used
# dcl_from_address = settings.DCL_SUPPORT_FROM_ADDRESS
user.is_active = False
if send_email is True:
email_data = {
'subject': str(_('Activate your ')) + dcl_text + str(_(' account')),
'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
'to': user.email,
'context': {'base_url': base_url,
'activation_link' : reverse('hosting:validate', kwargs={'validate_slug': user.validation_slug}),
'activation_link': reverse('hosting:validate',
kwargs={'validate_slug': user.validation_slug}),
'dcl_text': dcl_text
},
'template_name': 'user_activation',

View file

@ -27,5 +27,3 @@ class LoginTestCase(TestCase):
res4 = self.client.post(url, data={'email': 'test@gmail.com', 'password': 'falsepassword'})
self.assertContains(res4, 'Sorry, that login was invalid.', 1, 200)

View file

@ -13,7 +13,6 @@ from .forms import LoginForm, RegisterForm, PaymentForm
from utils.stripe_utils import StripeUtils
def validate_email(request, validate_slug):
validated = CustomUser.validate_url(validate_slug)
if validated:
@ -21,10 +20,12 @@ def validate_email(request, validate_slug):
else:
return render(request, 'templates/error.html', {'msg': 'Validation failed.'})
def reset(request, time):
request.session['next'] = 0
return redirect('payment', time=time)
class CreditCardView(View):
def _get_context(self, request, time):
request.session['time'] = time
@ -64,7 +65,7 @@ class CreditCardView(View):
stripe_token = request.POST['stripeToken']
if form.is_valid():
ret = form.save(request.user)
form.save(request.user)
amount = 35 if time == 'month' else 360
request.session['token'] = stripe_token
request.session['amount'] = amount
@ -129,6 +130,7 @@ class MembershipView(View):
language = get_language()
return render(request, 'templates/membership.html', context={'language_code': language})
def logout_glarus(request):
logout(request)
return HttpResponseRedirect('/digitalglarus')

View file

@ -1,3 +1,3 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.

View file

@ -1,3 +1,3 @@
from django.contrib import admin
# from django.contrib import admin
# Register your models here.

View file

@ -1,9 +1,10 @@
class KeyExistsError(Exception):
pass
class UserExistsError(Exception):
pass
class UserCredentialError(Exception):
pass

View file

@ -6,7 +6,6 @@ from oca.pool import WrongNameError, WrongIdError
from oca.exceptions import OpenNebulaException
from django.conf import settings
from django.utils.functional import cached_property
from utils.models import CustomUser
from .exceptions import KeyExistsError, UserExistsError, UserCredentialError
@ -38,6 +37,7 @@ class OpenNebulaManager():
)
except:
pass
def _get_client(self, user):
"""Get a opennebula client object for a CustomUser object
@ -135,7 +135,6 @@ class OpenNebulaManager():
)
raise ConnectionRefusedError
def _get_or_create_user(self, email, password):
try:
user_pool = self._get_user_pool()
@ -209,36 +208,6 @@ class OpenNebulaManager():
except:
raise ConnectionRefusedError
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
disk_size_price, ssh=''):
"""Create and add a new template to opennebula.
:param name: A string representation describing the template.
Used as label in view.
:param cores: Amount of virtual cpu cores for the VM.
:param memory: Amount of RAM for the VM (GB)
:param disk_size: Amount of disk space for VM (GB)
:param core_price: Price of virtual cpu for the VM per core.
:param memory_price: Price of RAM for the VM per GB
:param disk_size_price: Price of disk space for VM per GB
:param ssh: User public ssh key
"""
template_id = oca.VmTemplate.allocate(
self.oneadmin_client,
template_string_formatter.format(
name=name,
vcpu=cores,
cpu=0.1 * cores,
size=1024 * disk_size,
memory=1024 * memory,
# * 10 because we set cpu to *0.1
cpu_cost=10 * core_price,
memory_cost=memory_price,
disk_cost=disk_size_price,
ssh=ssh
)
)
def create_vm(self, template_id, specs, ssh_key=None, vm_name=None):
template = self.get_template(template_id)
@ -468,7 +437,8 @@ class OpenNebulaManager():
except AttributeError:
pass
self.oneadmin_client.call('user.update', open_user.id,
'<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'.format(key=public_key))
'<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'
.format(key=public_key))
return True
except WrongNameError:
raise
@ -512,7 +482,8 @@ class OpenNebulaManager():
# raise KeyDoesNotExistsError()
self.oneadmin_client.call('user.update', open_user.id,
'<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'.format(key=public_key))
'<CONTEXT><SSH_PUBLIC_KEY>{key}</SSH_PUBLIC_KEY></CONTEXT>'
.format(key=public_key))
return True
except WrongNameError:
raise

View file

@ -1,13 +1,12 @@
import oca
import ipaddress
from rest_framework import serializers
from oca import OpenNebulaException
from oca.template import VmTemplate
from .models import OpenNebulaManager
class VirtualMachineTemplateSerializer(serializers.Serializer):
"""Serializer to map the virtual machine template instance into JSON format."""
id = serializers.IntegerField(read_only=True)
@ -39,7 +38,6 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
return obj.name.strip('public-')
class VirtualMachineSerializer(serializers.Serializer):
"""Serializer to map the virtual machine instance into JSON format."""
@ -49,7 +47,6 @@ class VirtualMachineSerializer(serializers.Serializer):
set_memory = serializers.IntegerField(write_only=True, label='Memory')
memory = serializers.SerializerMethodField()
disk_size = serializers.SerializerMethodField()
ipv4 = serializers.SerializerMethodField()
ipv6 = serializers.SerializerMethodField()
@ -82,7 +79,6 @@ class VirtualMachineSerializer(serializers.Serializer):
'memory': memory,
}
try:
manager = OpenNebulaManager(email=owner.email,
password=owner.password,
@ -112,6 +108,7 @@ class VirtualMachineSerializer(serializers.Serializer):
for disk in template.disks:
price += int(disk.size)/1024 * 0.6
return price
def get_configuration(self, obj):
template_id = obj.template.template_id
template = OpenNebulaManager().get_template(template_id)
@ -131,13 +128,16 @@ class VirtualMachineSerializer(serializers.Serializer):
def get_name(self, obj):
return obj.name.strip('public-')
def hexstr2int(string):
return int(string.replace(':', ''), 16)
FIRST_MAC = hexstr2int('02:00:b3:39:79:4d')
FIRST_V4 = ipaddress.ip_address('185.203.112.2')
COUNT = 1000
def v4_from_mac(mac):
"""Calculates the IPv4 address from a MAC address.
@ -146,5 +146,6 @@ def v4_from_mac(mac):
"""
return FIRST_V4 + (hexstr2int(mac) - FIRST_MAC)
def is_in_v4_range(mac):
return FIRST_MAC <= hexstr2int(mac) < FIRST_MAC + 1000

View file

@ -1,4 +1,3 @@
import socket
import random
import string
@ -8,13 +7,12 @@ from .models import OpenNebulaManager
from .serializers import VirtualMachineSerializer
from utils.models import CustomUser
class OpenNebulaManagerTestCases(TestCase):
"""This class defines the test suite for the opennebula manager model."""
def setUp(self):
"""Define the test client and other test variables."""
self.email = '{}@ungleich.ch'.format(''.join(random.choices(string.ascii_uppercase, k=10)))
self.password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=20))
@ -28,7 +26,6 @@ class OpenNebulaManagerTestCases(TestCase):
self.manager = OpenNebulaManager()
def test_connect_to_server(self):
"""Test the opennebula manager can connect to a server."""
try:
@ -118,7 +115,6 @@ class OpenNebulaManagerTestCases(TestCase):
self.assertEqual(new_public_key,
old_public_key.replace('{}\n'.format(public_key), '', 1))
def test_requires_ssh_key_for_new_vm(self):
"""Test the opennebula manager requires the user to have a ssh key when
creating a new vm"""
@ -129,7 +125,6 @@ class VirtualMachineSerializerTestCase(TestCase):
"""Define the test client and other test variables."""
self.manager = OpenNebulaManager(email=None, password=None)
def test_serializer_strips_of_public(self):
""" Test the serialized virtual machine object contains no 'public-'."""
@ -137,5 +132,3 @@ class VirtualMachineSerializerTestCase(TestCase):
serialized = VirtualMachineSerializer(vm)
self.assertEqual(serialized.data.get('name'), vm.name.strip('public-'))
break

View file

@ -1,19 +1,11 @@
from rest_framework import generics
from rest_framework import permissions
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import authenticate, login
from utils.views import LoginViewMixin
from membership.models import CustomUser, StripeCustomer
from guardian.mixins import PermissionRequiredMixin
from .serializers import VirtualMachineTemplateSerializer, \
VirtualMachineSerializer
from .serializers import VirtualMachineSerializer
from .models import OpenNebulaManager
from rest_framework.exceptions import APIException
class ServiceUnavailable(APIException):
status_code = 503
default_detail = 'Service temporarily unavailable, try again later.'
@ -41,6 +33,7 @@ class VmCreateView(generics.ListCreateAPIView):
"""Save the post data when creating a new template."""
serializer.save(owner=self.request.user)
class VmDetailsView(generics.RetrieveUpdateDestroyAPIView):
"""This class handles the http GET, PUT and DELETE requests."""
permission_classes = (permissions.IsAuthenticated, )
@ -81,4 +74,3 @@ class VmDetailsView(generics.RetrieveUpdateDestroyAPIView):
manager.delete_vm(instance.id)
except ConnectionRefusedError:
raise ServiceUnavailable

View file

@ -84,5 +84,4 @@ django-admin-honeypot==1.0.0
coverage==4.3.4
git+https://github.com/ungleich/python-oca.git#egg=python-oca
djangorestframework
flake8==3.3.0

3
setup.cfg Executable file
View file

@ -0,0 +1,3 @@
[flake8]
max-line-length = 120
exclude = .tox,.git,*/migrations/*,*/static/*,docs,venv,node_modules/*

View file

@ -9,4 +9,5 @@ from .models import UngleichPage
class UngleichPageAdmin(PageExtensionAdmin):
pass
admin.site.register(UngleichPage, UngleichPageAdmin)

View file

@ -2,7 +2,6 @@ from cms.extensions.toolbar import ExtensionToolbar
from django.utils.translation import ugettext_lazy as _
from cms.toolbar_pool import toolbar_pool
from cms.toolbar_base import CMSToolbar
from .models import UngleichPage

View file

@ -1,5 +1,3 @@
from django.db import models
from cms.extensions import PageExtension
from cms.extensions.extension_pool import extension_pool
from filer.fields.image import FilerImageField
@ -16,4 +14,5 @@ class UngleichPage(PageExtension):
class Meta:
app_label = 'ungleich'
extension_pool.register(UngleichPage)

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _
# from django.utils.translation import ugettext_lazy as _
# TEMPLATES = {
# 'blog_u.html': _('Blog'),
# 'page.html': _('Page'),

View file

@ -1,3 +1,3 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.

View file

@ -6,6 +6,7 @@ from django.utils.translation import get_language
from djangocms_blog.models import Post
from djangocms_blog.views import PostListView
from djangocms_blog.settings import get_setting
from django.utils.translation import ugettext_lazy as _
def blog(request):

View file

@ -1,3 +1,3 @@
from django.contrib import admin
# from django.contrib import admin
# Register your models here.

View file

@ -1,3 +1,3 @@
from django.db import models
# from django.db import models
# Create your models here.

View file

@ -1,3 +1,3 @@
from django.test import TestCase
# from django.test import TestCase
# Create your tests here.

View file

@ -2,10 +2,9 @@ from django.contrib import messages
from django.views.generic.edit import FormView
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse_lazy,reverse
from django.core.urlresolvers import reverse_lazy
from django.views.generic import View
from django.shortcuts import render,redirect,render_to_response
from django.http import HttpResponseRedirect
from django.shortcuts import render
from utils.forms import ContactUsForm

View file

@ -1,5 +1,5 @@
from django.contrib import admin
from .models import BillingAddress, UserBillingAddress
from .models import UserBillingAddress
# Register your models here.

View file

@ -1,6 +1,5 @@
from django.utils.translation import ugettext as _
from django.db import models
from django import forms
# http://xml.coverpages.org/country3166.html
COUNTRIES = (

View file

@ -116,6 +116,7 @@ class BillingAddressForm(forms.ModelForm):
class UserBillingAddressForm(forms.ModelForm):
user = forms.ModelChoiceField(queryset=CustomUser.objects.all(),
widget=forms.HiddenInput())
class Meta:
model = UserBillingAddress
fields = ['street_address', 'city', 'postal_code', 'country', 'user']
@ -126,6 +127,7 @@ class UserBillingAddressForm(forms.ModelForm):
'Country': _('Country'),
}
class ContactUsForm(forms.ModelForm):
error_css_class = 'autofocus'

View file

@ -77,4 +77,3 @@ class DigitalGlarusRegistrationMailer(BaseMailer):
self.registration = self.message
self._message = self._message.format(slug=self._slug)
super().__init__()

View file

@ -1,6 +1,4 @@
from django.db import models
from django.core import serializers
from django.forms.models import model_to_dict
from membership.models import CustomUser
@ -18,6 +16,7 @@ class BaseBillingAddress(models.Model):
class Meta:
abstract = True
class BillingAddress(BaseBillingAddress):
def __str__(self):

View file

@ -127,22 +127,10 @@ class StripeUtils(object):
id=id)
@handleStripeError
def make_payment(self, user, amount, token):
def make_payment(self, customer, amount, token):
charge = self.stripe.Charge.create(
amount=amount, # in cents
currency=self.CURRENCY,
customer=customer
)
return charge
@handleStripeError
def create_plan(self, amount, name, id):
self.stripe.Plan.create(
amount=amount,
interval=self.INTERVAL,
name=name,
currency=self.CURRENCY,
id=id)